From b649b5e1bdc8d08e5414679ab9559ac5a2aeb48f Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Wed, 3 Sep 2025 21:14:56 +0800 Subject: [PATCH] change: Switch to offical OpenFX Support. Still can't compile. --- .clang-tidy | 147 - .gitignore | 2 +- .gitmodules | 6 +- CMakeLists.txt | 13 +- app/CMakeLists.txt | 11 +- app/main.cpp | 11 +- app/node/plugins/Plugin.h | 2 +- app/pluginSupport/CMakeLists.txt | 26 +- app/pluginSupport/Core.cpp | 17 - app/pluginSupport/Dialog.cpp | 25 - app/pluginSupport/DrawSuite.cpp | 19 - app/pluginSupport/GpuRender.cpp | 17 - app/pluginSupport/ImageEffect.cpp | 17 - app/pluginSupport/Interact.cpp | 17 - app/pluginSupport/KeySyms.cpp | 17 - app/pluginSupport/Memory.cpp | 17 - app/pluginSupport/Message.cpp | 17 - app/pluginSupport/MultiThread.cpp | 17 - app/pluginSupport/OliveHost.cpp | 85 + app/pluginSupport/OliveHost.h | 69 + app/pluginSupport/OliveInstance.cpp | 64 + app/pluginSupport/OliveInstance.h | 58 + app/pluginSupport/OlivePlugin.cpp | 215 -- app/pluginSupport/OlivePlugin.h | 81 - app/pluginSupport/OpenGLRender.cpp | 17 - app/pluginSupport/Param.cpp | 17 - app/pluginSupport/ParametricParam.cpp | 17 - app/pluginSupport/Pixels.cpp | 17 - app/pluginSupport/Progress.cpp | 17 - app/pluginSupport/Property.cpp | 217 -- app/pluginSupport/TimeLine.cpp | 17 - third_party/openfx | 1 - third_party/openfx/HostSupport/BUILDING | 37 + third_party/openfx/HostSupport/CMakeLists.txt | 22 + third_party/openfx/HostSupport/README | 69 + third_party/openfx/HostSupport/TTD | 17 + .../openfx/HostSupport/include/ofxhBinary.h | 96 + .../openfx/HostSupport/include/ofxhClip.h | 499 +++ .../openfx/HostSupport/include/ofxhHost.h | 84 + .../HostSupport/include/ofxhImageEffect.h | 679 ++++ .../HostSupport/include/ofxhImageEffectAPI.h | 221 ++ .../openfx/HostSupport/include/ofxhInteract.h | 278 ++ .../openfx/HostSupport/include/ofxhMemory.h | 39 + .../openfx/HostSupport/include/ofxhParam.h | 678 ++++ .../HostSupport/include/ofxhPluginAPICache.h | 87 + .../HostSupport/include/ofxhPluginCache.h | 432 +++ .../openfx/HostSupport/include/ofxhProgress.h | 34 + .../HostSupport/include/ofxhPropertySuite.h | 545 +++ .../openfx/HostSupport/include/ofxhTimeLine.h | 34 + .../HostSupport/include/ofxhUtilities.h | 154 + .../openfx/HostSupport/include/ofxhXml.h | 74 + .../openfx/HostSupport/src/ofxhBinary.cpp | 104 + .../openfx/HostSupport/src/ofxhClip.cpp | 654 ++++ .../openfx/HostSupport/src/ofxhHost.cpp | 124 + .../HostSupport/src/ofxhImageEffect.cpp | 2809 ++++++++++++++ .../HostSupport/src/ofxhImageEffectAPI.cpp | 592 +++ .../openfx/HostSupport/src/ofxhInteract.cpp | 444 +++ .../openfx/HostSupport/src/ofxhMemory.cpp | 64 + .../openfx/HostSupport/src/ofxhParam.cpp | 2300 ++++++++++++ .../HostSupport/src/ofxhPluginAPICache.cpp | 135 + .../HostSupport/src/ofxhPluginCache.cpp | 694 ++++ .../HostSupport/src/ofxhPropertySuite.cpp | 1046 ++++++ .../openfx/HostSupport/src/ofxhUtilities.cpp | 37 + third_party/openfx/Support/CMakeLists.txt | 8 + third_party/openfx/Support/LICENSE | 32 + .../openfx/Support/Library/.gdb_history | 57 + .../openfx/Support/Library/CMakeLists.txt | 16 + .../openfx/Support/Library/ofxSupport.dsp | 128 + .../openfx/Support/Library/ofxsCore.cpp | 113 + .../Support/Library/ofxsImageEffect.cpp | 3078 ++++++++++++++++ .../openfx/Support/Library/ofxsInteract.cpp | 546 +++ .../openfx/Support/Library/ofxsLog.cpp | 129 + .../Support/Library/ofxsMultiThread.cpp | 128 + .../openfx/Support/Library/ofxsParams.cpp | 3226 +++++++++++++++++ .../openfx/Support/Library/ofxsProperty.cpp | 230 ++ .../Library/ofxsPropertyValidation.cpp | 1313 +++++++ .../Support/Library/ofxsSupportPrivate.h | 228 ++ .../openfx/Support/Library/ofxsupport.dsw | 29 + .../openfx/Support/Library/ofxsupport.vcproj | 695 ++++ .../Support/OSXStaticLoader/pluginLoader.cpp | 74 + .../openfx/Support/Plugins/Basic/Info.plist | 20 + .../openfx/Support/Plugins/Basic/basic.cpp | 727 ++++ .../openfx/Support/Plugins/Basic/basic.dsp | 107 + .../openfx/Support/Plugins/Basic/basic.dsw | 44 + .../openfx/Support/Plugins/Basic/basic.vcproj | 464 +++ .../openfx/Support/Plugins/CMakeLists.txt | 48 + .../Support/Plugins/ChoiceParams/Info.plist | 20 + .../Plugins/ChoiceParams/choiceparams.cpp | 681 ++++ .../openfx/Support/Plugins/ExamplePlugs.sln | 115 + .../openfx/Support/Plugins/Field/Info.plist | 20 + .../openfx/Support/Plugins/Field/field.cpp | 286 ++ .../openfx/Support/Plugins/Field/field.vcproj | 464 +++ .../Support/Plugins/GPUGain/CudaKernel.cu | 26 + .../Support/Plugins/GPUGain/GPUGain.cpp | 462 +++ .../openfx/Support/Plugins/GPUGain/GPUGain.h | 16 + .../Support/Plugins/GPUGain/GPUGain.sln | 21 + .../Support/Plugins/GPUGain/GPUGain.vcxproj | 143 + .../GPUGain/GPUGain.xcodeproj/project.pbxproj | 225 ++ .../openfx/Support/Plugins/GPUGain/Info.plist | 20 + .../Support/Plugins/GPUGain/MetalKernel.mm | 108 + .../Support/Plugins/GPUGain/OpenCLKernel.cpp | 270 ++ .../Support/Plugins/Generator/Info.plist | 20 + .../Support/Plugins/Generator/noise.cpp | 293 ++ .../Support/Plugins/Generator/noise.dsp | 111 + .../Support/Plugins/Generator/noise.dsw | 44 + .../Support/Plugins/Generator/noise.vcproj | 472 +++ .../openfx/Support/Plugins/Invert/Info.plist | 20 + .../openfx/Support/Plugins/Invert/invert.cpp | 257 ++ .../Support/Plugins/Invert/invert.vcproj | 464 +++ .../Support/Plugins/MultiBundle/Info.plist | 20 + .../MultiBundle/PluginRegistration.cpp | 20 + .../Plugins/MultiBundle/multibundle.vcproj | 444 +++ .../Plugins/MultiBundle/multibundle1.cpp | 529 +++ .../Plugins/MultiBundle/multibundle1.h | 13 + .../Plugins/MultiBundle/multibundle2.cpp | 431 +++ .../Plugins/MultiBundle/multibundle2.h | 13 + .../openfx/Support/Plugins/Retimer/Info.plist | 20 + .../Support/Plugins/Retimer/retimer.cpp | 386 ++ .../Support/Plugins/Retimer/retimer.dsp | 107 + .../Support/Plugins/Retimer/retimer.dsw | 44 + .../Support/Plugins/Retimer/retimer.vcproj | 464 +++ .../openfx/Support/Plugins/Tester/Info.plist | 20 + .../openfx/Support/Plugins/Tester/Tester.cpp | 528 +++ .../Support/Plugins/Tester/Tester.vcproj | 464 +++ .../Support/Plugins/Transition/Info.plist | 20 + .../Support/Plugins/Transition/crossFade.cpp | 260 ++ .../Support/Plugins/Transition/crossFade.dsp | 107 + .../Support/Plugins/Transition/crossFade.dsw | 44 + .../Plugins/Transition/crossFade.vcproj | 464 +++ .../openfx/Support/Plugins/include/README | 3 + .../Plugins/include/ofxsImageBlender.H | 95 + .../Support/Plugins/include/ofxsProcessing.H | 121 + .../openfx/Support/PropTester/CMakeLists.txt | 7 + .../openfx/Support/PropTester/Info.plist | 20 + .../openfx/Support/PropTester/propTester.cpp | 579 +++ .../openfx/Support/PropTester/propTester.dsp | 107 + .../openfx/Support/PropTester/propTester.dsw | 44 + .../Support/PropTester/propTester.vcproj | 464 +++ third_party/openfx/Support/README | 73 + .../Support/Support.xcodeproj/project.pbxproj | 1691 +++++++++ third_party/openfx/Support/TODO | 8 + third_party/openfx/Support/include/ofxsCore.h | 334 ++ .../openfx/Support/include/ofxsImageEffect.h | 1224 +++++++ .../openfx/Support/include/ofxsInteract.h | 286 ++ third_party/openfx/Support/include/ofxsLog.h | 43 + .../openfx/Support/include/ofxsMemory.h | 45 + .../openfx/Support/include/ofxsMessage.h | 30 + .../openfx/Support/include/ofxsMultiThread.h | 106 + .../openfx/Support/include/ofxsParam.h | 1868 ++++++++++ .../openfx/Support/include/ofxsProcessing.h | 230 ++ .../openfx/Support/include/osxDeploy.sh | 172 + third_party/openfx/Support/support.doxy | 1074 ++++++ third_party/openfx/include/DocSrc/footer.html | 35 + .../openfx/include/DocSrc/ofx_footer.html | 39 + .../openfx/include/DocSrc/ofx_header.html | 73 + .../openfx/include/DocSrc/ofx_style.css | 1456 ++++++++ third_party/openfx/include/OFX_navheader.png | Bin 0 -> 8753 bytes .../ofx-native-v1.5_aces-v1.3_ocio-v2.3.h | 839 +++++ .../ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio | 1549 ++++++++ third_party/openfx/include/ofx.doxy | 2379 ++++++++++++ third_party/openfx/include/ofx.dtd | 231 ++ third_party/openfx/include/ofxColour.h | 289 ++ third_party/openfx/include/ofxCore.h | 966 +++++ third_party/openfx/include/ofxDialog.h | 78 + third_party/openfx/include/ofxDrawSuite.h | 185 + third_party/openfx/include/ofxGPURender.h | 842 +++++ third_party/openfx/include/ofxImageEffect.h | 1757 +++++++++ third_party/openfx/include/ofxInteract.h | 550 +++ third_party/openfx/include/ofxKeySyms.h | 528 +++ third_party/openfx/include/ofxMemory.h | 68 + third_party/openfx/include/ofxMessage.h | 171 + third_party/openfx/include/ofxMultiThread.h | 168 + third_party/openfx/include/ofxOld.h | 109 + third_party/openfx/include/ofxOpenGLRender.h | 10 + third_party/openfx/include/ofxParam.h | 1295 +++++++ .../openfx/include/ofxParametricParam.h | 286 ++ third_party/openfx/include/ofxPixels.h | 64 + third_party/openfx/include/ofxProgress.h | 150 + third_party/openfx/include/ofxProperty.h | 321 ++ third_party/openfx/include/ofxTimeLine.h | 63 + .../logos/png/openfx-horizontal-black.png | Bin 0 -> 7885 bytes .../logos/png/openfx-horizontal-color.png | Bin 0 -> 8795 bytes .../logos/png/openfx-horizontal-white.png | Bin 0 -> 7475 bytes .../openfx/logos/png/openfx-icon-black.png | Bin 0 -> 5613 bytes .../openfx/logos/png/openfx-icon-color.png | Bin 0 -> 6355 bytes .../openfx/logos/png/openfx-icon-white.png | Bin 0 -> 5283 bytes .../openfx/logos/png/openfx-stacked-black.png | Bin 0 -> 8121 bytes .../openfx/logos/png/openfx-stacked-color.png | Bin 0 -> 8831 bytes .../openfx/logos/png/openfx-stacked-white.png | Bin 0 -> 7721 bytes .../logos/svg/openfx-horizontal-black.svg | 57 + .../logos/svg/openfx-horizontal-color.svg | 65 + .../logos/svg/openfx-horizontal-white.svg | 61 + .../openfx/logos/svg/openfx-icon-black.svg | 49 + .../openfx/logos/svg/openfx-icon-color.svg | 57 + .../openfx/logos/svg/openfx-icon-white.svg | 53 + .../openfx/logos/svg/openfx-stacked-black.svg | 59 + .../openfx/logos/svg/openfx-stacked-color.svg | 67 + .../openfx/logos/svg/openfx-stacked-white.svg | 63 + 198 files changed, 57444 insertions(+), 980 deletions(-) delete mode 100644 .clang-tidy delete mode 100644 app/pluginSupport/Core.cpp delete mode 100644 app/pluginSupport/Dialog.cpp delete mode 100644 app/pluginSupport/DrawSuite.cpp delete mode 100644 app/pluginSupport/GpuRender.cpp delete mode 100644 app/pluginSupport/ImageEffect.cpp delete mode 100644 app/pluginSupport/Interact.cpp delete mode 100644 app/pluginSupport/KeySyms.cpp delete mode 100644 app/pluginSupport/Memory.cpp delete mode 100644 app/pluginSupport/Message.cpp delete mode 100644 app/pluginSupport/MultiThread.cpp create mode 100644 app/pluginSupport/OliveHost.cpp create mode 100644 app/pluginSupport/OliveHost.h create mode 100644 app/pluginSupport/OliveInstance.cpp create mode 100644 app/pluginSupport/OliveInstance.h delete mode 100644 app/pluginSupport/OlivePlugin.cpp delete mode 100644 app/pluginSupport/OlivePlugin.h delete mode 100644 app/pluginSupport/OpenGLRender.cpp delete mode 100644 app/pluginSupport/Param.cpp delete mode 100644 app/pluginSupport/ParametricParam.cpp delete mode 100644 app/pluginSupport/Pixels.cpp delete mode 100644 app/pluginSupport/Progress.cpp delete mode 100644 app/pluginSupport/Property.cpp delete mode 100644 app/pluginSupport/TimeLine.cpp delete mode 160000 third_party/openfx create mode 100644 third_party/openfx/HostSupport/BUILDING create mode 100644 third_party/openfx/HostSupport/CMakeLists.txt create mode 100644 third_party/openfx/HostSupport/README create mode 100644 third_party/openfx/HostSupport/TTD create mode 100644 third_party/openfx/HostSupport/include/ofxhBinary.h create mode 100755 third_party/openfx/HostSupport/include/ofxhClip.h create mode 100644 third_party/openfx/HostSupport/include/ofxhHost.h create mode 100755 third_party/openfx/HostSupport/include/ofxhImageEffect.h create mode 100644 third_party/openfx/HostSupport/include/ofxhImageEffectAPI.h create mode 100755 third_party/openfx/HostSupport/include/ofxhInteract.h create mode 100755 third_party/openfx/HostSupport/include/ofxhMemory.h create mode 100755 third_party/openfx/HostSupport/include/ofxhParam.h create mode 100644 third_party/openfx/HostSupport/include/ofxhPluginAPICache.h create mode 100644 third_party/openfx/HostSupport/include/ofxhPluginCache.h create mode 100644 third_party/openfx/HostSupport/include/ofxhProgress.h create mode 100644 third_party/openfx/HostSupport/include/ofxhPropertySuite.h create mode 100644 third_party/openfx/HostSupport/include/ofxhTimeLine.h create mode 100644 third_party/openfx/HostSupport/include/ofxhUtilities.h create mode 100644 third_party/openfx/HostSupport/include/ofxhXml.h create mode 100755 third_party/openfx/HostSupport/src/ofxhBinary.cpp create mode 100755 third_party/openfx/HostSupport/src/ofxhClip.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhHost.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhImageEffect.cpp create mode 100755 third_party/openfx/HostSupport/src/ofxhImageEffectAPI.cpp create mode 100755 third_party/openfx/HostSupport/src/ofxhInteract.cpp create mode 100755 third_party/openfx/HostSupport/src/ofxhMemory.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhParam.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhPluginAPICache.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhPluginCache.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhPropertySuite.cpp create mode 100644 third_party/openfx/HostSupport/src/ofxhUtilities.cpp create mode 100644 third_party/openfx/Support/CMakeLists.txt create mode 100644 third_party/openfx/Support/LICENSE create mode 100644 third_party/openfx/Support/Library/.gdb_history create mode 100644 third_party/openfx/Support/Library/CMakeLists.txt create mode 100755 third_party/openfx/Support/Library/ofxSupport.dsp create mode 100644 third_party/openfx/Support/Library/ofxsCore.cpp create mode 100644 third_party/openfx/Support/Library/ofxsImageEffect.cpp create mode 100644 third_party/openfx/Support/Library/ofxsInteract.cpp create mode 100644 third_party/openfx/Support/Library/ofxsLog.cpp create mode 100644 third_party/openfx/Support/Library/ofxsMultiThread.cpp create mode 100644 third_party/openfx/Support/Library/ofxsParams.cpp create mode 100644 third_party/openfx/Support/Library/ofxsProperty.cpp create mode 100644 third_party/openfx/Support/Library/ofxsPropertyValidation.cpp create mode 100644 third_party/openfx/Support/Library/ofxsSupportPrivate.h create mode 100755 third_party/openfx/Support/Library/ofxsupport.dsw create mode 100755 third_party/openfx/Support/Library/ofxsupport.vcproj create mode 100644 third_party/openfx/Support/OSXStaticLoader/pluginLoader.cpp create mode 100644 third_party/openfx/Support/Plugins/Basic/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Basic/basic.cpp create mode 100755 third_party/openfx/Support/Plugins/Basic/basic.dsp create mode 100755 third_party/openfx/Support/Plugins/Basic/basic.dsw create mode 100755 third_party/openfx/Support/Plugins/Basic/basic.vcproj create mode 100644 third_party/openfx/Support/Plugins/CMakeLists.txt create mode 100644 third_party/openfx/Support/Plugins/ChoiceParams/Info.plist create mode 100644 third_party/openfx/Support/Plugins/ChoiceParams/choiceparams.cpp create mode 100755 third_party/openfx/Support/Plugins/ExamplePlugs.sln create mode 100644 third_party/openfx/Support/Plugins/Field/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Field/field.cpp create mode 100755 third_party/openfx/Support/Plugins/Field/field.vcproj create mode 100644 third_party/openfx/Support/Plugins/GPUGain/CudaKernel.cu create mode 100644 third_party/openfx/Support/Plugins/GPUGain/GPUGain.cpp create mode 100644 third_party/openfx/Support/Plugins/GPUGain/GPUGain.h create mode 100644 third_party/openfx/Support/Plugins/GPUGain/GPUGain.sln create mode 100644 third_party/openfx/Support/Plugins/GPUGain/GPUGain.vcxproj create mode 100644 third_party/openfx/Support/Plugins/GPUGain/GPUGain.xcodeproj/project.pbxproj create mode 100644 third_party/openfx/Support/Plugins/GPUGain/Info.plist create mode 100644 third_party/openfx/Support/Plugins/GPUGain/MetalKernel.mm create mode 100644 third_party/openfx/Support/Plugins/GPUGain/OpenCLKernel.cpp create mode 100644 third_party/openfx/Support/Plugins/Generator/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Generator/noise.cpp create mode 100755 third_party/openfx/Support/Plugins/Generator/noise.dsp create mode 100755 third_party/openfx/Support/Plugins/Generator/noise.dsw create mode 100755 third_party/openfx/Support/Plugins/Generator/noise.vcproj create mode 100644 third_party/openfx/Support/Plugins/Invert/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Invert/invert.cpp create mode 100755 third_party/openfx/Support/Plugins/Invert/invert.vcproj create mode 100644 third_party/openfx/Support/Plugins/MultiBundle/Info.plist create mode 100755 third_party/openfx/Support/Plugins/MultiBundle/PluginRegistration.cpp create mode 100755 third_party/openfx/Support/Plugins/MultiBundle/multibundle.vcproj create mode 100755 third_party/openfx/Support/Plugins/MultiBundle/multibundle1.cpp create mode 100755 third_party/openfx/Support/Plugins/MultiBundle/multibundle1.h create mode 100644 third_party/openfx/Support/Plugins/MultiBundle/multibundle2.cpp create mode 100755 third_party/openfx/Support/Plugins/MultiBundle/multibundle2.h create mode 100644 third_party/openfx/Support/Plugins/Retimer/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Retimer/retimer.cpp create mode 100755 third_party/openfx/Support/Plugins/Retimer/retimer.dsp create mode 100755 third_party/openfx/Support/Plugins/Retimer/retimer.dsw create mode 100755 third_party/openfx/Support/Plugins/Retimer/retimer.vcproj create mode 100644 third_party/openfx/Support/Plugins/Tester/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Tester/Tester.cpp create mode 100644 third_party/openfx/Support/Plugins/Tester/Tester.vcproj create mode 100644 third_party/openfx/Support/Plugins/Transition/Info.plist create mode 100644 third_party/openfx/Support/Plugins/Transition/crossFade.cpp create mode 100755 third_party/openfx/Support/Plugins/Transition/crossFade.dsp create mode 100755 third_party/openfx/Support/Plugins/Transition/crossFade.dsw create mode 100755 third_party/openfx/Support/Plugins/Transition/crossFade.vcproj create mode 100644 third_party/openfx/Support/Plugins/include/README create mode 100644 third_party/openfx/Support/Plugins/include/ofxsImageBlender.H create mode 100644 third_party/openfx/Support/Plugins/include/ofxsProcessing.H create mode 100644 third_party/openfx/Support/PropTester/CMakeLists.txt create mode 100644 third_party/openfx/Support/PropTester/Info.plist create mode 100644 third_party/openfx/Support/PropTester/propTester.cpp create mode 100755 third_party/openfx/Support/PropTester/propTester.dsp create mode 100755 third_party/openfx/Support/PropTester/propTester.dsw create mode 100755 third_party/openfx/Support/PropTester/propTester.vcproj create mode 100644 third_party/openfx/Support/README create mode 100644 third_party/openfx/Support/Support.xcodeproj/project.pbxproj create mode 100644 third_party/openfx/Support/TODO create mode 100755 third_party/openfx/Support/include/ofxsCore.h create mode 100644 third_party/openfx/Support/include/ofxsImageEffect.h create mode 100644 third_party/openfx/Support/include/ofxsInteract.h create mode 100644 third_party/openfx/Support/include/ofxsLog.h create mode 100644 third_party/openfx/Support/include/ofxsMemory.h create mode 100644 third_party/openfx/Support/include/ofxsMessage.h create mode 100644 third_party/openfx/Support/include/ofxsMultiThread.h create mode 100644 third_party/openfx/Support/include/ofxsParam.h create mode 100644 third_party/openfx/Support/include/ofxsProcessing.h create mode 100755 third_party/openfx/Support/include/osxDeploy.sh create mode 100644 third_party/openfx/Support/support.doxy create mode 100644 third_party/openfx/include/DocSrc/footer.html create mode 100644 third_party/openfx/include/DocSrc/ofx_footer.html create mode 100644 third_party/openfx/include/DocSrc/ofx_header.html create mode 100644 third_party/openfx/include/DocSrc/ofx_style.css create mode 100644 third_party/openfx/include/OFX_navheader.png create mode 100644 third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h create mode 100644 third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio create mode 100644 third_party/openfx/include/ofx.doxy create mode 100644 third_party/openfx/include/ofx.dtd create mode 100644 third_party/openfx/include/ofxColour.h create mode 100644 third_party/openfx/include/ofxCore.h create mode 100644 third_party/openfx/include/ofxDialog.h create mode 100644 third_party/openfx/include/ofxDrawSuite.h create mode 100644 third_party/openfx/include/ofxGPURender.h create mode 100644 third_party/openfx/include/ofxImageEffect.h create mode 100644 third_party/openfx/include/ofxInteract.h create mode 100644 third_party/openfx/include/ofxKeySyms.h create mode 100644 third_party/openfx/include/ofxMemory.h create mode 100644 third_party/openfx/include/ofxMessage.h create mode 100644 third_party/openfx/include/ofxMultiThread.h create mode 100644 third_party/openfx/include/ofxOld.h create mode 100644 third_party/openfx/include/ofxOpenGLRender.h create mode 100644 third_party/openfx/include/ofxParam.h create mode 100644 third_party/openfx/include/ofxParametricParam.h create mode 100644 third_party/openfx/include/ofxPixels.h create mode 100644 third_party/openfx/include/ofxProgress.h create mode 100644 third_party/openfx/include/ofxProperty.h create mode 100644 third_party/openfx/include/ofxTimeLine.h create mode 100644 third_party/openfx/logos/png/openfx-horizontal-black.png create mode 100644 third_party/openfx/logos/png/openfx-horizontal-color.png create mode 100644 third_party/openfx/logos/png/openfx-horizontal-white.png create mode 100644 third_party/openfx/logos/png/openfx-icon-black.png create mode 100644 third_party/openfx/logos/png/openfx-icon-color.png create mode 100644 third_party/openfx/logos/png/openfx-icon-white.png create mode 100644 third_party/openfx/logos/png/openfx-stacked-black.png create mode 100644 third_party/openfx/logos/png/openfx-stacked-color.png create mode 100644 third_party/openfx/logos/png/openfx-stacked-white.png create mode 100644 third_party/openfx/logos/svg/openfx-horizontal-black.svg create mode 100644 third_party/openfx/logos/svg/openfx-horizontal-color.svg create mode 100644 third_party/openfx/logos/svg/openfx-horizontal-white.svg create mode 100644 third_party/openfx/logos/svg/openfx-icon-black.svg create mode 100644 third_party/openfx/logos/svg/openfx-icon-color.svg create mode 100644 third_party/openfx/logos/svg/openfx-icon-white.svg create mode 100644 third_party/openfx/logos/svg/openfx-stacked-black.svg create mode 100644 third_party/openfx/logos/svg/openfx-stacked-color.svg create mode 100644 third_party/openfx/logos/svg/openfx-stacked-white.svg diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index fd8c681c4..000000000 --- a/.clang-tidy +++ /dev/null @@ -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' \ No newline at end of file diff --git a/.gitignore b/.gitignore index a21cddf06..920df8e17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # CMake artifacts /build*/ - +build # Doxygen /docs/ diff --git a/.gitmodules b/.gitmodules index 426466e0c..cd2150bf4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,6 @@ -[submodule "ext/core"] +[submodule "ext/core"]README path = ext/core url = https://github.com/olive-editor/core [submodule "ext/KDDockWidgets"] path = ext/KDDockWidgets 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 303939381..6de42b934 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,10 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -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) +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_DOXYGEN "Build Doxygen documentation" OFF) option(BUILD_TESTS "Build unit tests" OFF) @@ -31,10 +37,11 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) + # 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 set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - +add_subdirectory(third_party/openfx/HostSupport) # Sanitizers add_library(olive-sanitizers INTERFACE) include(cmake/Sanitizers.cmake) @@ -168,7 +175,7 @@ list(APPEND OLIVE_LIBRARIES ) # Link FFmpeg -find_package(FFMPEG 3.0 REQUIRED +find_package(FFMPEG 7.0 REQUIRED COMPONENTS avutil avcodec diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index c0f4eb917..3776f5be6 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -18,7 +18,6 @@ set(OLIVE_SOURCES core.h core.cpp - pluginSupport/DrawSuite.cpp ) #set(OLIVE_RESOURCES) @@ -33,7 +32,6 @@ add_subdirectory(dialog) add_subdirectory(node) add_subdirectory(packaging) add_subdirectory(panel) -add_subdirectory(pluginSupport) add_subdirectory(render) add_subdirectory(shaders) add_subdirectory(task) @@ -75,8 +73,10 @@ add_library(libolive-editor ${OLIVE_SOURCES} ${OLIVE_RESOURCES} ) - -target_include_directories(libolive-editor PUBLIC ../third_party/openfx/include) +add_subdirectory(pluginSupport) +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" set_target_properties(libolive-editor PROPERTIES PREFIX "") @@ -86,7 +86,8 @@ add_executable(olive-editor $ $ ) - +target_include_directories(olive-editor PUBLIC pluginSupport) +target_link_libraries(olive-editor PUBLIC OfxHost) # Create docs if doxygen was found if(DOXYGEN_FOUND) set(DOXYGEN_PROJECT_NAME "Olive") diff --git a/app/main.cpp b/app/main.cpp index f6f77813e..90f5e28a2 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -52,7 +52,7 @@ extern "C" { #ifdef USE_CRASHPAD #include "common/crashpadinterface.h" #endif // USE_CRASHPAD - +#include "OlivePlugin.cpp" int decompress_project(const QString &project) { if (project.isEmpty()) { @@ -214,6 +214,11 @@ int main(int argc, char *argv[]) QStringLiteral("project"), 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) // // 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()) { startup_params.set_crash_on_startup(true); } diff --git a/app/node/plugins/Plugin.h b/app/node/plugins/Plugin.h index 6133def42..457a0ece8 100644 --- a/app/node/plugins/Plugin.h +++ b/app/node/plugins/Plugin.h @@ -20,7 +20,7 @@ #define PLUGIN_NODES_H #include "node/node.h" #include "pluginSupport/Plugin.h" -#include "pluginSupport/OlivePlugin.h" +#include "pluginSupport/OlivePlugin.cpp" namespace olive { namespace plugin diff --git a/app/pluginSupport/CMakeLists.txt b/app/pluginSupport/CMakeLists.txt index 4ef75de73..19b62b0f8 100644 --- a/app/pluginSupport/CMakeLists.txt +++ b/app/pluginSupport/CMakeLists.txt @@ -1,22 +1,6 @@ -set(OLIVE_SOURCES - ${OLIVE_SOURCES} - pluginSupport/OlivePlugin.h - pluginSupport/OlivePlugin.cpp - pluginSupport/Dialog.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 +target_sources(libolive-editor PRIVATE + OliveHost.h + OliveHost.cpp + OliveInstance.h + OliveInstance.cpp ) \ No newline at end of file diff --git a/app/pluginSupport/Core.cpp b/app/pluginSupport/Core.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Core.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Dialog.cpp b/app/pluginSupport/Dialog.cpp deleted file mode 100644 index 5a37fd612..000000000 --- a/app/pluginSupport/Dialog.cpp +++ /dev/null @@ -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 . - */ - -#include -#include - -OfxStatus NotifyRedrawPending() -{ - return kOfxStatReplyDefault; -} diff --git a/app/pluginSupport/DrawSuite.cpp b/app/pluginSupport/DrawSuite.cpp deleted file mode 100644 index 0116ea858..000000000 --- a/app/pluginSupport/DrawSuite.cpp +++ /dev/null @@ -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 . - */ - -#include "DrawSuite.h" diff --git a/app/pluginSupport/GpuRender.cpp b/app/pluginSupport/GpuRender.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/GpuRender.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/ImageEffect.cpp b/app/pluginSupport/ImageEffect.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/ImageEffect.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Interact.cpp b/app/pluginSupport/Interact.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Interact.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/KeySyms.cpp b/app/pluginSupport/KeySyms.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/KeySyms.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Memory.cpp b/app/pluginSupport/Memory.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Memory.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Message.cpp b/app/pluginSupport/Message.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Message.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/MultiThread.cpp b/app/pluginSupport/MultiThread.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/MultiThread.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/OliveHost.cpp b/app/pluginSupport/OliveHost.cpp new file mode 100644 index 000000000..8477cb4fd --- /dev/null +++ b/app/pluginSupport/OliveHost.cpp @@ -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 . + */ + +#include "node/project.h" +#include "ofxhImageEffect.h" +#include +#include +#include + +#include +#include +#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; +}; diff --git a/app/pluginSupport/OliveHost.h b/app/pluginSupport/OliveHost.h new file mode 100644 index 000000000..f0d39d633 --- /dev/null +++ b/app/pluginSupport/OliveHost.h @@ -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 . + */ +#include "ofxhHost.h" +#include "ofxhImageEffectAPI.h" +#include "ofxCore.h" +#include "ofxhImageEffect.h" + +#include +#include +#include +#include +#include +#include +#include +#include +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 descriptors_; + QList instances_; +}; +} +} \ No newline at end of file diff --git a/app/pluginSupport/OliveInstance.cpp b/app/pluginSupport/OliveInstance.cpp new file mode 100644 index 000000000..bac1cd081 --- /dev/null +++ b/app/pluginSupport/OliveInstance.cpp @@ -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 . + */ +#include "OliveInstance.h" +#include "ofxCore.h" +#include "ofxMessage.h" +#include +#include +#include +#include +#include +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; + } +} + +} +} diff --git a/app/pluginSupport/OliveInstance.h b/app/pluginSupport/OliveInstance.h new file mode 100644 index 000000000..6522efa6d --- /dev/null +++ b/app/pluginSupport/OliveInstance.h @@ -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 . + */ + +#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; + + +}; +} +} \ No newline at end of file diff --git a/app/pluginSupport/OlivePlugin.cpp b/app/pluginSupport/OlivePlugin.cpp deleted file mode 100644 index 8395979f4..000000000 --- a/app/pluginSupport/OlivePlugin.cpp +++ /dev/null @@ -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 . - */ -#include "OlivePlugin.h" - -#include -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 vec; - vec.emplace_back(str); - stringProps[key]=vec; - return kOfxStatOK; -} -OfxStatus olive::plugin::OlivePlugin::setPropN(QString key, int count, char **strs) -{ - QVector vector; - for (int i=0;iindex) { - pointerProps[key].insert(index, p); - return kOfxStatOK; - } - pointerProps[key].emplace_back(p); - return kOfxStatOK; - } - QVector vec; - vec.emplace_back(p); - pointerProps[key]=vec; - return kOfxStatOK; -} -OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, void **ps) -{ - QVector 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 vec; - vec.emplace_back(p); - intProps[key]=vec; - return kOfxStatOK; -} -OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, int *ps) -{ - QVector 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 vec; - vec.emplace_back(p); - doubleProps[key]=vec; - return kOfxStatOK; -} -OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, double *ps) -{ - QVector vector; - vector.reserve(count); - memcpy(vector.data(), ps, sizeof(doubleProps)*count); - doubleProps[key]=vector; - return kOfxStatOK; -} - diff --git a/app/pluginSupport/OlivePlugin.h b/app/pluginSupport/OlivePlugin.h deleted file mode 100644 index 6ccc9f4dd..000000000 --- a/app/pluginSupport/OlivePlugin.h +++ /dev/null @@ -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 . - */ - -#ifndef OLIVE_PLUGIN_H -#define OLIVE_PLUGIN_H -#include "OlivePlugin.h" -#include "ofxCore.h" -#include -#include -#include -#include -#include -#include -#include -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> stringProps; - QMap> intProps; - QMap> doubleProps; - QMap> pointerProps; - std::list mems; -}; -} -} -struct OfxPropertySetStruct { - olive::plugin::OlivePlugin* plugin; -}; -#endif //OLIVE_PLUGIN_H diff --git a/app/pluginSupport/OpenGLRender.cpp b/app/pluginSupport/OpenGLRender.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/OpenGLRender.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Param.cpp b/app/pluginSupport/Param.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Param.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/ParametricParam.cpp b/app/pluginSupport/ParametricParam.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/ParametricParam.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Pixels.cpp b/app/pluginSupport/Pixels.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Pixels.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Progress.cpp b/app/pluginSupport/Progress.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/Progress.cpp +++ /dev/null @@ -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 . - */ diff --git a/app/pluginSupport/Property.cpp b/app/pluginSupport/Property.cpp deleted file mode 100644 index fad450e9e..000000000 --- a/app/pluginSupport/Property.cpp +++ /dev/null @@ -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 . - */ -#include "node/plugins/Plugin.h" - -#include -#include -#include - -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(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(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(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(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(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; -} diff --git a/app/pluginSupport/TimeLine.cpp b/app/pluginSupport/TimeLine.cpp deleted file mode 100644 index 52182e8d4..000000000 --- a/app/pluginSupport/TimeLine.cpp +++ /dev/null @@ -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 . - */ diff --git a/third_party/openfx b/third_party/openfx deleted file mode 160000 index 6aa45d817..000000000 --- a/third_party/openfx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6aa45d81799f04208af26434cc62a292ebd22924 diff --git a/third_party/openfx/HostSupport/BUILDING b/third_party/openfx/HostSupport/BUILDING new file mode 100644 index 000000000..de4d2328c --- /dev/null +++ b/third_party/openfx/HostSupport/BUILDING @@ -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 + + diff --git a/third_party/openfx/HostSupport/CMakeLists.txt b/third_party/openfx/HostSupport/CMakeLists.txt new file mode 100644 index 000000000..61fc531d3 --- /dev/null +++ b/third_party/openfx/HostSupport/CMakeLists.txt @@ -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}) diff --git a/third_party/openfx/HostSupport/README b/third_party/openfx/HostSupport/README new file mode 100644 index 000000000..83d00609f --- /dev/null +++ b/third_party/openfx/HostSupport/README @@ -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 + Andrew Whitmore + Bruno Nicoletti + +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 + diff --git a/third_party/openfx/HostSupport/TTD b/third_party/openfx/HostSupport/TTD new file mode 100644 index 000000000..525a5e760 --- /dev/null +++ b/third_party/openfx/HostSupport/TTD @@ -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. + + + diff --git a/third_party/openfx/HostSupport/include/ofxhBinary.h b/third_party/openfx/HostSupport/include/ofxhBinary.h new file mode 100644 index 000000000..70b4d05f8 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhBinary.h @@ -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 +#include + +#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 +#elif defined (WINDOWS) +#include "windows.h" +#include +#endif + +#include + +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 diff --git a/third_party/openfx/HostSupport/include/ofxhClip.h b/third_party/openfx/HostSupport/include/ofxhClip.h new file mode 100755 index 000000000..495f4355f --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhClip.h @@ -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 &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 diff --git a/third_party/openfx/HostSupport/include/ofxhHost.h b/third_party/openfx/HostSupport/include/ofxhHost.h new file mode 100644 index 000000000..c74158ee3 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhHost.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 +#include +#include + +#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 + diff --git a/third_party/openfx/HostSupport/include/ofxhImageEffect.h b/third_party/openfx/HostSupport/include/ofxhImageEffect.h new file mode 100755 index 000000000..e9d641e99 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhImageEffect.h @@ -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 _clips; ///< clips descriptors by name + std::vector _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 &getClips() const; + + /// add a new clip + void addClip(const std::string &name, ClipDescriptor *clip); + + /// get the clips in order of construction + const std::vector &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 > 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 _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 &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 diff --git a/third_party/openfx/HostSupport/include/ofxhImageEffectAPI.h b/third_party/openfx/HostSupport/include/ofxhImageEffectAPI.h new file mode 100644 index 000000000..ed762e771 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhImageEffectAPI.h @@ -0,0 +1,221 @@ + + + +#ifndef OFXH_IMAGE_EFFECT_API_H +#define OFXH_IMAGE_EFFECT_API_H + +#include "ofxhPluginAPICache.h" +#include "ofxhPluginCache.h" +#include +#include +#include +#include +#include + +#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> _contexts; + + mutable std::set _knownContexts; + mutable bool _madeKnownContexts; + + std::unique_ptr _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 ied); + + virtual void saveXML(std::ostream &os); + + const std::set& 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 _plugins; + + /// latest version of each plugin by ID + std::map _pluginsByID; + + /// latest minor version of each plugin by (ID,major) + std::map _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& getPlugins() const; + + [[nodiscard]] const std::map& getPluginsByID() const; + + [[nodiscard]] const std::map& 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 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 diff --git a/third_party/openfx/HostSupport/include/ofxhInteract.h b/third_party/openfx/HostSupport/include/ofxhInteract.h new file mode 100755 index 000000000..c38aad487 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhInteract.h @@ -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& 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 diff --git a/third_party/openfx/HostSupport/include/ofxhMemory.h b/third_party/openfx/HostSupport/include/ofxhMemory.h new file mode 100755 index 000000000..a16e817c5 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhMemory.h @@ -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 diff --git a/third_party/openfx/HostSupport/include/ofxhParam.h b/third_party/openfx/HostSupport/include/ofxhParam.h new file mode 100755 index 000000000..bbc15336e --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhParam.h @@ -0,0 +1,678 @@ + + + +#ifndef OFXH_PARAM_H +#define OFXH_PARAM_H + +#include +#include +#include +#include + +//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 _paramMap; + std::list _paramList; + + /// CC doesn't exist + SetDescriptor(const SetDescriptor &); + + public: + /// default ctor + SetDescriptor(); + + /// dtor + virtual ~SetDescriptor(); + + /// get the map of params + const std::map &getParams() const; + + /// get the list of params + const std::list &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 _children; + public: + GroupInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {} + + void setChildren(std::vector children); + const std::vector &getChildren() const; + }; + + class PageInstance : public Instance { + public: + PageInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {} + const std::map &getChildren() const; + protected : + mutable std::map _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 _params; ///< params by name + std::list _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 &getParams() const; + + /// get the params + const std::list &getParamList() const; + + // get the param + Instance* getParam(const std::string &name) const { + std::map::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 diff --git a/third_party/openfx/HostSupport/include/ofxhPluginAPICache.h b/third_party/openfx/HostSupport/include/ofxhPluginAPICache.h new file mode 100644 index 000000000..25c3d28ef --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhPluginAPICache.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 +#include +#include +#include + +#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) = 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 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 diff --git a/third_party/openfx/HostSupport/include/ofxhPluginCache.h b/third_party/openfx/HostSupport/include/ofxhPluginCache.h new file mode 100644 index 000000000..776e8d6c7 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhPluginCache.h @@ -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 +#include +#include +#include +#include + +#include + +#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 _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 _pluginPath; ///< list of directories to look in + std::set _nonrecursePath; ///< list of directories to look in (non-recursively) + std::list _pluginDirs; ///< list of directories we found + std::list _binaries; ///< all the binaries we know about, we own these + std::list _plugins; ///< all the plugins inside the binaries, we don't own these, populated from _binaries + std::set _knownBinFiles; + + PluginBinary *_xmlCurrentBinary; + Plugin *_xmlCurrentPlugin; + + std::list _apiHandlers; + + void scanDirectory(std::set &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 &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 &getPlugins() const { + return _plugins; + } + }; + + } +} + +#endif diff --git a/third_party/openfx/HostSupport/include/ofxhProgress.h b/third_party/openfx/HostSupport/include/ofxhProgress.h new file mode 100644 index 000000000..5e1a85f7a --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhProgress.h @@ -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 diff --git a/third_party/openfx/HostSupport/include/ofxhPropertySuite.h b/third_party/openfx/HostSupport/include/ofxhPropertySuite.h new file mode 100644 index 000000000..cb73d922d --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhPropertySuite.h @@ -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 +#include +#include +#include +#include + +namespace OFX { + namespace Host { + namespace Property { + /// simple function to turn a thing into a std string + template 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 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 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 _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 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 _value; + + /// this is the default value of the property + std::vector _defaultValue; + + public : + /// constructor + PropertyTemplate(const std::string &name, + int dimension, + bool pluginReadOnly, + APIType defaultValue); + + PropertyTemplate(const PropertyTemplate &pt); + + PropertyTemplate *deepCopy() { + return new PropertyTemplate(*this); + } + + virtual ~PropertyTemplate() + { + } + + /// get the vector + const std::vector &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 Int; /// Our int property + typedef PropertyTemplate Double; /// Our double property + typedef PropertyTemplate String; /// Our string property + typedef PropertyTemplate 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 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 void setProperty(const std::string &property, int index, const typename T::Type &value); + + /// set the first N of a particular property + template void setPropertyN(const std::string &property, int count, const typename T::APIType *value); + + /// get a particular property + template typename T::ReturnType getProperty(const std::string &property, int index) const; + + /// get the first N of a particular property + template void getPropertyN(const std::string &property, int index, typename T::APIType *v) const; + + /// get a particular property without going through any getHook + template typename T::ReturnType getPropertyRaw(const std::string &property, int index) const; + + /// get a particular property without going through any getHook + template 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 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 diff --git a/third_party/openfx/HostSupport/include/ofxhTimeLine.h b/third_party/openfx/HostSupport/include/ofxhTimeLine.h new file mode 100644 index 000000000..95f73f65e --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhTimeLine.h @@ -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 diff --git a/third_party/openfx/HostSupport/include/ofxhUtilities.h b/third_party/openfx/HostSupport/include/ofxhUtilities.h new file mode 100644 index 000000000..b71e2dd18 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhUtilities.h @@ -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 +#include +#include +#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 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 inline T Minimum(const T &a, const T &b) + { + return a < b ? a : b; + } + + /// get the min value + template inline T Maximum(const T &a, const T &b) + { + return a > b ? a : b; + } + + /// clamp the value + template 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 + + diff --git a/third_party/openfx/HostSupport/include/ofxhXml.h b/third_party/openfx/HostSupport/include/ofxhXml.h new file mode 100644 index 000000000..194397914 --- /dev/null +++ b/third_party/openfx/HostSupport/include/ofxhXml.h @@ -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': + 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 diff --git a/third_party/openfx/HostSupport/src/ofxhBinary.cpp b/third_party/openfx/HostSupport/src/ofxhBinary.cpp new file mode 100755 index 000000000..265afbd8d --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhBinary.cpp @@ -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; + } +} + + diff --git a/third_party/openfx/HostSupport/src/ofxhClip.cpp b/third_party/openfx/HostSupport/src/ofxhClip.cpp new file mode 100755 index 000000000..fdc900389 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhClip.cpp @@ -0,0 +1,654 @@ + + +#include + +// 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 &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<<"->"<mainEntry(kOfxActionInstanceChanged, _effectInstance->getHandle(), &inArgs, 0); + } else { + st = kOfxStatFailed; + } +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)_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 &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 diff --git a/third_party/openfx/HostSupport/src/ofxhHost.cpp b/third_party/openfx/HostSupport/src/ofxhHost.cpp new file mode 100644 index 000000000..27b12d318 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhHost.cpp @@ -0,0 +1,124 @@ + + +#include +#include +#include +#include + +// 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(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 diff --git a/third_party/openfx/HostSupport/src/ofxhImageEffect.cpp b/third_party/openfx/HostSupport/src/ofxhImageEffect.cpp new file mode 100644 index 000000000..042e44491 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhImageEffect.cpp @@ -0,0 +1,2809 @@ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +#include + +// 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 "ofxhUtilities.h" +#ifdef OFX_SUPPORTS_PARAMETRIC +#include "ofxhParametricParam.h" +#endif +#ifdef OFX_SUPPORTS_OPENGLRENDER +#include "ofxGPURender.h" +#endif +#include "ofxOld.h" // old plugins may rely on deprecated properties being present + +#include +#include + +namespace OFX { + + namespace Host { + + namespace ImageEffect { + + /// properties common on an effect and a descriptor + static const Property::PropSpec effectDescriptorStuff[] = { + /* name type dim. r/o default value */ + { kOfxPropType, Property::eString, 1, true, kOfxTypeImageEffect }, + { kOfxPropLabel, Property::eString, 1, false, "" }, + { kOfxPropShortLabel, Property::eString, 1, false, "" }, + { kOfxPropLongLabel, Property::eString, 1, false, "" }, + { kOfxPropVersion, Property::eInt, 0, false, "0" }, + { kOfxPropVersionLabel, Property::eString, 1, false, "" }, + { kOfxPropPluginDescription, Property::eString, 1, false, "" }, + { kOfxImageEffectPropSupportedContexts, Property::eString, 0, false, "" }, + { kOfxImageEffectPluginPropGrouping, Property::eString, 1, false, "" }, + { kOfxImageEffectPluginPropSingleInstance, Property::eInt, 1, false, "0" }, + { kOfxImageEffectPluginRenderThreadSafety, Property::eString, 1, false, kOfxImageEffectRenderInstanceSafe }, + { kOfxImageEffectPluginPropHostFrameThreading, Property::eInt, 1, false, "1" }, + { kOfxImageEffectPluginPropOverlayInteractV1, Property::ePointer, 1, false, NULL }, + { kOfxImageEffectPropSupportsMultiResolution, Property::eInt, 1, false, "1" } , + { kOfxImageEffectPropSupportsTiles, Property::eInt, 1, false, "1" }, + { kOfxImageEffectPropTemporalClipAccess, Property::eInt, 1, false, "0" }, + { kOfxImageEffectPropSupportedPixelDepths, Property::eString, 0, false, "" }, + { kOfxImageEffectPluginPropFieldRenderTwiceAlways, Property::eInt, 1, false, "1" } , + { kOfxImageEffectPropSupportsMultipleClipDepths, Property::eInt, 1, false, "0" }, + { kOfxImageEffectPropSupportsMultipleClipPARs, Property::eInt, 1, false, "0" }, + { kOfxImageEffectPropClipPreferencesSlaveParam, Property::eString, 0, false, "" }, + { kOfxImageEffectInstancePropSequentialRender, Property::eInt, 1, false, "0" }, + { kOfxPluginPropFilePath, Property::eString, 1, true, ""}, +#ifdef OFX_SUPPORTS_OPENGLRENDER + { kOfxImageEffectPropOpenGLRenderSupported, Property::eString, 1, false, "false"}, // OFX 1.3 + { kOfxImageEffectPropCudaRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropCudaStreamSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropMetalRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropOpenCLRenderSupported, Property::eString, 1, false, "false" }, +#endif + + Property::propSpecEnd + }; + + // + // Base + // + + Base::Base(const Property::Set &set) + : _properties(set) + {} + + Base::Base(const Property::PropSpec * propSpec) + : _properties(propSpec) + {} + + Base::~Base() {} + + /// obtain a handle on this for passing to the C api + OfxImageEffectHandle Base::getHandle() const { + return (OfxImageEffectHandle)this; + } + + /// get the properties set + Property::Set &Base::getProps() { + return _properties; + } + + /// get the properties set, const version + const Property::Set &Base::getProps() const { + return _properties; + } + + /// name of the clip + const std::string &Base::getShortLabel() const + { + const std::string &s = _properties.getStringProperty(kOfxPropShortLabel); + if(s == "") { + const std::string &s2 = _properties.getStringProperty(kOfxPropLabel); + if(s2 == "") { + return _properties.getStringProperty(kOfxPropName); + } + } + return s; + } + + /// name of the clip + const std::string &Base::getLabel() const + { + const std::string &s = _properties.getStringProperty(kOfxPropLabel); + if(s == "") { + return _properties.getStringProperty(kOfxPropName); + } + return s; + } + + /// name of the clip + const std::string &Base::getLongLabel() const + { + const std::string &s = _properties.getStringProperty(kOfxPropLongLabel); + if(s == "") { + const std::string &s2 = _properties.getStringProperty(kOfxPropLabel); + if(s2 == "") { + return _properties.getStringProperty(kOfxPropName); + } + } + return s; + } + + /// is the given context supported + bool Base::isContextSupported(const std::string &s) const + { + return _properties.findStringPropValueIndex(kOfxImageEffectPropSupportedContexts, s) != -1; + } + + /// what is the name of the group the plug-in belongs to + const std::string &Base::getPluginGrouping() const + { + return _properties.getStringProperty(kOfxImageEffectPluginPropGrouping); + } + + /// is the effect single instance + bool Base::isSingleInstance() const + { + return _properties.getIntProperty(kOfxImageEffectPluginPropSingleInstance) != 0; + } + + /// what is the thread safety on this effect + const std::string &Base::getRenderThreadSafety() const + { + return _properties.getStringProperty(kOfxImageEffectPluginRenderThreadSafety); + } + + /// should the host attempt to managed multi-threaded rendering if it can + /// via tiling or some such + bool Base::getHostFrameThreading() const + { + return _properties.getIntProperty(kOfxImageEffectPluginPropHostFrameThreading) != 0; + } + + /// get the overlay interact main entry if it exists + OfxPluginEntryPoint *Base::getOverlayInteractMainEntry() const + { + return (OfxPluginEntryPoint *)(_properties.getPointerProperty(kOfxImageEffectPluginPropOverlayInteractV1)); + } + + /// does the effect support images of differing sizes + bool Base::supportsMultiResolution() const + { + return _properties.getIntProperty(kOfxImageEffectPropSupportsMultiResolution) != 0; + } + + /// does the effect support tiled rendering + bool Base::supportsTiles() const + { + return _properties.getIntProperty(kOfxImageEffectPropSupportsTiles) != 0; + } + + /// does this effect need random temporal access + bool Base::temporalAccess() const + { + return _properties.getIntProperty(kOfxImageEffectPropTemporalClipAccess) != 0; + } + + /// is the given RGBA/A pixel depth supported by the effect + bool Base::isPixelDepthSupported(const std::string &s) const + { + return _properties.findStringPropValueIndex(kOfxImageEffectPropSupportedPixelDepths, s) != -1; + } + + /// when field rendering, does the effect need to be called + /// twice to render a frame in all Base::circumstances (with different fields) + bool Base::fieldRenderTwiceAlways() const + { + return _properties.getIntProperty(kOfxImageEffectPluginPropFieldRenderTwiceAlways) != 0; + } + + /// does the effect support multiple clip depths + bool Base::supportsMultipleClipDepths() const + { + return _properties.getIntProperty(kOfxImageEffectPropSupportsMultipleClipDepths) != 0; + } + + /// does the effect support multiple clip pixel aspect ratios + bool Base::supportsMultipleClipPARs() const + { + return _properties.getIntProperty(kOfxImageEffectPropSupportsMultipleClipPARs) != 0; + } + + /// does changing the named param re-tigger a clip preferences action + bool Base::isClipPreferencesSlaveParam(const std::string &s) const + { + return _properties.findStringPropValueIndex(kOfxImageEffectPropClipPreferencesSlaveParam, s) != -1; + } + + + //////////////////////////////////////////////////////////////////////////////// + // descriptor + + Descriptor::Descriptor(Plugin *plug) + : Base(effectDescriptorStuff) + , _plugin(plug) + { + _properties.setStringProperty(kOfxPluginPropFilePath, plug->getBinary()->getBundlePath()); + gImageEffectHost->initDescriptor(this); + } + + Descriptor::Descriptor(const Descriptor &other, Plugin *plug) + : Base(other._properties) + , _plugin(plug) + { + _properties.setStringProperty(kOfxPluginPropFilePath, plug->getBinary()->getBundlePath()); + gImageEffectHost->initDescriptor(this); + } + + Descriptor::Descriptor(const std::string &bundlePath, Plugin *plug) + : Base(effectDescriptorStuff) + , _plugin(plug) + { + _properties.setStringProperty(kOfxPluginPropFilePath, bundlePath); + gImageEffectHost->initDescriptor(this); + } + + Descriptor::~Descriptor() + { + for(std::map::iterator it = _clips.begin(); it != _clips.end(); ++it) + delete it->second; + _clips.clear(); + } + + + /// create a new clip and add this to the clip map + ClipDescriptor *Descriptor::defineClip(const std::string &name) { + ClipDescriptor *c = new ClipDescriptor(name); + _clips[name] = c; + _clipsByOrder.push_back(c); + return c; + } + + /// implemented for Param::SetDescriptor + Property::Set &Descriptor::getParamSetProps() + { + return _properties; + } + + /// get the interact description, this will also call describe on the interact + Interact::Descriptor &Descriptor::getOverlayDescriptor(int bitDepthPerComponent, bool hasAlpha) + { + if(_overlayDescriptor.getState() == Interact::eUninitialised) { + // OK, we need to describe it, set the entry point and describe away + _overlayDescriptor.setEntryPoint(getOverlayInteractMainEntry()); + _overlayDescriptor.describe(bitDepthPerComponent, hasAlpha); + } + + return _overlayDescriptor; + } + + /// get the clips + const std::map &Descriptor::getClips() const { + return _clips; + } + + void Descriptor::addClip(const std::string &name, ClipDescriptor *clip) { + _clips[name] = clip; + _clipsByOrder.push_back(clip); + } + + // + // Instance + // + + static const Property::PropSpec effectInstanceStuff[] = { + /* name type dim. r/o default value */ + { kOfxPropType, Property::eString, 1, true, kOfxTypeImageEffectInstance }, + { kOfxImageEffectPropContext, Property::eString, 1, true, "" }, + { kOfxPropInstanceData, Property::ePointer, 1, false, NULL }, + { kOfxImageEffectPropPluginHandle, Property::ePointer, 1, false, NULL }, + { kOfxImageEffectPropProjectSize, Property::eDouble, 2, true, "0" }, + { kOfxImageEffectPropProjectOffset, Property::eDouble, 2, true, "0" }, + { kOfxImageEffectPropProjectExtent, Property::eDouble, 2, true, "0" }, + { kOfxImageEffectPropProjectPixelAspectRatio, Property::eDouble, 1, true, "0" }, + { kOfxImageEffectInstancePropEffectDuration, Property::eDouble, 1, true, "0" }, + { kOfxImageEffectInstancePropSequentialRender, Property::eInt, 1, false, "0" }, + { kOfxImageEffectPropFrameRate , Property::eDouble, 1, true, "0" }, + { kOfxPropIsInteractive, Property::eInt, 1, true, "0" }, +# ifdef kOfxImageEffectPropInAnalysis + { kOfxImageEffectPropInAnalysis, Property::eInt, 1, false, "0" }, // removed in OFX 1.4 +# endif + { kOfxImageEffectPropSupportsTiles, Property::eInt, 1, false, "1" }, // OFX 1.4 +#ifdef OFX_SUPPORTS_OPENGLRENDER + { kOfxImageEffectPropOpenGLRenderSupported, Property::eString, 1, false, "false"}, // OFX 1.4 + { kOfxImageEffectPropCudaRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropCudaStreamSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropMetalRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropOpenCLRenderSupported, Property::eString, 1, false, "false" }, +#endif + Property::propSpecEnd + }; + + Instance::Instance(ImageEffectPlugin* plugin, + Descriptor &other, + const std::string &context, + bool interactive) + : Base(effectInstanceStuff) + , _plugin(plugin) + , _context(context) + , _descriptor(&other) + , _interactive(interactive) + , _created(false) + , _clipPrefsDirty(true) + , _continuousSamples(false) + , _frameVarying(false) + , _outputFrameRate(24) + { + int i = 0; + _properties.setChainedSet(&other.getProps()); + + _properties.setPointerProperty(kOfxImageEffectPropPluginHandle, _plugin->getPluginHandle()->getOfxPlugin()); + + _properties.setStringProperty(kOfxImageEffectPropContext,context); + _properties.setIntProperty(kOfxPropIsInteractive,interactive); + + // copy is sequential over + bool sequential = other.getProps().getIntProperty(kOfxImageEffectInstancePropSequentialRender) != 0; + _properties.setIntProperty(kOfxImageEffectInstancePropSequentialRender,sequential); + + while(effectInstanceStuff[i].name) { + + // don't set hooks for context or isinteractive + + if(strcmp(effectInstanceStuff[i].name,kOfxImageEffectPropContext) && + strcmp(effectInstanceStuff[i].name,kOfxPropIsInteractive) && + strcmp(effectInstanceStuff[i].name,kOfxImageEffectInstancePropSequentialRender) ) + { + const Property::PropSpec& spec = effectInstanceStuff[i]; + + switch (spec.type) { + case Property::eDouble: + _properties.setGetHook(spec.name, this); + break; + default: + break; + } + } + + i++; + } + } + + /// implemented for Param::SetDescriptor + Property::Set &Instance::getParamSetProps() + { + return _properties; + } + + /// called after construction to populate clips and params + OfxStatus Instance::populate() + { + const std::vector& clips = _descriptor->getClipsByOrder(); + + int counter = 0; + for(std::vector::const_iterator it=clips.begin(); + it!=clips.end(); + ++it, ++counter) { + const std::string &name = (*it)->getName(); + // foreach clip descriptor make a clip instance + ClipInstance* instance = newClipInstance(this, *it, counter); + if(!instance) return kOfxStatFailed; + + _clips[name] = instance; + } + + const std::list& map = _descriptor->getParamList(); + + std::map > parameters; + std::map groups; + + for(std::list::const_iterator it=map.begin(); + it!=map.end(); + ++it) { + Param::Descriptor* descriptor = (*it); + // get the param descriptor + if(!descriptor) return kOfxStatErrValue; + + // name of the parameter + std::string name = descriptor->getName(); + + // get a param instance from a param descriptor + Param::Instance* instance = newParam(name,*descriptor); + if(!instance) return kOfxStatFailed; + + // add the value into the param set instance + OfxStatus st = addParam(name,instance); + if(st != kOfxStatOK) return st; + + std::string parent = instance->getParentName(); + + if(parent!="") + parameters[parent].push_back(instance); + + if(instance->getType()==kOfxParamTypeGroup){ + groups[instance->getName()]=instance; + } + } + + // for each group parameter made + for(std::map::iterator it=groups.begin(); + it!=groups.end(); + ++it) { + // cast to a group instance + Param::GroupInstance* group = dynamic_cast(it->second); + + // if cast ok + if(group){ + // find the parameters whose parent was this group + std::map >::iterator it2 = parameters.find(group->getName()); + if(it2!=parameters.end()){ + // associate the group with its children, and the children with its parent group + group->setChildren(it2->second); + } + } + } + + return kOfxStatOK; + } + + // do nothing + int Instance::getDimension(const std::string &name) const { + printf("failing in %s with name=%s\n", __PRETTY_FUNCTION__, name.c_str()); + throw Property::Exception(kOfxStatErrMissingHostFeature); + } + + int Instance::upperGetDimension(const std::string &name) { + return _properties.getDimension(name); + } + + void Instance::notify(const std::string &/*name*/, bool /*singleValue*/, int /*indexOrN*/) + { + printf("failing in %s\n", __PRETTY_FUNCTION__); + } + + // don't know what to do + void Instance::reset(const std::string &/*name*/) { + printf("failing in %s\n", __PRETTY_FUNCTION__); + throw Property::Exception(kOfxStatErrMissingHostFeature); + } + + // get the virutals for viewport size, pixel scale, background colour + double Instance::getDoubleProperty(const std::string &name, int index) const + { + if(name==kOfxImageEffectPropProjectSize){ + if(index>=2) throw Property::Exception(kOfxStatErrBadIndex); + double values[2]; + getProjectSize(values[0],values[1]); + return values[index]; + } + else if(name==kOfxImageEffectPropProjectOffset){ + if(index>=2) throw Property::Exception(kOfxStatErrBadIndex); + double values[2]; + getProjectOffset(values[0],values[1]); + return values[index]; + } + else if(name==kOfxImageEffectPropProjectExtent){ + if(index>=2) throw Property::Exception(kOfxStatErrBadIndex); + double values[2]; + getProjectExtent(values[0],values[1]); + return values[index]; + } + else if(name==kOfxImageEffectPropProjectPixelAspectRatio){ + if(index>=1) throw Property::Exception(kOfxStatErrBadIndex); + return getProjectPixelAspectRatio(); + } + else if(name==kOfxImageEffectInstancePropEffectDuration){ + if(index>=1) throw Property::Exception(kOfxStatErrBadIndex); + return getEffectDuration(); + } + else if(name==kOfxImageEffectPropFrameRate){ + if(index>=1) throw Property::Exception(kOfxStatErrBadIndex); + return getFrameRate(); + } + else + throw Property::Exception(kOfxStatErrUnknown); + } + + void Instance::getDoublePropertyN(const std::string &name, double* first, int n) const + { + if(name==kOfxImageEffectPropProjectSize){ + if(n>2) throw Property::Exception(kOfxStatErrBadIndex); + getProjectSize(first[0],first[1]); + } + else if(name==kOfxImageEffectPropProjectOffset){ + if(n>2) throw Property::Exception(kOfxStatErrBadIndex); + getProjectOffset(first[0],first[1]); + } + else if(name==kOfxImageEffectPropProjectExtent){ + if(n>2) throw Property::Exception(kOfxStatErrBadIndex); + getProjectExtent(first[0],first[1]); + } + else if(name==kOfxImageEffectPropProjectPixelAspectRatio){ + if(n>1) throw Property::Exception(kOfxStatErrBadIndex); + *first = getProjectPixelAspectRatio(); + } + else if(name==kOfxImageEffectInstancePropEffectDuration){ + if(n>1) throw Property::Exception(kOfxStatErrBadIndex); + *first = getEffectDuration(); + } + else if(name==kOfxImageEffectPropFrameRate){ + if(n>1) throw Property::Exception(kOfxStatErrBadIndex); + *first = getFrameRate(); + } + else + throw Property::Exception(kOfxStatErrUnknown); + } + + Instance::~Instance(){ + // destroy the instance, only if succesfully created + if (_created) { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<::iterator i; + for(i = _clips.begin(); i != _clips.end(); ++i) { + if(i->second) + delete i->second; + i->second = NULL; + } + } + + /// this is used to populate with any extra action in argumnents that may be needed + void Instance::setCustomInArgs(const std::string &/*action*/, Property::Set &/*inArgs*/) + { + } + + /// this is used to populate with any extra action out argumnents that may be needed + void Instance::setCustomOutArgs(const std::string &/*action*/, Property::Set &/*outArgs*/) + { + } + + /// this is used to populate with any extra action out argumnents that may be needed + void Instance::examineOutArgs(const std::string &/*action*/, OfxStatus, const Property::Set &/*outArgs*/) + { + } + + /// check for connection + bool Instance::checkClipConnectionStatus() const + { + std::map::const_iterator i; + for(i = _clips.begin(); i != _clips.end(); ++i) { + if(!i->second->isOptional() && !i->second->getConnected()) { + return false; + } + } + return true; + } + + // override this to make processing abort, return 1 to abort processing + int Instance::abort() { + return 0; + } + + // override this to use your own memory instance - must inherrit from memory::instance + Memory::Instance* Instance::newMemoryInstance(size_t /*nBytes*/) { + return 0; + } + + // return an memory::instance calls makeMemoryInstance that can be overriden + Memory::Instance* Instance::imageMemoryAlloc(size_t nBytes){ + Memory::Instance* instance = newMemoryInstance(nBytes); + if(instance) + return instance; + else{ + Memory::Instance* instance = new Memory::Instance; + instance->alloc(nBytes); + return instance; + } + } + + // call the effect entry point + OfxStatus Instance::mainEntry(const char *action, + const void *handle, + Property::Set *inArgs, + Property::Set *outArgs) + { + if(_plugin){ + PluginHandle* pHandle = _plugin->getPluginHandle(); + if(pHandle){ + OfxPlugin* ofxPlugin = pHandle->getOfxPlugin(); + if(ofxPlugin){ + + OfxPropertySetHandle inHandle = 0; + if(inArgs) { + setCustomInArgs(action, *inArgs); + inHandle = inArgs->getHandle(); + } + + OfxPropertySetHandle outHandle = 0; + if(outArgs) { + setCustomOutArgs(action, *outArgs); + outHandle = outArgs->getHandle(); + } + + OfxStatus stat; + try { + stat = ofxPlugin->mainEntry(action, handle, inHandle, outHandle); + } CatchAllSetStatus(stat, gImageEffectHost, ofxPlugin, action); + + if(outArgs) + examineOutArgs(action, stat, *outArgs); + + return stat; + } + return kOfxStatFailed; + } + return kOfxStatFailed; + } + return kOfxStatFailed; + } + + // get the nth clip, in order of declaration + ClipInstance* Instance::getNthClip(int index) + { + const std::string name = _descriptor->getClipsByOrder()[index]->getName(); + return _clips[name]; + } + + ClipInstance* Instance::getClip(const std::string& name) const { + std::map::const_iterator it = _clips.find(name); + if(it!=_clips.end()){ + return it->second; + } + return 0; + } + + // create a clip instance + OfxStatus Instance::createInstanceAction() + { + /// we need to init the clips before we call create instance incase + /// they try and fetch something in create instance, which they are allowed + setDefaultClipPreferences(); + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<::iterator it=_clips.find(clipName); + if(it!=_clips.end()) + return (it->second)->instanceChangedAction(why,time,renderScale); + else + return kOfxStatFailed; + } + + OfxStatus Instance::endInstanceChangedAction(const std::string & why) + { + Property::PropSpec whyStuff[] = { + { kOfxPropChangeReason, Property::eString, 1, true, why.c_str() }, + Property::propSpecEnd + }; + + Property::Set inArgs(whyStuff); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getValue() : true; + OfxStatus st = kOfxStatReplyDefault; + if (needsSyncing) { + st = mainEntry(kOfxActionSyncPrivateData,this->getHandle(),0,0); + if (s) { + s->setValue(0); + } + } +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(),0,0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<"<getHandle(), &inArgs, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<getRegionOfDefinition(time); + } else { + throw Property::Exception(kOfxStatFailed); + } + } + else if(_context == kOfxImageEffectContextTransition) { + // transition is the union of the two clips + ClipInstance *clipFrom = getClip(kOfxImageEffectTransitionSourceFromClipName); + ClipInstance *clipTo = getClip(kOfxImageEffectTransitionSourceToClipName); + if(clipFrom && clipTo) { + rod = clipFrom->getRegionOfDefinition(time); + rod = Union(rod, clipTo->getRegionOfDefinition(time)); + } else { + throw Property::Exception(kOfxStatFailed); + } + } + else if(_context == kOfxImageEffectContextGeneral + ) { + // general context is the union of all the non optional clips + bool gotOne = false; + for(std::map::const_iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + if(!clip->isOutput() && (!clip->isOptional() || (clip->getConnected() && clip->getName() == kOfxImageEffectSimpleSourceClipName))) { + if(!gotOne) + rod = clip->getRegionOfDefinition(time); + else + rod = Union(rod, clip->getRegionOfDefinition(time)); + gotOne = true; + } + } + + if(!gotOne) { + /// no non optionals? then be the extent + rod.x1 = rod.y1 = 0; + getProjectExtent(rod.x2, rod.y2); + } + + } + else if(_context == kOfxImageEffectContextRetimer) { + // retimer + ClipInstance *clip = getClip(kOfxImageEffectSimpleSourceClipName); + if(clip) { + Param::DoubleInstance *param = dynamic_cast(getParam(kOfxImageEffectRetimerParamName)); + if(param) { + rod = clip->getRegionOfDefinition(floor(time)); + rod = Union(rod, clip->getRegionOfDefinition(floor(time) + 1)); + } else { + throw Property::Exception(kOfxStatFailed); + } + } else { + throw Property::Exception(kOfxStatFailed); + } + } + else { + // unknown context + throw Property::Exception(kOfxStatErrMissingHostFeature); + } + + return rod; + } + + //////////////////////////////////////////////////////////////////////////////// + // RoD call + OfxStatus Instance::getRegionOfDefinitionAction(OfxTime time, + OfxPointD renderScale, + OfxRectD &rod) + { + static const Property::PropSpec inStuff[] = { + { kOfxPropTime, Property::eDouble, 1, true, "0" }, + { kOfxImageEffectPropRenderScale, Property::eDouble, 2, true, "0" }, + Property::propSpecEnd + }; + + static const Property::PropSpec outStuff[] = { + { kOfxImageEffectPropRegionOfDefinition , Property::eDouble, 4, false, "0" }, + Property::propSpecEnd + }; + + Property::Set inArgs(inStuff); + Property::Set outArgs(outStuff); + + inArgs.setDoubleProperty(kOfxPropTime,time); + inArgs.setDoublePropertyN(kOfxImageEffectPropRenderScale, &renderScale.x, 2); + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), + &inArgs, + &outArgs); + if(stat == kOfxStatOK) { + outArgs.getDoublePropertyN(kOfxImageEffectPropRegionOfDefinition, &rod.x1, 4); + } + else if(stat == kOfxStatReplyDefault) { + rod = calcDefaultRegionOfDefinition(time, renderScale); + } + + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<& rois) + { + OfxStatus stat = kOfxStatReplyDefault; + + // reset the map + rois.clear(); + + if(!supportsTiles()) { + /// No tiling support on the effect at all. So set the roi of each input clip to be the RoD of that clip. + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + if(!it->second->isOutput() || + getContext() == kOfxImageEffectContextGenerator) { + if (it->second->isOutput() || it->second->getConnected()) {// needed to be able to fetch the RoD + /// @todo tuttle: how to support size on generators... check if this is correct in all cases. + OfxRectD roi = it->second->getRegionOfDefinition(time); + rois[it->second] = roi; + } + } + } + stat = kOfxStatOK; + } + else { + /// set up the in args + static const Property::PropSpec inStuff[] = { + { kOfxPropTime, Property::eDouble, 1, true, "0" }, + { kOfxImageEffectPropRenderScale, Property::eDouble, 2, true, "0" }, + { kOfxImageEffectPropRegionOfInterest , Property::eDouble, 4, true, 0 }, + Property::propSpecEnd + }; + Property::Set inArgs(inStuff); + + inArgs.setDoublePropertyN(kOfxImageEffectPropRenderScale, &renderScale.x, 2); + inArgs.setDoubleProperty(kOfxPropTime,time); + inArgs.setDoublePropertyN(kOfxImageEffectPropRegionOfInterest, &roi.x1, 4); + + Property::Set outArgs; + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + if(!it->second->isOutput() || + getContext() == kOfxImageEffectContextGenerator) { + Property::PropSpec s; + std::string name = "OfxImageClipPropRoI_"+it->first; + + s.name = name.c_str(); + s.type = Property::eDouble; + s.dimension = 4; + s.readonly = false; + s.defaultValue = ""; + outArgs.createProperty(s); + + /// initialise to the default + outArgs.setDoublePropertyN(s.name, &roi.x1, 4); + } + } + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), + &inArgs, + &outArgs); + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + std::string name = "OfxImageClipPropRoI_"+it->first; + OfxRectD thisRoi; + thisRoi.x1 = outArgs.getDoubleProperty(name,0); + thisRoi.y1 = outArgs.getDoubleProperty(name,1); + thisRoi.x2 = outArgs.getDoubleProperty(name,2); + thisRoi.y2 = outArgs.getDoubleProperty(name,3); + std::cout << it->first << "->("<::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + if(!it->second->isOutput() || + getContext() == kOfxImageEffectContextGenerator) { + if (it->second->isOutput() || it->second->getConnected()) { // needed to be able to fetch the RoD + + if(it->second->supportsTiles()) { + std::string name = "OfxImageClipPropRoI_"+it->first; + OfxRectD thisRoi; + thisRoi.x1 = outArgs.getDoubleProperty(name,0); + thisRoi.y1 = outArgs.getDoubleProperty(name,1); + thisRoi.x2 = outArgs.getDoubleProperty(name,2); + thisRoi.y2 = outArgs.getDoubleProperty(name,3); + + // and DON'T clamp it to the clip's rod + // We cannot clip it against the RoD because the RoI may be used for frames + // at different a time or view than the current time and view passed to this action + // which would result in a wrong clipping. Unfortunately only the implementation of + // the host can do the correct clipping. + //thisRoi = Clamp(thisRoi, rod); + rois[it->second] = thisRoi; + } + else { + /// not supporting tiles on this input, so set it to the rod + OfxRectD rod = it->second->getRegionOfDefinition(time + ); + rois[it->second] = rod; + } + } + } + } + } + + return stat; + } + + + //////////////////////////////////////////////////////////////////////////////// + /// see how many frames are needed from each clip to render the indicated frame + OfxStatus Instance::getFrameNeededAction(OfxTime time, + RangeMap &rangeMap) + { + OfxStatus stat = kOfxStatReplyDefault; + Property::Set outArgs; + + if(temporalAccess()) { + static const Property::PropSpec inStuff[] = { + { kOfxPropTime, Property::eDouble, 1, true, "0" }, + Property::propSpecEnd + }; + Property::Set inArgs(inStuff); + inArgs.setDoubleProperty(kOfxPropTime,time); + + + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + if(!it->second->isOutput()) { + Property::PropSpec s; + std::string name = "OfxImageClipPropFrameRange_"+it->first; + + s.name = name.c_str(); + s.type = Property::eDouble; + s.dimension = 0; + s.readonly = false; + s.defaultValue = ""; + outArgs.createProperty(s); + /// intialise it to the current frame + outArgs.setDoubleProperty(name, time, 0); + outArgs.setDoubleProperty(name, time, 1); + } + } + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), + &inArgs, + &outArgs); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + if(!clip->isOutput()) { + std::string name = "OfxImageClipPropFrameRange_"+it->first; + std::cout << it->first << "->["; + + int nRanges = outArgs.getDimension(name); + for(int r=0;r::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + if(!clip->isOutput()) { + if(stat != kOfxStatOK) { + rangeMap[clip].push_back(defaultRange); + } + else { + std::string name = "OfxImageClipPropFrameRange_"+it->first; + + int nRanges = outArgs.getDimension(name); + if(nRanges%2 != 0) + return kOfxStatFailed; // bad! needs to be divisible by 2 + + if(nRanges == 0) { + rangeMap[clip].push_back(defaultRange); + } + else { + for(int r=0;r"<getHandle(), + &inArgs, + &outArgs); + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<getProperties().getIntProperty(kOfxImageEffectPropSupportsMultipleClipDepths) != 0;; + + /// does the plug-in support 'em + bool pluginSupports = supportsMultipleClipDepths(); + + /// no support, so no + if(!hostSupports || !pluginSupports) + return false; + + /// if filter context, no support, tempted to change this though + if(_context == kOfxImageEffectContextFilter) + return false; + + /// if filter context, no support + if(_context == kOfxImageEffectContextGenerator || + _context == kOfxImageEffectContextTransition || + _context == kOfxImageEffectContextPaint || + _context == kOfxImageEffectContextRetimer) + return false; + + /// OK we're cool + return true; + } + + /// Setup the default clip preferences on the clips + void Instance::setDefaultClipPreferences() + { + /// is there multiple bit depth support? Depends on host, plugin and context + bool multiBitDepth = canCurrentlyHandleMultipleClipDepths(); + + /// OK find the deepest chromatic component on our input clips and the one with the + /// most components + bool hasSetCompsAndDepth = false; + std::string deepestBitDepth = kOfxBitDepthNone; + std::string mostComponents = kOfxImageComponentNone; + double frameRate = getFrameRate(); //< default to the project frame rate + std::string premult = kOfxImageOpaque; + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + if(!clip->isOutput()) { + bool connected = clip->getConnected(); + + if (connected) { + frameRate = Maximum(frameRate, clip->getFrameRate()); + } + + std::string rawComp = clip->getUnmappedComponents(); + rawComp = clip->findSupportedComp(rawComp); // turn that into a comp the plugin expects on that clip + + const std::string &rawDepth = clip->getUnmappedBitDepth(); + const std::string &rawPreMult = clip->getPremult(); + + if(isChromaticComponent(rawComp)) { + if(connected) { + if(rawPreMult == kOfxImagePreMultiplied) + premult = kOfxImagePreMultiplied; + else if(rawPreMult == kOfxImageUnPreMultiplied && premult != kOfxImagePreMultiplied) + premult = kOfxImageUnPreMultiplied; + } + + if(connected) { + //Update deepest bitdepth and most components only if the infos are relevant, i.e: only if the clip is connected + hasSetCompsAndDepth = true; + deepestBitDepth = FindDeepestBitDepth(deepestBitDepth, rawDepth); + mostComponents = findMostChromaticComponents(mostComponents, rawComp); + } + } + } + } + // default to a reasonable value if there is no input + if (!hasSetCompsAndDepth) { + mostComponents = kOfxImageComponentRGBA; + deepestBitDepth = kOfxBitDepthFloat; + } + + /// set some stuff up + _outputFrameRate = frameRate; + _outputFielding = getDefaultOutputFielding(); + _outputPreMultiplication = premult; + _continuousSamples = false; + _frameVarying = false; + + /// now find the best depth that the plugin supports + deepestBitDepth = bestSupportedDepth(deepestBitDepth); + + /// now add the clip gubbins to the out args + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + std::string comp, depth; + + std::string rawComp = clip->getUnmappedComponents(); + rawComp = clip->findSupportedComp(rawComp); // turn that into a comp the plugin expects on that clip + const std::string &rawDepth = clip->getUnmappedBitDepth(); + + if(isChromaticComponent(rawComp)) { + + if(clip->isOutput() || clip->isOptional()) { + // "Optional input clips can always have their component types remapped" + // http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#id482755 + depth = deepestBitDepth; + comp = clip->findSupportedComp(mostComponents); + + clip->setPixelDepth(depth); + clip->setComponents(comp); + } + else { + comp = rawComp; + depth = multiBitDepth ? bestSupportedDepth(rawDepth) : deepestBitDepth; + + clip->setPixelDepth(depth); + clip->setComponents(comp); + } + } + else { + /// hmm custom component type, don't touch it and pass it through + clip->setPixelDepth(rawDepth); + clip->setComponents(rawComp); + } + } + } + + /// Initialise the clip preferences arguments, override this to do + /// stuff with wierd components etc... + void Instance::setupClipPreferencesArgs(Property::Set &outArgs) + { + /// reset all the clip prefs stuff to their defaults + setDefaultClipPreferences(); + + static const Property::PropSpec clipPrefsStuffs []= + { + { kOfxImageEffectPropFrameRate, Property::eDouble, 1, false, "1" }, + { kOfxImageEffectPropPreMultiplication, Property::eString, 1, false, "" }, + { kOfxImageClipPropFieldOrder, Property::eString, 1, false, "" }, + { kOfxImageClipPropContinuousSamples, Property::eInt, 1, false, "0" }, + { kOfxImageEffectFrameVarying, Property::eInt, 1, false, "0" }, + Property::propSpecEnd + }; + + outArgs.addProperties(clipPrefsStuffs); + + /// set the default for those + + /// is there multiple bit depth support? Depends on host, plugin and context + bool multiBitDepth = canCurrentlyHandleMultipleClipDepths(); + + outArgs.setStringProperty(kOfxImageClipPropFieldOrder, _outputFielding); + outArgs.setStringProperty(kOfxImageEffectPropPreMultiplication, _outputPreMultiplication); + + /// now add the clip gubbins to the out args + double projectPAR = getProjectPixelAspectRatio(); + bool multipleClipsPAR = supportsMultipleClipPARs(); + /// get the PAR of inputs, if it has different PARs and the effect does not support multiple clips PAR, throw an exception + double inputPar; + bool inputParSet = false; + for (std::map::iterator it2 = _clips.begin(); it2 != _clips.end(); ++it2) { + if (!it2->second->isOutput() && it2->second->getConnected()) { + if (!inputParSet) { + inputPar = it2->second->getAspectRatio(); + inputParSet = true; + } else if (!multipleClipsPAR && inputPar != it2->second->getAspectRatio()) { + // We have several inputs with different aspect ratio, which should be forbidden by the host. + throw Property::Exception(kOfxStatErrValue); + } + } + } + + + for(std::map::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + std::string componentParamName = "OfxImageClipPropComponents_"+it->first; + std::string depthParamName = "OfxImageClipPropDepth_"+it->first; + std::string parParamName = "OfxImageClipPropPAR_"+it->first; + + Property::PropSpec specComp = {componentParamName.c_str(), Property::eString, 0, false, ""}; // note the support for multi-planar clips + outArgs.createProperty(specComp); + outArgs.setStringProperty(componentParamName.c_str(), clip->getComponents().c_str()); // as it is variable dimension, there is no default value, so we have to set it explicitly + + Property::PropSpec specDep = {depthParamName.c_str(), Property::eString, 1, !multiBitDepth, clip->getPixelDepth().c_str()}; + outArgs.createProperty(specDep); + + Property::PropSpec specPAR = {parParamName.c_str(), Property::eDouble, 1, false, "1"}; + outArgs.createProperty(specPAR); + if (!clip->isOutput()) { + // If the clip is input, use the same par for all inputs unless the plug-in supports multiple clips PAR + double par; + if (!multipleClipsPAR && inputParSet) { + par = inputPar; + } else if (multipleClipsPAR) { + par = clip->getAspectRatio(); + } else { + par = projectPAR; + } + outArgs.setDoubleProperty(parParamName, par); + } else { + // If the clip is output we should propagate the pixel aspect ratio of the inputs + outArgs.setDoubleProperty(parParamName, inputParSet ? inputPar : projectPAR); + } + } + + //Set the output frame rate according to what input clips have. Several inputs with different frame rates should be + //forbidden by the host. + bool outputFrameRateSet = false; + double outputFrameRate = _outputFrameRate; + for (std::map::iterator it2 = _clips.begin(); it2 != _clips.end(); ++it2) { + if (!it2->second->isOutput() && it2->second->getConnected()) { + if (!outputFrameRateSet) { + outputFrameRate = it2->second->getFrameRate(); + outputFrameRateSet = true; + } else if (outputFrameRate != it2->second->getFrameRate()) { + // We have several inputs with different frame rates + throw Property::Exception(kOfxStatErrValue); + } + } + } + + outArgs.setDoubleProperty(kOfxImageEffectPropFrameRate, outputFrameRate); + + } + + /// the idea here is the clip prefs live as active props on the effect + /// and are set up by clip preferences. The action manages the clip + /// preferences bits. We also monitor clip and param changes and + /// flag when clip prefs is dirty. + /// call the clip preferences action + bool Instance::getClipPreferences() + { + /// create the out args with the stuff that does not depend on individual clips + Property::Set outArgs; + + setupClipPreferencesArgs(outArgs); + + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), + 0, + &outArgs); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<::iterator it=_clips.begin(); + it!=_clips.end(); + ++it) { + ClipInstance *clip = it->second; + + std::string componentParamName = "OfxImageClipPropComponents_"+it->first; + std::string depthParamName = "OfxImageClipPropDepth_"+it->first; + std::string parParamName = "OfxImageClipPropPAR_"+it->first; + +# ifdef OFX_DEBUG_ACTIONS + std::cout << it->first<<"->"<setPixelDepth(outArgs.getStringProperty(depthParamName)); + clip->setComponents(outArgs.getStringProperty(componentParamName)); + //clip->setPixelAspect(outArgs.getDoubleProperty(parParamName)); + } + + _outputFrameRate = outArgs.getDoubleProperty(kOfxImageEffectPropFrameRate); + _outputFielding = outArgs.getStringProperty(kOfxImageClipPropFieldOrder); + _outputPreMultiplication = outArgs.getStringProperty(kOfxImageEffectPropPreMultiplication); + _continuousSamples = outArgs.getIntProperty(kOfxImageClipPropContinuousSamples) != 0; + _frameVarying = outArgs.getIntProperty(kOfxImageEffectFrameVarying) != 0; +# ifdef OFX_DEBUG_ACTIONS + std::cout << _outputFrameRate<<","<<_outputFielding<<","<<_outputPreMultiplication<<","<<_continuousSamples<<","<<_frameVarying<getOverlayDescriptor(bitDepthPerComponent, hasAlpha); + } + + OfxStatus Instance::getTimeDomainAction(OfxRangeD& range) + { + static const Property::PropSpec outStuff[] = { + { kOfxImageEffectPropFrameRange , Property::eDouble, 2, false, "0.0" }, + Property::propSpecEnd + }; + + Property::Set outArgs(outStuff); + +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<getHandle(), + 0, + &outArgs); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)this<<"->"<"<getName(), kOfxChangePluginEdited, frame, renderScale); + endInstanceChangedAction(kOfxChangePluginEdited); + } + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// The image effect suite functions + static OfxStatus getPropertySet(OfxImageEffectHandle h1, + OfxPropertySetHandle *h2) + { + try { + if (!h2) { + return kOfxStatErrBadHandle; + } + + Base *effectBase = reinterpret_cast(h1); + + if (!effectBase || !effectBase->verifyMagic()) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + + *h2 = effectBase->getProps().getHandle(); + + return kOfxStatOK; + } catch (...) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus getParamSet(OfxImageEffectHandle h1, + OfxParamSetHandle *h2) + { + try { + if (!h2) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Base *effectBase = reinterpret_cast(h1); + + if (!effectBase || !effectBase->verifyMagic()) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + + ImageEffect::Descriptor *effectDescriptor = dynamic_cast(effectBase); + + if(effectDescriptor) { + *h2 = effectDescriptor->getParamSetHandle(); + + return kOfxStatOK; + } + + ImageEffect::Instance *effectInstance = dynamic_cast(effectBase); + + if(effectInstance) { + *h2 = effectInstance->getParamSetHandle(); + + return kOfxStatOK; + } + + *h2 = NULL; + + return kOfxStatErrBadHandle; + } catch (...) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipDefine(OfxImageEffectHandle h1, + const char *name, + OfxPropertySetHandle *h2) + { + try { + if (!h2) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Base *effectBase = reinterpret_cast(h1); + + if (!effectBase || !effectBase->verifyMagic()) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + + ImageEffect::Descriptor *effectDescriptor = dynamic_cast(effectBase); + + if(effectDescriptor){ + ClipDescriptor *clip = effectDescriptor->defineClip(name); + *h2 = clip->getPropHandle(); + + return kOfxStatOK; + } + + *h2 = NULL; + + return kOfxStatErrBadHandle; + } catch (...) { + *h2 = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipGetPropertySet(OfxImageClipHandle clip, + OfxPropertySetHandle *propHandle){ + try { + if (!propHandle) { + return kOfxStatErrBadHandle; + } + + ClipInstance *clipInstance = reinterpret_cast(clip); + + if (!clipInstance || !clipInstance->verifyMagic()) { + *propHandle = NULL; + + return kOfxStatErrBadHandle; + } + + *propHandle = clipInstance->getPropHandle(); + return kOfxStatOK; + } catch (...) { + *propHandle = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipGetImage(OfxImageClipHandle h1, + OfxTime time, + const OfxRectD *h2, + OfxPropertySetHandle *h3) + { + try { + if (!h3) { + return kOfxStatErrBadHandle; + } + + ClipInstance *clipInstance = reinterpret_cast(h1); + + if (!clipInstance || !clipInstance->verifyMagic()) { + *h3 = NULL; + return kOfxStatErrBadHandle; + } + + Image* image = clipInstance->getImage(time,h2); + if(!image) { + *h3 = NULL; + + return kOfxStatFailed; + } + + *h3 = image->getPropHandle(); + + return kOfxStatOK; + } catch (...) { + *h3 = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipReleaseImage(OfxPropertySetHandle h1) + { + try { + Property::Set *pset = reinterpret_cast(h1); + + if (!pset || !pset->verifyMagic()) { + return kOfxStatErrBadHandle; + } + + Image *image = dynamic_cast(pset); + + if(image){ + // clip::image has a virtual destructor for derived classes + image->releaseReference(); + + return kOfxStatOK; + } + + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipGetHandle(OfxImageEffectHandle imageEffect, + const char *name, + OfxImageClipHandle *clip, + OfxPropertySetHandle *propertySet) + { + try { + if (!clip) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Base *effectBase = reinterpret_cast(imageEffect); + + if (!effectBase || !effectBase->verifyMagic()) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Instance *effectInstance = reinterpret_cast(effectBase); + + if(effectInstance){ + ClipInstance* instance = effectInstance->getClip(name); + if(!instance) + return kOfxStatErrBadHandle; + *clip = instance->getHandle(); + if(propertySet) + *propertySet = instance->getPropHandle(); + return kOfxStatOK; + } + + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipGetRegionOfDefinition(OfxImageClipHandle clip, + OfxTime time, + OfxRectD *bounds) + { + try { + if (!bounds) { + return kOfxStatErrBadHandle; + } + + ClipInstance *clipInstance = reinterpret_cast(clip); + + if (!clipInstance || !clipInstance->verifyMagic()) { + bounds->x1 = bounds->y1 = bounds->x2 = bounds->y2 = 0.; + + return kOfxStatErrBadHandle; + } + + *bounds = clipInstance->getRegionOfDefinition(time); + if (bounds->x2 < bounds->x1 || bounds->y2 < bounds->y1) { + // the RoD is invalid (empty is OK) + + return kOfxStatFailed; + } + + return kOfxStatOK; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + // should processing be aborted? + static int abort(OfxImageEffectHandle imageEffect) + { + try { + ImageEffect::Base *effectBase = reinterpret_cast(imageEffect); + + if (!effectBase || !effectBase->verifyMagic()) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Instance *effectInstance = dynamic_cast(effectBase); + + if(effectInstance) + return effectInstance->abort(); + else + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static OfxStatus imageMemoryAlloc(OfxImageEffectHandle instanceHandle, + size_t nBytes, + OfxImageMemoryHandle *memoryHandle) + { + try { + if (!memoryHandle) { + return kOfxStatErrBadHandle; + } + + ImageEffect::Base *effectBase = reinterpret_cast(instanceHandle); + ImageEffect::Instance *effectInstance = reinterpret_cast(effectBase); + Memory::Instance* memory; + + if(effectInstance){ + + if (!effectInstance->verifyMagic()) { + *memoryHandle = NULL; + return kOfxStatErrBadHandle; + } + + memory = effectInstance->imageMemoryAlloc(nBytes); + } + else { + memory = gImageEffectHost->imageMemoryAlloc(nBytes); + } + + if (memory) { + *memoryHandle = memory->getHandle(); + return kOfxStatOK; + } else { + *memoryHandle = NULL; + return kOfxStatErrMemory; + } + } catch (std::bad_alloc&) { + *memoryHandle = NULL; + return kOfxStatErrMemory; + } catch (...) { + *memoryHandle = NULL; + return kOfxStatErrBadHandle; + } + } + + static OfxStatus imageMemoryFree(OfxImageMemoryHandle memoryHandle){ + try { + Memory::Instance *memoryInstance = reinterpret_cast(memoryHandle); + + if(memoryInstance && memoryInstance->verifyMagic()) { + memoryInstance->freeMem(); + delete memoryInstance; + return kOfxStatOK; + } + else + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static + OfxStatus imageMemoryLock(OfxImageMemoryHandle memoryHandle, + void **returnedPtr){ + try { + if (!returnedPtr) { + return kOfxStatErrBadHandle; + } + + Memory::Instance *memoryInstance = reinterpret_cast(memoryHandle); + + if(memoryInstance && memoryInstance->verifyMagic()) { + memoryInstance->lock(); + *returnedPtr = memoryInstance->getPtr(); + + return (*returnedPtr) ? kOfxStatOK : kOfxStatErrMemory; + } + + *returnedPtr = NULL; + + return kOfxStatErrBadHandle; + } catch (...) { + *returnedPtr = NULL; + return kOfxStatErrBadHandle; + } + } + + static OfxStatus imageMemoryUnlock(OfxImageMemoryHandle memoryHandle){ + try { + Memory::Instance *memoryInstance = reinterpret_cast(memoryHandle); + + if(memoryInstance && memoryInstance->verifyMagic()){ + memoryInstance->unlock(); + + return kOfxStatOK; + } + + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static const struct OfxImageEffectSuiteV1 gImageEffectSuite = { + getPropertySet, + getParamSet, + clipDefine, + clipGetHandle, + clipGetPropertySet, + clipGetImage, + clipReleaseImage, + clipGetRegionOfDefinition, + abort, + imageMemoryAlloc, + imageMemoryFree, + imageMemoryLock, + imageMemoryUnlock + }; + +# ifdef OFX_SUPPORTS_OPENGLRENDER + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// The OpenGL render suite functions + + static OfxStatus clipLoadTexture(OfxImageClipHandle h1, + OfxTime time, + const char *format, + const OfxRectD *h2, + OfxPropertySetHandle *h3) + { + try { + if (!h3) { + return kOfxStatErrBadHandle; + } + + ClipInstance *clipInstance = reinterpret_cast(h1); + + if (!clipInstance || !clipInstance->verifyMagic()) { + return kOfxStatErrBadHandle; + } + + if(clipInstance){ + Texture* texture = clipInstance->loadTexture(time,format,h2); + if(!texture) { + *h3 = NULL; + + return kOfxStatFailed; + } + + *h3 = texture->getPropHandle(); + + return kOfxStatOK; + } + + return kOfxStatErrBadHandle; + } catch (...) { + *h3 = NULL; + + return kOfxStatErrBadHandle; + } + } + + static OfxStatus clipFreeTexture(OfxPropertySetHandle h1) + { + try { + Property::Set *pset = reinterpret_cast(h1); + + if (!pset || !pset->verifyMagic()) { + return kOfxStatErrBadHandle; + } + + Texture *texture = dynamic_cast(pset); + + if(texture){ + // clip::texture has a virtual destructor for derived classes + texture->releaseReference(); + return kOfxStatOK; + } + else + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatErrBadHandle; + } + } + + static OfxStatus flushResources( ) + { + return gImageEffectHost->flushOpenGLResources(); + } + + static const struct OfxImageEffectOpenGLRenderSuiteV1 gOpenGLRenderSuite = { + clipLoadTexture, + clipFreeTexture, + flushResources + }; +# endif + + /// message suite function for an image effect + static OfxStatus message(void *handle, const char *type, const char *id, const char *format, ...) + { + try { + ImageEffect::Instance *effectInstance = reinterpret_cast(handle); + OfxStatus stat; + if(effectInstance){ + va_list args; + va_start(args,format); + stat = effectInstance->vmessage(type,id,format,args); + va_end(args); + } + else{ + va_list args; + va_start(args,format); + vprintf(format,args); + va_end(args); + stat = kOfxStatErrBadHandle; + } + return stat; + } catch (...) { + return kOfxStatFailed; + } + } + + static OfxStatus setPersistentMessage(void *handle, const char *type, const char *id, const char *format, ...) + { + try { + ImageEffect::Instance *effectInstance = reinterpret_cast(handle); + OfxStatus stat; + if(effectInstance){ + va_list args; + va_start(args,format); + stat = effectInstance->setPersistentMessage(type,id,format,args); + va_end(args); + } + else{ + va_list args; + va_start(args,format); + vprintf(format,args); + va_end(args); + stat = kOfxStatErrBadHandle; + } + return stat; + } catch (...) { + return kOfxStatFailed; + } + } + + static OfxStatus clearPersistentMessage(void *handle) + { + try { + ImageEffect::Instance *effectInstance = reinterpret_cast(handle); + OfxStatus stat; + if(effectInstance){ + stat = effectInstance->clearPersistentMessage(); + } + else{ + stat = kOfxStatErrBadHandle; + } + return stat; + } catch (...) { + return kOfxStatFailed; + } + } + + /// message suite for an image effect plugin (backward-compatible with OfxMessageSuiteV1) + static const struct OfxMessageSuiteV2 gMessageSuite = { + message, + setPersistentMessage, + clearPersistentMessage + }; + + + //////////////////////////////////////////////////////////////////////////////// + /// make an overlay interact for an image effect + OverlayInteract::OverlayInteract(ImageEffect::Instance &effect, int bitDepthPerComponent, bool hasAlpha) + : Interact::Instance(effect.getOverlayDescriptor(bitDepthPerComponent, hasAlpha), + (void *)(effect.getHandle())) + , _instance(effect) + { + } + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + // Progress suite functions + + /// begin progressing + static OfxStatus ProgressStartV1(void *effectInstance, + const char *label) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + me->progressStart(label, ""); + return kOfxStatOK; + } + + + /// begin progressing + static OfxStatus ProgressStart(void *effectInstance, + const char *message, + const char *messageid) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + me->progressStart(message, messageid); + return kOfxStatOK; + } + + /// finish progressing + static OfxStatus ProgressEnd(void *effectInstance) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + me->progressEnd(); + return kOfxStatOK; + } + + /// update progressing + static OfxStatus ProgressUpdate(void *effectInstance, double progress) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + bool v = me->progressUpdate(progress); + return v ? kOfxStatOK : kOfxStatReplyNo; + } + + /// our progress suite + struct OfxProgressSuiteV1 gProgressSuiteV1 = { + ProgressStartV1, + ProgressUpdate, + ProgressEnd + }; + + struct OfxProgressSuiteV2 gProgressSuiteV2 = { + ProgressStart, + ProgressUpdate, + ProgressEnd + }; + + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + // timeline suite functions + + /// timeline suite function + static OfxStatus TimeLineGetTime(void *effectInstance, double *time) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + *time = me->timeLineGetTime(); + return kOfxStatOK; + } + + /// timeline suite function + static OfxStatus TimeLineGotoTime(void *effectInstance, double time) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + me->timeLineGotoTime(time); + return kOfxStatOK; + } + + /// timeline suite function + static OfxStatus TimeLineGetBounds(void *effectInstance, double *firstTime, double *lastTime) + { + if (!effectInstance) + return kOfxStatErrBadHandle; + Instance *me = reinterpret_cast(effectInstance); + me->timeLineGetBounds(*firstTime, *lastTime); + return kOfxStatOK; + } + + /// our progress suite + struct OfxTimeLineSuiteV1 gTimelineSuite = { + TimeLineGetTime, + TimeLineGotoTime, + TimeLineGetBounds + }; + + //////////////////////////////////////////////////////////////////////////////// +#ifdef OFX_SUPPORTS_MULTITHREAD + // Forward all multithread suite calls to the host implementation. + + static OfxStatus multiThread(OfxThreadFunctionV1 func, + unsigned int nThreads, + void *customArg) + { + return gImageEffectHost->multiThread(func, nThreads, customArg); + } + + static OfxStatus multiThreadNumCPUs(unsigned int *nCPUs) + { + return gImageEffectHost->multiThreadNumCPUS(nCPUs); + } + + static OfxStatus multiThreadIndex(unsigned int *threadIndex){ + return gImageEffectHost->multiThreadIndex(threadIndex); + } + + static int multiThreadIsSpawnedThread(void){ + return gImageEffectHost->multiThreadIsSpawnedThread(); + } + + static OfxStatus mutexCreate(OfxMutexHandle *mutex, int lockCount) + { + return gImageEffectHost->mutexCreate(mutex, lockCount); + } + + static OfxStatus mutexDestroy(const OfxMutexHandle mutex) + { + return gImageEffectHost->mutexDestroy(mutex); + } + + static OfxStatus mutexLock(const OfxMutexHandle mutex){ + return gImageEffectHost->mutexLock(mutex); + } + + static OfxStatus mutexUnLock(const OfxMutexHandle mutex){ + return gImageEffectHost->mutexUnLock(mutex); + } + + static OfxStatus mutexTryLock(const OfxMutexHandle mutex){ + return gImageEffectHost->mutexTryLock(mutex); + } +#else // !OFX_SUPPORTS_MULTITHREAD + /// a simple multithread suite + static OfxStatus multiThread(OfxThreadFunctionV1 func, + unsigned int /*nThreads*/, + void *customArg) + { + if (!func) + return kOfxStatFailed; + func(0,1,customArg); + return kOfxStatOK; + } + + static OfxStatus multiThreadNumCPUs(unsigned int *nCPUs) + { + if (!nCPUs) + return kOfxStatFailed; + *nCPUs = 1; + return kOfxStatOK; + } + + static OfxStatus multiThreadIndex(unsigned int *threadIndex){ + if (!threadIndex) + return kOfxStatFailed; + *threadIndex = 0; + return kOfxStatOK; + } + + static int multiThreadIsSpawnedThread(void){ + return false; + } + + static OfxStatus mutexCreate(OfxMutexHandle *mutex, int /*lockCount*/) + { + if (!mutex) + return kOfxStatFailed; + // do nothing single threaded + *mutex = 0; + return kOfxStatOK; + } + + static OfxStatus mutexDestroy(const OfxMutexHandle mutex) + { + if (mutex != 0) + return kOfxStatErrBadHandle; + // do nothing single threaded + return kOfxStatOK; + } + + static OfxStatus mutexLock(const OfxMutexHandle mutex){ + if (mutex != 0) + return kOfxStatErrBadHandle; + // do nothing single threaded + return kOfxStatOK; + } + + static OfxStatus mutexUnLock(const OfxMutexHandle mutex){ + if (mutex != 0) + return kOfxStatErrBadHandle; + // do nothing single threaded + return kOfxStatOK; + } + + static OfxStatus mutexTryLock(const OfxMutexHandle mutex){ + if (mutex != 0) + return kOfxStatErrBadHandle; + // do nothing single threaded + return kOfxStatOK; + } +#endif // !OFX_SUPPORTS_MULTITHREAD + + static const struct OfxMultiThreadSuiteV1 gMultiThreadSuite = { + multiThread, + multiThreadNumCPUs, + multiThreadIndex, + multiThreadIsSpawnedThread, + mutexCreate, + mutexDestroy, + mutexLock, + mutexUnLock, + mutexTryLock + }; + + + //////////////////////////////////////////////////////////////////////////////// + /// The image effect host + + /// properties for the image effect host + static const Property::PropSpec hostStuffs[] = { + { kOfxImageEffectHostPropIsBackground, Property::eInt, 1, true, "0" }, + { kOfxImageEffectPropSupportsOverlays, Property::eInt, 1, true, "1" }, + { kOfxImageEffectPropSupportsMultiResolution, Property::eInt, 1, true, "1" }, + { kOfxImageEffectPropSupportsTiles, Property::eInt, 1, true, "1" }, + { kOfxImageEffectPropTemporalClipAccess, Property::eInt, 1, true, "1" }, + + + + /// xxx this needs defaulting manually + { kOfxImageEffectPropSupportedComponents, Property::eString, 0, true, "" }, + /// xxx this needs defaulting manually + + { kOfxImageEffectPropSupportedPixelDepths, Property::eString, 0, true, "" }, + + /// xxx this needs defaulting manually + + { kOfxImageEffectPropSupportedContexts, Property::eString, 0, true, "" }, + /// xxx this needs defaulting manually + + { kOfxImageEffectPropSupportsMultipleClipDepths, Property::eInt, 1, true, "1" }, + { kOfxImageEffectPropSupportsMultipleClipPARs, Property::eInt, 1, true, "0" }, + { kOfxImageEffectPropSetableFrameRate, Property::eInt, 1, true, "0" }, + { kOfxImageEffectPropSetableFielding, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropSupportsCustomInteract, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropSupportsStringAnimation, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropSupportsChoiceAnimation, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropSupportsBooleanAnimation, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropSupportsCustomAnimation, Property::eInt, 1, true, "0" }, + { kOfxPropHostOSHandle, Property::ePointer, 1, true, NULL }, +#ifdef OFX_SUPPORTS_PARAMETRIC + { kOfxParamHostPropSupportsParametricAnimation, Property::eInt, 1, true, "0"}, +#endif + { kOfxParamHostPropMaxParameters, Property::eInt, 1, true, "-1" }, + { kOfxParamHostPropMaxPages, Property::eInt, 1, true, "0" }, + { kOfxParamHostPropPageRowColumnCount, Property::eInt, 2, true, "0" }, + { kOfxImageEffectInstancePropSequentialRender, Property::eInt, 1, true, "0" }, // OFX 1.2 +#ifdef OFX_SUPPORTS_OPENGLRENDER + { kOfxImageEffectPropOpenGLRenderSupported, Property::eString, 1, true, "false"}, // OFX 1.3 + { kOfxImageEffectPropCudaRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropCudaStreamSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropMetalRenderSupported, Property::eString, 1, false, "false" }, + { kOfxImageEffectPropOpenCLRenderSupported, Property::eString, 1, false, "false" }, +#endif + { kOfxImageEffectPropRenderQualityDraft, Property::eInt, 1, true, "0" }, // OFX 1.4 + { kOfxImageEffectHostPropNativeOrigin, Property::eString, 0, true, kOfxHostNativeOriginBottomLeft }, // OFX 1.4 + Property::propSpecEnd + }; + + /// ctor + Host::Host() + { + /// add the properties for an image effect host, derived classs to set most of them + _properties.addProperties(hostStuffs); + } + + /// optionally over-ridden function to register the creation of a new descriptor in the host app + void Host::initDescriptor(Descriptor* /*desc*/) + { + } + + /// Use this in any dialogue etc... showing progress + void Host::loadingStatus(const std::string &) + { + } + + bool Host::pluginSupported(ImageEffectPlugin */*plugin*/, std::string &/*reason*/) const + { + return true; + } + + // override this to use your own memory instance - must inherrit from memory::instance + Memory::Instance* Host::newMemoryInstance(size_t /*nBytes*/) { + return 0; + } + + // return an memory::instance calls makeMemoryInstance that can be overriden + Memory::Instance* Host::imageMemoryAlloc(size_t nBytes){ + Memory::Instance* instance = newMemoryInstance(nBytes); + if(instance) + return instance; + else{ + Memory::Instance* instance = new Memory::Instance; + instance->alloc(nBytes); + return instance; + } + } + + /// our suite fetcher + const void *Host::fetchSuite(const char *suiteName, int suiteVersion) + { + if (strcmp(suiteName, kOfxImageEffectSuite)==0) { + if(suiteVersion==1) + return (void *)&gImageEffectSuite; + else + return NULL; + } + else if (strcmp(suiteName, kOfxParameterSuite)==0) { + return Param::GetSuite(suiteVersion); + } + else if (strcmp(suiteName, kOfxMessageSuite)==0) { + // version 2 is backward-compatible + if(suiteVersion==1 || suiteVersion==2) + return (void *)&gMessageSuite; + else + return NULL; + } + else if (strcmp(suiteName, kOfxInteractSuite)==0) { + return Interact::GetSuite(suiteVersion); + } + else if (strcmp(suiteName, kOfxProgressSuite)==0) { + if(suiteVersion==1) + return (void*)&gProgressSuiteV1; + else if(suiteVersion==2) + return (void*)&gProgressSuiteV2; + else + return 0; + } + else if (strcmp(suiteName, kOfxTimeLineSuite)==0) { + if(suiteVersion==1) + return (void*)&gTimelineSuite; + else + return 0; + } + else if (strcmp(suiteName, kOfxMultiThreadSuite)==0) { + if(suiteVersion == 1) + return (void*)&gMultiThreadSuite; + else + return NULL; + } +# ifdef OFX_SUPPORTS_OPENGLRENDER + else if (strcmp(suiteName, kOfxOpenGLRenderSuite)==0) { + if(suiteVersion == 1) + return (void*)&gOpenGLRenderSuite; + else + return NULL; + } +# endif +# ifdef OFX_SUPPORTS_PARAMETRIC + else if (strcmp(suiteName, kOfxParametricParameterSuite)==0) { + return ParametricParam::GetSuite(suiteVersion); + } +# endif + else /// otherwise just grab the base class one, which is props and memory + return OFX::Host::Host::fetchSuite(suiteName, suiteVersion); + } + + } // ImageEffect + + } // Host + +} // OFX diff --git a/third_party/openfx/HostSupport/src/ofxhImageEffectAPI.cpp b/third_party/openfx/HostSupport/src/ofxhImageEffectAPI.cpp new file mode 100755 index 000000000..ffb68dbe3 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhImageEffectAPI.cpp @@ -0,0 +1,592 @@ + + +#include + +#include +#include +#include + +// 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<<"->"<mainEntry(kOfxActionUnload, 0, 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)op<<"->"<"< 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 &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;jgetOfxPlugin(); + + if (!op) { + _pluginHandle.reset(); + return nullptr; + } + + OfxStatus stat; + try { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)op<<"->"<mainEntry(kOfxActionLoad, 0, 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)op<<"->"<"<"<mainEntry(kOfxActionDescribe, getDescriptor().getHandle(), 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)op<<"->"<"<>::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 newContext( gImageEffectHost->makeDescriptor(getDescriptor(), this)); + + OfxStatus stat; + try { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)ph->getOfxPlugin()<<"->"<getOfxPlugin()->mainEntry(kOfxImageEffectActionDescribeInContext, newContext->getHandle(), inarg.getHandle(), 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)ph->getOfxPlugin()<<"->"<"<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()<<"->"<mainEntry(kOfxActionUnload, 0, 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)_pluginHandle->getOfxPlugin()<<"->"<"<::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(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::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& PluginCache::getPlugins() const + { + return _plugins; + } + + const std::map& 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(op); + assert(p); + + PluginHandle plug(p, _host); + + OfxStatus stat; + try { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<mainEntry(kOfxActionLoad, 0, 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<"<getIdentifier() << std::endl; + return; + } + + try { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<mainEntry(kOfxActionDescribe, p->getDescriptor().getHandle(), 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<"<getIdentifier() << std::endl; + return; + } + + ImageEffect::Descriptor &e = p->getDescriptor(); + Property::Set &eProps = e.getProps(); + + int size = eProps.getDimension(kOfxImageEffectPropSupportedContexts); + + for (int j=0;jaddContext(context); + } + + try { +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<mainEntry(kOfxActionUnload, 0, 0, 0); +# ifdef OFX_DEBUG_ACTIONS + std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<"<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(p); + } + + /// XML handler : element begins (everything is stored in elements and attributes) + void PluginCache::xmlElementBegin(const std::string &el, std::map map) + { + if (el == "apiproperties") { + return; + } + + if (el == "context") { + std::unique_ptr 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(ip); + if (p) { + p->saveXML(os); + } + } + + void PluginCache::confirmPlugin(Plugin *p) { + ImageEffectPlugin *plugin = dynamic_cast(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::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& contexts = it->second->getContexts(); + for (std::set::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& inputs = d.getClips(); + for (std::map::const_iterator it2 = inputs.begin(); it2 != inputs.end(); ++it2) + std::cout << "\t\t* " << it2->first << std::endl; + } + } + + } // ImageEffect + + } // Host + +} // OFX + diff --git a/third_party/openfx/HostSupport/src/ofxhInteract.cpp b/third_party/openfx/HostSupport/src/ofxhInteract.cpp new file mode 100755 index 000000000..22ebc29d1 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhInteract.cpp @@ -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& params) const + { + int nSlaveParams = _properties.getDimension(kOfxInteractPropSlaveToParam); + + for (int i=0; i(handle); + if(interactInstance) + return interactInstance->swapBuffers(); + else + return kOfxStatErrBadHandle; + } catch (...) { + return kOfxStatFailed; + } + } + + static OfxStatus interactRedraw(OfxInteractHandle handle) + { + try { + Interact::Instance *interactInstance = reinterpret_cast(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(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 diff --git a/third_party/openfx/HostSupport/src/ofxhMemory.cpp b/third_party/openfx/HostSupport/src/ofxhMemory.cpp new file mode 100755 index 000000000..8f69f07b3 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhMemory.cpp @@ -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 + diff --git a/third_party/openfx/HostSupport/src/ofxhParam.cpp b/third_party/openfx/HostSupport/src/ofxhParam.cpp new file mode 100644 index 000000000..4036b8501 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhParam.cpp @@ -0,0 +1,2300 @@ + + +// ofx +#include "ofxCore.h" +#include "ofxImageEffect.h" +#ifdef OFX_SUPPORTS_PARAMETRIC +#include "ofxParametricParam.h" +#endif + +// ofx host +#include "ofxhBinary.h" +#include "ofxhPropertySuite.h" +#include "ofxhParam.h" +#include "ofxhImageEffect.h" +#include "ofxOld.h" // old plugins may rely on deprecated properties being present + + +#include +#include +#include +#include + +namespace OFX { + + namespace Host { + + namespace Param { + + // + // Base + // + Base::Base(const std::string &name, const std::string& type) : + _paramName(name), + _paramType(type) + { + assert(_paramType.c_str()); + } + + Base::Base(const std::string &name, const std::string &type, const Property::Set &properties) : + _paramName(name), + _paramType(type), + _properties(properties) + { + assert(_paramType.c_str()); + } + + + Base::~Base() {} + + /// grab a handle on the parameter for passing to the C API + OfxParamHandle Base::getHandle() const { + return (OfxParamHandle)this; + } + + /// grab a handle on the properties of this parameter for the C api + OfxPropertySetHandle Base::getPropHandle() const { + return _properties.getHandle(); + } + + Property::Set &Base::getProperties() { + return _properties; + } + + const Property::Set &Base::getProperties() const { + return _properties; + } + + const std::string &Base::getType() const { + return _paramType; + } + + const std::string &Base::getName() const { + return _paramName; + } + + const std::string &Base::getParentName() const { + return _properties.getStringProperty(kOfxParamPropParent); + } + + const std::string &Base::getScriptName() const { + return _properties.getStringProperty(kOfxParamPropScriptName); + } + + const std::string &Base::getLabel() const { + return _properties.getStringProperty(kOfxPropLabel); + } + + const std::string &Base::getLongLabel() const { + return _properties.getStringProperty(kOfxPropLongLabel); + } + + const std::string &Base::getShortLabel() const { + return _properties.getStringProperty(kOfxPropShortLabel); + } + + const std::string &Base::getDoubleType() const { + return _properties.getStringProperty(kOfxParamPropDoubleType, 0); + } + + const std::string &Base::getDefaultCoordinateSystem() const { + return _properties.getStringProperty(kOfxParamPropDefaultCoordinateSystem, 0); + } + + const std::string &Base::getHint() const { + return _properties.getStringProperty(kOfxParamPropHint, 0); + } + + bool Base::getEnabled() const { + return _properties.getIntProperty(kOfxParamPropEnabled, 0) != 0; + } + + bool Base::getSecret() const { + return _properties.getIntProperty(kOfxParamPropSecret, 0) != 0; + } + + bool Base::getIsPersistant() const { + return _properties.getIntProperty(kOfxParamPropPersistant, 0) != 0; + } + + bool Base::getEvaluateOnChange() const { + return _properties.getIntProperty(kOfxParamPropEvaluateOnChange, 0) != 0; + } + + bool Base::getCanUndo() const { + if (_properties.fetchProperty(kOfxParamPropCanUndo)) { + return _properties.getIntProperty(kOfxParamPropCanUndo) != 0; + } + return false; + } + + bool Base::getCanAnimate() const { + if (_properties.fetchProperty(kOfxParamPropAnimates)) { + return _properties.getIntProperty(kOfxParamPropAnimates) != 0; + } + return false; + } + + // + // Descriptor + // + + struct TypeMap { + const char *paramType; + Property::TypeEnum propType; + int propDimension; + }; + + static + bool isDoubleParam(const std::string ¶mType) + { + return paramType == kOfxParamTypeDouble || + paramType == kOfxParamTypeDouble2D || + paramType == kOfxParamTypeDouble3D +#ifdef OFX_SUPPORTS_PARAMETRIC + || paramType == kOfxParamTypeParametric +#endif + ; + } + + bool isColourParam(const std::string ¶mType) + { + return + paramType == kOfxParamTypeRGBA || + paramType == kOfxParamTypeRGB; + } + + bool isIntParam(const std::string ¶mType) + { + return paramType == kOfxParamTypeInteger || + paramType == kOfxParamTypeInteger2D || + paramType == kOfxParamTypeInteger3D; + } + + static const TypeMap typeMap[] = { + { kOfxParamTypeInteger, Property::eInt, 1 }, + { kOfxParamTypeDouble, Property::eDouble, 1 }, + { kOfxParamTypeBoolean, Property::eInt, 1 }, + { kOfxParamTypeChoice, Property::eInt, 1 }, + { kOfxParamTypeRGBA, Property::eDouble, 4 }, + { kOfxParamTypeRGB, Property::eDouble, 3 }, + { kOfxParamTypeDouble2D, Property::eDouble, 2 }, + { kOfxParamTypeInteger2D, Property::eInt, 2 }, + { kOfxParamTypeDouble3D, Property::eDouble, 3 }, + { kOfxParamTypeInteger3D, Property::eInt, 3 }, + { kOfxParamTypeString, Property::eString, 1 }, + { kOfxParamTypeCustom, Property::eString, 1 }, + { kOfxParamTypeGroup, Property::eNone, 0 }, + { kOfxParamTypePage, Property::eNone, 0 }, + { kOfxParamTypePushButton,Property::eNone, 0 }, +#ifdef OFX_SUPPORTS_PARAMETRIC + { kOfxParamTypeParametric,Property::eDouble, 0 }, +#endif + { 0, Property::eNone, 0 } + }; + + /// is this a standard type + bool isStandardType(const std::string &type) + { + const TypeMap *tm = typeMap; + while (tm->paramType) { + if (tm->paramType == type) + return true; + tm++; + } + return false; + } + + static + bool findType(const std::string paramType, Property::TypeEnum &propType, int &propDim) + { + const TypeMap *tm = typeMap; + while (tm->paramType) { + if (tm->paramType == paramType) { + propType = tm->propType; + propDim = tm->propDimension; + return true; + } + tm++; + } + return false; + } + + /// make a parameter, with the given type and name + Descriptor::Descriptor(const std::string &type, + const std::string &name) : Base(name, type) + { + const char *ctype = type.c_str(); + const char *cname = name.c_str(); + + Property::PropSpec universalProps[] = { + { kOfxPropType, Property::eString, 1, true, kOfxTypeParameter }, + { kOfxParamPropSecret, Property::eInt, 1, false, "0"}, + { kOfxParamPropHint, Property::eString, 1, false, ""}, + { kOfxParamPropScriptName, Property::eString, 1, false, cname }, + { kOfxParamPropParent, Property::eString, 1, false, "" }, + { kOfxParamPropEnabled, Property::eInt, 1, false, "1" }, + { kOfxParamPropDataPtr, Property::ePointer, 1, false, 0 }, + { kOfxParamPropType, Property::eString, 1, true, ctype }, + { kOfxPropName, Property::eString, 1, false, cname }, + { kOfxPropLabel, Property::eString, 1, false, cname }, + { kOfxPropShortLabel, Property::eString, 1, false, cname }, + { kOfxPropLongLabel, Property::eString, 1, false, cname }, + { kOfxPropIcon, Property::eString, 2, false, "" }, + Property::propSpecEnd + }; + + _properties.addProperties(universalProps); + } + + /// make a parameter, with the given type and name + void Descriptor::addStandardParamProps(const std::string &type) + { + Property::TypeEnum propType = Property::eString; + int propDim = 1; + findType(type, propType, propDim); + + + static const Property::PropSpec allString[] = { + { kOfxParamPropStringMode, Property::eString, 1, false, kOfxParamStringIsSingleLine }, + { kOfxParamPropStringFilePathExists, Property::eInt, 1, false, "1" }, + Property::propSpecEnd + }; + + static const Property::PropSpec allChoice[] = { + { kOfxParamPropChoiceOption, Property::eString, 0, false, "" }, + Property::propSpecEnd + }; + + static const Property::PropSpec allCustom[] = { + { kOfxParamPropCustomInterpCallbackV1, Property::ePointer, 1, false, 0 }, + Property::propSpecEnd + }; + + static const Property::PropSpec allPage[] = { + { kOfxParamPropPageChild, Property::eString, 0, false, "" }, + Property::propSpecEnd + }; + + static const Property::PropSpec allGroup[] = { + { kOfxParamPropGroupOpen, Property::eInt, 1, false, "1" }, + Property::propSpecEnd + }; + +# ifdef OFX_SUPPORTS_PARAMETRIC + static const Property::PropSpec allParametric[] = { + { kOfxParamPropParametricDimension, Property::eInt, 1, false, "1" }, + { kOfxParamPropParametricUIColour, Property::eDouble, 0, false, "" }, + { kOfxParamPropParametricInteractBackground,Property::ePointer, 1, false, 0 }, + { kOfxParamPropParametricRange, Property::eDouble, 2, false, "0" }, + Property::propSpecEnd + }; +# endif + + if (propType != Property::eNone) { + addValueParamProps(type, propType, propDim); + } + + if (type == kOfxParamTypeString) { + _properties.addProperties(allString); + } + + if (isDoubleParam(type) || isIntParam(type) || isColourParam(type)) { + addNumericParamProps(type, propType, propDim); + } + + if (type != kOfxParamTypeGroup && type != kOfxParamTypePage) { + addInteractParamProps(type); + } + + if (type == kOfxParamTypeChoice) { + _properties.addProperties(allChoice); + } + + if (type == kOfxParamTypeCustom) { + _properties.addProperties(allCustom); + } + + if (type == kOfxParamTypePage) { + _properties.addProperties(allPage); + } + + if (type == kOfxParamTypeGroup) { + _properties.addProperties(allGroup); + } + +# ifdef OFX_SUPPORTS_PARAMETRIC + if (type == kOfxParamTypeParametric) { + _properties.addProperties(allParametric); + _properties.setDoubleProperty(kOfxParamPropParametricRange, 0., 0); + _properties.setDoubleProperty(kOfxParamPropParametricRange, 1., 1); + } +# endif + } + + /// add standard properties to a params that can take an interact + void Descriptor::addInteractParamProps(const std::string &/*type*/) + { + static const Property::PropSpec allButGroupPageProps[] = { + { kOfxParamPropInteractV1, Property::ePointer, 1, false, 0 }, + { kOfxParamPropInteractSize, Property::eDouble, 2, false, "0" }, + { kOfxParamPropInteractSizeAspect, Property::eDouble, 1, false, "1" }, + { kOfxParamPropInteractMinimumSize, Property::eDouble, 2, false, "10" }, + { kOfxParamPropInteractPreferedSize,Property::eInt, 2, false, "10" }, + Property::propSpecEnd + }; + + + _properties.addProperties(allButGroupPageProps); + } + + /// add standard properties to a value holding param + void Descriptor::addValueParamProps(const std::string &type, Property::TypeEnum valueType, int dim) + { + static const Property::PropSpec invariantProps[] = { + { kOfxParamPropIsAnimating, Property::eInt, 1, false, "0" }, + { kOfxParamPropIsAutoKeying,Property::eInt, 1, false, "0" }, + { kOfxParamPropPersistant, Property::eInt, 1, false, "1" }, + { kOfxParamPropEvaluateOnChange, Property::eInt, 1, false, "1" }, +# ifdef kOfxParamPropPluginMayWrite + { kOfxParamPropPluginMayWrite, Property::eInt, 1, false, "0" }, // removed in OFX 1.4 +# endif + { kOfxParamPropCanUndo, Property::eInt, 1, false, "1" }, + { kOfxParamPropCacheInvalidation, Property::eString, 1, false, kOfxParamInvalidateValueChange }, + Property::propSpecEnd + }; + + /// http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#ParametersAnimation + /// The following may animate, depending on the host. + /// Properties exist on the host to check this. If the host does support animation on them, then they do _not_ animate by default. + /// They are... + /// - kOfxParamTypeCustom + /// - kOfxParamTypeString + /// - kOfxParamTypeBoolean + /// - kOfxParamTypeChoice + /// If host doesn't support animation on them, then setting kOfxParamPropIsAnimating to 0 or 1 doesn't matter + /// so just set the kOfxParamPropIsAnimating property to 0 for all those "extra animating" params. + bool animates = type != kOfxParamTypeCustom && type != kOfxParamTypeString && type != kOfxParamTypeBoolean && type != kOfxParamTypeChoice; + + Property::PropSpec variantProps[] = { + { kOfxParamPropAnimates, Property::eInt, 1, false, animates ? "1" : "0" }, + { kOfxParamPropDefault, valueType, dim, false, valueType == Property::eString ? "" : "0" }, + Property::propSpecEnd + }; + + _properties.addProperties(invariantProps); + _properties.addProperties(variantProps); + } + + /// add standard properties to a value holding param + void Descriptor::addNumericParamProps(const std::string &type, Property::TypeEnum valueType, int dim) + { + static std::string dbl_minstr, dbl_maxstr, int_minstr, int_maxstr; + static bool doneOne = false; + + if(!doneOne) { + std::ostringstream dbl_min, dbl_max, int_min, int_max; + doneOne = true; + dbl_min << -DBL_MAX; // not a bug, @see kOfxParamPropDisplayMin + dbl_max << DBL_MAX; + int_min << INT_MIN; + int_max << INT_MAX; + + dbl_minstr = dbl_min.str(); + dbl_maxstr = dbl_max.str(); + int_minstr = int_min.str(); + int_maxstr = int_max.str(); + } + + Property::PropSpec allNumeric[] = { + { kOfxParamPropDisplayMin, valueType, dim, false, isColourParam(type) ? "0" : (valueType == Property::eDouble ? dbl_minstr : int_minstr).c_str() }, + { kOfxParamPropDisplayMax, valueType, dim, false, isColourParam(type) ? "1" : (valueType == Property::eDouble ? dbl_maxstr : int_maxstr).c_str() }, + { kOfxParamPropMin, valueType, dim, false, (valueType == Property::eDouble ? dbl_minstr : int_minstr).c_str() }, + { kOfxParamPropMax, valueType, dim, false, (valueType == Property::eDouble ? dbl_maxstr : int_maxstr).c_str() }, + Property::propSpecEnd + }; + + _properties.addProperties(allNumeric); + + /// if any double or a colour + if (valueType == Property::eDouble) { + static const Property::PropSpec allDouble[] = { + { kOfxParamPropIncrement, Property::eDouble, 1, false, "1" }, + { kOfxParamPropDigits, Property::eInt, 1, false, "2" }, + Property::propSpecEnd + }; + _properties.addProperties(allDouble); + } + + /// if a double param type + if(isDoubleParam(type)) { + static const Property::PropSpec allDouble[] = { + { kOfxParamPropDoubleType, Property::eString, 1, false, kOfxParamDoubleTypePlain }, + { kOfxParamPropDefaultCoordinateSystem, Property::eString, 1, false, kOfxParamCoordinatesCanonical }, + Property::propSpecEnd + }; + _properties.addProperties(allDouble); + + if(dim == 1) { + static const Property::PropSpec allDouble1D[] = { + { kOfxParamPropShowTimeMarker, Property::eInt, 1, false, "0" }, + Property::propSpecEnd + }; + + _properties.addProperties(allDouble1D); + } + } + + /// if a multi dimensional param + if ((isDoubleParam(type) || isIntParam(type)) && (dim == 2 || dim == 3 +#ifdef OFX_SUPPORTS_PARAMETRIC + || dim == 0 +#endif + )) { + static const Property::PropSpec all2D3D[] = { + { kOfxParamPropDimensionLabel, Property::eString, dim, false, "" }, + Property::propSpecEnd + }; + + _properties.addProperties(all2D3D); + _properties.setStringProperty(kOfxParamPropDimensionLabel, "x", 0); + _properties.setStringProperty(kOfxParamPropDimensionLabel, "y", 1); + if (dim == 3) { + _properties.setStringProperty(kOfxParamPropDimensionLabel, "z", 2); + } + } + + /// if a multi dimensional param + if (isColourParam(type)) { + static const Property::PropSpec allColor[] = { + { kOfxParamPropDimensionLabel, Property::eString, dim, false, "" }, + Property::propSpecEnd + }; + + _properties.addProperties(allColor); + _properties.setStringProperty(kOfxParamPropDimensionLabel, "r", 0); + _properties.setStringProperty(kOfxParamPropDimensionLabel, "g", 1); + _properties.setStringProperty(kOfxParamPropDimensionLabel, "b", 2); + if (dim == 4) { + _properties.setStringProperty(kOfxParamPropDimensionLabel, "a", 3); + } + } + } + + BaseSet::~BaseSet() {} + + /// obtain a handle on this set for passing to the C api + SetDescriptor::SetDescriptor() + { + } + + /// obtain a handle on this set for passing to the C api + OfxParamSetHandle BaseSet::getParamSetHandle() const + { + return (OfxParamSetHandle)this; + } + + SetDescriptor::~SetDescriptor() + { + // iterate the params and delete them + std::list::iterator i; + for(i = _paramList.begin(); i != _paramList.end(); ++i) { + if(*i) + delete (*i); + } + } + + const std::map &SetDescriptor::getParams() const + { + return _paramMap; + } + + const std::list &SetDescriptor::getParamList() const + { + return _paramList; + } + + void SetDescriptor::addParam(const std::string &name, Descriptor *p) { + _paramList.push_back(p); + _paramMap[name] = p; + } + + /// define a param on this effect + Descriptor *SetDescriptor::paramDefine(const char *paramType, + const char *name) + { + if(!isStandardType(paramType)) + return NULL; /// << EEK! This is bad. + + Descriptor *desc = new Descriptor(paramType, name); + desc->addStandardParamProps(paramType); + addParam(name, desc); + return desc; + } + + //////////////////////////////////////////////////////////////////////////////// + // + // Instance + // + + /// the description of a plugin parameter + Instance::~Instance() {} + + /// make a parameter, with the given type and name + Instance::Instance(Descriptor& descriptor, Param::SetInstance* paramSet) + : Base(descriptor.getName(), descriptor.getType(), descriptor.getProperties()) + , _paramSetInstance(paramSet) + , _parentInstance(0) + { + _properties.addNotifyHook(kOfxParamPropEnabled, this); + _properties.addNotifyHook(kOfxParamPropSecret, this); + _properties.addNotifyHook(kOfxPropLabel, this); + _properties.addNotifyHook(kOfxParamPropMin, this); + _properties.addNotifyHook(kOfxParamPropMax, this); + _properties.addNotifyHook(kOfxParamPropDisplayMin, this); + _properties.addNotifyHook(kOfxParamPropDisplayMax, this); + _properties.addNotifyHook(kOfxParamPropEvaluateOnChange, this); + } + + // callback which should set enabled state as appropriate + void Instance::setEnabled() + { + } + + // callback which should set secret state as appropriate + void Instance::setSecret() + { + } + + // callback which should update label + void Instance::setLabel() + { + } + + /// callback which should set range + void Instance::setRange() + { + } + + /// callback which should set display range + void Instance::setDisplayRange() + { + } + + /// callback which should set evaluate on change + void Instance::setEvaluateOnChange() + { + } + + /// get a value, implemented by instances to deconstruct var args + OfxStatus Instance::getV(va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// get a value, implemented by instances to deconstruct var args + OfxStatus Instance::getV(OfxTime /*time*/, va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// set a value, implemented by instances to deconstruct var args + OfxStatus Instance::setV(va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// key a value, implemented by instances to deconstruct var args + OfxStatus Instance::setV(OfxTime /*time*/, va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// derive a value, implemented by instances to deconstruct var args + OfxStatus Instance::deriveV(OfxTime /*time*/, va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// integrate a value, implemented by instances to deconstruct var args + OfxStatus Instance::integrateV(OfxTime /*time1*/, OfxTime /*time2*/, va_list /*arg*/) + { + return kOfxStatErrUnsupported; + } + + /// overridden from Property::NotifyHook + void Instance::notify(const std::string &name, bool /*single*/, int /*num*/) + { + if (name == kOfxPropLabel) { + setLabel(); + } + if (name == kOfxParamPropEnabled) { + setEnabled(); + } + if (name == kOfxParamPropSecret) { + setSecret(); + } + if (name == kOfxParamPropMin || name == kOfxParamPropMax) { + setRange(); + } + if (name == kOfxParamPropDisplayMin || name == kOfxParamPropDisplayMax) { + setDisplayRange(); + } + if (name == kOfxParamPropEvaluateOnChange) { + setEvaluateOnChange(); + } + } + + // copy one parameter to another, with a range (NULL means to copy all animation) + OfxStatus Instance::copyFrom(const Instance &/*instance*/, OfxTime /*offset*/, const OfxRangeD* /*range*/) { + return kOfxStatErrMissingHostFeature; + } + + void Instance::setParentInstance(Instance* instance){ + _parentInstance = instance; + } + + Instance* Instance::getParentInstance(){ + return _parentInstance; + } + + // + // KeyframeParam + // + + OfxStatus KeyframeParam::getNumKeys(unsigned int &/*nKeys*/) const { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus KeyframeParam::getKeyTime(int /*nth*/, OfxTime& /*time*/) const { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus KeyframeParam::getKeyIndex(OfxTime /*time*/, int /*direction*/, int & /*index*/) const { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus KeyframeParam::deleteKey(OfxTime /*time*/) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus KeyframeParam::deleteAllKeys() { + return kOfxStatErrMissingHostFeature; + } + + void GroupInstance::setChildren(std::vector children) + { + _children = children; + for (std::vector::iterator it=children.begin(); it!=children.end(); ++it) { + if(*it){ + (*it)->setParentInstance(this); + } + } + } + + const std::vector &GroupInstance::getChildren() const + { + return _children; + } + + // + // Page Instance + // + + const std::map &PageInstance::getChildren() const + { + // HACK!!!! this really should be done with a notify hook so we don't force + // _children to be mutable + if(_children.size() == 0 ) + { + int nChildren = _properties.getDimension(kOfxParamPropPageChild); + for(int i=0;igetParam(childName); + if(child) + _children[i]=child; + } + } + return _children; + } + + // + // ChoiceInstance + // + + /// make a parameter, with the given type and name + ChoiceInstance::ChoiceInstance(Descriptor& descriptor, Param::SetInstance* instance) + : Instance(descriptor,instance) + { + _properties.addNotifyHook(kOfxParamPropChoiceOption, this); + } + + // callback which should set option as appropriate + void ChoiceInstance::setOption(int /*num*/) + { + } + + /// implementation of var args function + OfxStatus ChoiceInstance::getV(va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = get(*value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus ChoiceInstance::getV(OfxTime time, va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = get(time, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus ChoiceInstance::setV(va_list arg) + { + int value = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(value); + } + + /// implementation of var args function + OfxStatus ChoiceInstance::setV(OfxTime time, va_list arg) + { + int value = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(time, value); + } + + /// overridden from Instance + void ChoiceInstance::notify(const std::string &name, bool single, int num) + { + Instance::notify(name, single, num); + if (name == kOfxParamPropChoiceOption) { + setOption(num); + } + } + // + // IntegerInstance + // + OfxStatus IntegerInstance::derive(OfxTime /*time*/, int&) { + return kOfxStatErrUnsupported; + } + + OfxStatus IntegerInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, int&) { + return kOfxStatErrUnsupported; + } + + /// implementation of var args function + OfxStatus IntegerInstance::getV(va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = get(*value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus IntegerInstance::getV(OfxTime time, va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = get(time, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus IntegerInstance::setV(va_list arg) + { + int value = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(value); + } + + /// implementation of var args function + OfxStatus IntegerInstance::setV(OfxTime time, va_list arg) + { + int value = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(time, value); + } + + /// implementation of var args function + OfxStatus IntegerInstance::deriveV(OfxTime time, va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = derive(time, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus IntegerInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + int *value = va_arg(arg, int*); + OfxStatus stat = integrate(time1, time2, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + // + // DoubleInstance + // + /// implementation of var args function + OfxStatus DoubleInstance::getV(va_list arg) + { + double *value = va_arg(arg, double*); + OfxStatus stat = get(*value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus DoubleInstance::getV(OfxTime time, va_list arg) + { + double *value = va_arg(arg, double*); + OfxStatus stat = get(time, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus DoubleInstance::setV(va_list arg) + { + double value = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(value); + } + + /// implementation of var args function + OfxStatus DoubleInstance::setV(OfxTime time, va_list arg) + { + double value = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(time, value); + } + + /// implementation of var args function + OfxStatus DoubleInstance::deriveV(OfxTime time, va_list arg) + { + double *value = va_arg(arg, double*); + OfxStatus stat = derive(time, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus DoubleInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + double *value = va_arg(arg, double*); + OfxStatus stat = integrate(time1, time2, *value); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + // + // BooleanInstance + // + /// implementation of var args function + OfxStatus BooleanInstance::getV(va_list arg) + { + bool v; + OfxStatus stat = get(v); + + int *value = va_arg(arg, int*); + *value = v; +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus BooleanInstance::getV(OfxTime time, va_list arg) + { + bool v; + OfxStatus stat = get(time, v); + + int *value = va_arg(arg, int*); + *value = v; +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus BooleanInstance::setV(va_list arg) + { + bool value = va_arg(arg, int) != 0; +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(value); + } + + /// implementation of var args function + OfxStatus BooleanInstance::setV(OfxTime time, va_list arg) + { + bool value = va_arg(arg, int) != 0; +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(time, value); + } + + + // + // RGBAInstance + // + + OfxStatus RGBAInstance::derive(OfxTime /*time*/, double&, double&, double&, double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus RGBAInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, double&,double&,double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + /// implementation of var args function + OfxStatus RGBAInstance::getV(va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + double *a = va_arg(arg, double*); + OfxStatus stat = get(*r, *g, *b, *a); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b << ' ' << *a; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBAInstance::getV(OfxTime time, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + double *a = va_arg(arg, double*); + OfxStatus stat = get(time, *r, *g, *b, *a); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b << ' ' << *a; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBAInstance::setV(va_list arg) + { + double r = va_arg(arg, double); + double g = va_arg(arg, double); + double b = va_arg(arg, double); + double a = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << r << ',' << g << ',' << b << ',' << a << ')'; +# endif + return set(r, g, b, a); + } + + /// implementation of var args function + OfxStatus RGBAInstance::setV(OfxTime time, va_list arg) + { + double r = va_arg(arg, double); + double g = va_arg(arg, double); + double b = va_arg(arg, double); + double a = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << r << ',' << g << ',' << b << ',' << a << ')'; +# endif + return set(time, r, g, b, a); + } + + /// implementation of var args function + OfxStatus RGBAInstance::deriveV(OfxTime time, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + double *a = va_arg(arg, double*); + OfxStatus stat = derive(time, *r, *g, *b, *a); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b << ' ' << *a; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBAInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + double *a = va_arg(arg, double*); + OfxStatus stat = integrate(time1, time2, *r, *g, *b, *a); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b << ' ' << *a; + } +# endif + return stat; + } + + // + // RGBInstance + // + OfxStatus RGBInstance::derive(OfxTime /*time*/, double&,double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus RGBInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, double&,double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + /// implementation of var args function + OfxStatus RGBInstance::getV(va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + OfxStatus stat = get(*r, *g, *b); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBInstance::getV(OfxTime time, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + OfxStatus stat = get(time, *r, *g, *b); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBInstance::setV(va_list arg) + { + double r = va_arg(arg, double); + double g = va_arg(arg, double); + double b = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << r << ',' << g << ',' << b << ')'; +# endif + return set(r, g, b); + } + + /// implementation of var args function + OfxStatus RGBInstance::setV(OfxTime time, va_list arg) + { + double r = va_arg(arg, double); + double g = va_arg(arg, double); + double b = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << r << ',' << g << ',' << b << ')'; +# endif + return set(time, r, g, b); + } + + /// implementation of var args function + OfxStatus RGBInstance::deriveV(OfxTime time, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + OfxStatus stat = derive(time, *r, *g, *b); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus RGBInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + double *r = va_arg(arg, double*); + double *g = va_arg(arg, double*); + double *b = va_arg(arg, double*); + OfxStatus stat = integrate(time1, time2, *r, *g, *b); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *r << ' ' << *g << ' ' << *b; + } +# endif + return stat; + } + + // + // Double2DInstance + // + + OfxStatus Double2DInstance::derive(OfxTime /*time*/, double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Double2DInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Double2DInstance::getV(va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + OfxStatus stat = get(*value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double2DInstance::getV(OfxTime time, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + OfxStatus stat = get(time, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double2DInstance::setV(va_list arg) + { + double value1 = va_arg(arg, double); + double value2 = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ')'; +# endif + return set(value1, value2); + } + + /// implementation of var args function + OfxStatus Double2DInstance::setV(OfxTime time, va_list arg) + { + double value1 = va_arg(arg, double); + double value2 = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ')'; +# endif + return set(time, value1, value2); + } + + /// implementation of var args function + OfxStatus Double2DInstance::deriveV(OfxTime time, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + OfxStatus stat = derive(time, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double2DInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + OfxStatus stat = integrate(time1, time2, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + // + // Integer2DInstance + // + + OfxStatus Integer2DInstance::derive(OfxTime /*time*/, int&,int&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Integer2DInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, int&,int&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Integer2DInstance::getV(va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + OfxStatus stat = get(*value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer2DInstance::getV(OfxTime time, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + OfxStatus stat = get(time, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer2DInstance::setV(va_list arg) + { + int value1 = va_arg(arg, int); + int value2 = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ')'; +# endif + return set(value1, value2); + } + + /// implementation of var args function + OfxStatus Integer2DInstance::setV(OfxTime time, va_list arg) + { + int value1 = va_arg(arg, int); + int value2 = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ')'; +# endif + return set(time, value1, value2); + } + + /// implementation of var args function + OfxStatus Integer2DInstance::deriveV(OfxTime time, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + OfxStatus stat = derive(time, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer2DInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + OfxStatus stat = integrate(time1, time2, *value1, *value2); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2; + } +# endif + return stat; + } + + // + // Double3DInstance + // + + OfxStatus Double3DInstance::derive(OfxTime /*time*/, double&,double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Double3DInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, double&,double&,double&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Double3DInstance::getV(va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + double *value3 = va_arg(arg, double*); + OfxStatus stat = get(*value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double3DInstance::getV(OfxTime time, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + double *value3 = va_arg(arg, double*); + OfxStatus stat = get(time, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double3DInstance::setV(va_list arg) + { + double value1 = va_arg(arg, double); + double value2 = va_arg(arg, double); + double value3 = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ',' << value3 << ')'; +# endif + return set(value1, value2, value3); + } + + /// implementation of var args function + OfxStatus Double3DInstance::setV(OfxTime time, va_list arg) + { + double value1 = va_arg(arg, double); + double value2 = va_arg(arg, double); + double value3 = va_arg(arg, double); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ',' << value3 << ')'; +# endif + return set(time, value1, value2, value3); + } + + /// implementation of var args function + OfxStatus Double3DInstance::deriveV(OfxTime time, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + double *value3 = va_arg(arg, double*); + OfxStatus stat = derive(time, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Double3DInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + double *value1 = va_arg(arg, double*); + double *value2 = va_arg(arg, double*); + double *value3 = va_arg(arg, double*); + OfxStatus stat = integrate(time1, time2, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + // + // Integer3DInstance + // + OfxStatus Integer3DInstance::derive(OfxTime /*time*/, int&,int&,int&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Integer3DInstance::integrate(OfxTime /*time1*/, OfxTime /*time2*/, int&,int&,int&) { + return kOfxStatErrMissingHostFeature; + } + + OfxStatus Integer3DInstance::getV(va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + int *value3 = va_arg(arg, int*); + OfxStatus stat = get(*value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer3DInstance::getV(OfxTime time, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + int *value3 = va_arg(arg, int*); + OfxStatus stat = get(time, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer3DInstance::setV(va_list arg) + { + int value1 = va_arg(arg, int); + int value2 = va_arg(arg, int); + int value3 = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ',' << value3 << ')'; +# endif + return set(value1, value2, value3); + } + + /// implementation of var args function + OfxStatus Integer3DInstance::setV(OfxTime time, va_list arg) + { + int value1 = va_arg(arg, int); + int value2 = va_arg(arg, int); + int value3 = va_arg(arg, int); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << '(' << value1 << ',' << value2 << ',' << value3 << ')'; +# endif + return set(time, value1, value2, value3); + } + + /// implementation of var args function + OfxStatus Integer3DInstance::deriveV(OfxTime time, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + int *value3 = va_arg(arg, int*); + OfxStatus stat = derive(time, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus Integer3DInstance::integrateV(OfxTime time1, OfxTime time2, va_list arg) + { + int *value1 = va_arg(arg, int*); + int *value2 = va_arg(arg, int*); + int *value3 = va_arg(arg, int*); + OfxStatus stat = integrate(time1, time2, *value1, *value2, *value3); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value1 << ' ' << *value2 << ' ' << *value3; + } +# endif + return stat; + } + + //////////////////////////////////////////////////////////////////////////////// + // string param + OfxStatus StringInstance::getV(va_list arg) + { + const char **value = va_arg(arg, const char **); + + OfxStatus stat = get(_returnValue); // I so don't like this, temp storage should be delegated to the implementation + *value = _returnValue.c_str(); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus StringInstance::getV(OfxTime time, va_list arg) + { + const char **value = va_arg(arg, const char **); + + OfxStatus stat = get(time, _returnValue); // I so don't like this, temp storage should be delegated to the implementation + *value = _returnValue.c_str(); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *value; + } +# endif + return stat; + } + + /// implementation of var args function + OfxStatus StringInstance::setV(va_list arg) + { + char *value = va_arg(arg, char*); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(value); + } + + /// implementation of var args function + OfxStatus StringInstance::setV(OfxTime time, va_list arg) + { + char *value = va_arg(arg, char*); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << value; +# endif + return set(time, value); + } + + ////////////////////////////////////////////////////////////////////////////////// + // Param::SetInstance + // + + /// ctor + SetInstance::SetInstance() + {} + + /// dtor. + SetInstance::~SetInstance() + { + // iterate the params and delete them + std::list::iterator i; + for(i = _paramList.begin(); i != _paramList.end(); ++i) { + if(*i) + delete (*i); + } + } + + const std::map &SetInstance::getParams() const + { + return _params; + } + + const std::list &SetInstance::getParamList() const + { + return _paramList; + } + + OfxStatus SetInstance::addParam(const std::string& name, Instance* instance) + { + if(_params.find(name)==_params.end()){ + _params[name] = instance; + _paramList.push_back(instance); + } + else + return kOfxStatErrExists; + + return kOfxStatOK; + } + + //////////////////////////////////////////////////////////////////////////////// + // Suite functions below + + static OfxStatus paramDefine(OfxParamSetHandle paramSet, + const char *paramType, + const char *name, + OfxPropertySetHandle *propertySet) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramDefine - " << paramSet << ' ' << paramType << ' ' << name << ' ' << propertySet << " ..."; +# endif + SetDescriptor *paramSetDescriptor = reinterpret_cast(paramSet); + + if (!paramSetDescriptor) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + Descriptor *desc = paramSetDescriptor->paramDefine(paramType, name); + + if(desc) { + if (propertySet) + *propertySet = desc->getPropHandle(); + // desc is still referenced by _paramList and _paramMap +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } else { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrUnsupported) << std::endl; +# endif + return kOfxStatErrUnsupported; + } + } + + static OfxStatus paramGetHandle(OfxParamSetHandle paramSet, + const char *name, + OfxParamHandle *param, + OfxPropertySetHandle *propertySet) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetHandle - " << paramSet << ' ' << name << ' ' << param << ' ' << propertySet << " ..."; +# endif + BaseSet *baseSet = reinterpret_cast(paramSet); + + if (!baseSet) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + SetInstance *setInstance = dynamic_cast(baseSet); + + if(setInstance){ + const std::map& params = setInstance->getParams(); + std::map::const_iterator it = params.find(name); + + // if we can't find it return an error... + if(it==params.end()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' '<< StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + + // get the param + if (param) { + *param = (it->second)->getHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *param; +# endif + } + + // get the param property set + if(propertySet) { + *propertySet = (it->second)->getPropHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *propertySet; +# endif + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } + + SetDescriptor *setDescriptor = dynamic_cast(baseSet); + + if(setDescriptor){ + const std::map& params = setDescriptor->getParams(); + std::map::const_iterator it = params.find(name); + + // if we can't find it return an error... + if(it==params.end()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' '<< StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + + // get the param + if (param) { + *param = (it->second)->getHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *param; +# endif + } + + // get the param property set + if(propertySet) { + *propertySet = (it->second)->getPropHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *propertySet; +# endif + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + static OfxStatus paramSetGetPropertySet(OfxParamSetHandle paramSet, + OfxPropertySetHandle *propHandle) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramSetGetPropertySet - " << paramSet << ' ' << propHandle << " ..."; +# endif + BaseSet *baseSet = reinterpret_cast(paramSet); + + if (baseSet) { + if (propHandle) { + *propHandle = baseSet->getParamSetProps().getHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *propHandle; +# endif + } +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + static OfxStatus paramGetPropertySet(OfxParamHandle param, + OfxPropertySetHandle *propHandle) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetPropertySet - " << param << ' ' << propHandle << " ..."; +# endif + Param::Instance *paramInstance = reinterpret_cast(param); + + if(paramInstance && paramInstance->verifyMagic()){ + // get the param property set + if (propHandle) { + *propHandle = paramInstance->getPropHandle(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << *propHandle; +# endif + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } else { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + } + + /// get the current param value + static OfxStatus paramGetValue(OfxParamHandle paramHandle, + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetValue - " << paramHandle << " ..."; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + va_list ap; + va_start(ap,paramHandle); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->getV(ap); + } + catch(...) {} + + va_end(ap); + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + /// get the param value at a time + static OfxStatus paramGetValueAtTime(OfxParamHandle paramHandle, + OfxTime time, + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetValueAtTime - " << paramHandle << ' ' << time << " ..."; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + + va_list ap; + va_start(ap, time); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->getV(time, ap); + } + catch(...) {} + + va_end(ap); + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + /// get the param's derivative at the given time + static OfxStatus paramGetDerivative(OfxParamHandle paramHandle, + OfxTime time, + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetDerivative - " << paramHandle << ' ' << time << " ..."; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + va_list ap; + va_start(ap, time); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->deriveV(time, ap); + } + catch(...) {} + + va_end(ap); + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramGetIntegral(OfxParamHandle paramHandle, + OfxTime time1, OfxTime time2, + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetIntegral - " << paramHandle << ' ' << time1 << ' ' << time2 << " ..."; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + va_list ap; + va_start(ap, time2); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->integrateV(time1, time2, ap); + } + catch(...) {} + + va_end(ap); + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + /// set the param's value at the 'current' time + static OfxStatus paramSetValue(OfxParamHandle paramHandle, + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramSetValue - " << paramHandle << ' '; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << " ... " << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + va_list ap; + va_start(ap, paramHandle); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->setV(ap); + } + catch(...) {} + + va_end(ap); + + if (stat == kOfxStatOK) { + paramInstance->getParamSetInstance()->paramChangedByPlugin(paramInstance); + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << " ... " << StatStr(stat) << std::endl; +# endif + return stat; + } + + + /// set the param's value at the indicated time, and set a key + static OfxStatus paramSetValueAtTime(OfxParamHandle paramHandle, + OfxTime time, // time in frames + ...) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramSetValueAtTime - " << paramHandle << ' ' << time << ' '; +# endif + Instance *paramInstance = reinterpret_cast(paramHandle); + if(!paramInstance || !paramInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << " ... " << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + va_list ap; + va_start(ap, time); + OfxStatus stat = kOfxStatErrUnsupported; + + try { + stat = paramInstance->setV(time, ap); + } + catch(...) {} + + va_end(ap); + + if (stat == kOfxStatOK) { + paramInstance->getParamSetInstance()->paramChangedByPlugin(paramInstance); + } + +# ifdef OFX_DEBUG_PARAMETERS + std::cout << " ... " << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramGetNumKeys(OfxParamHandle paramHandle, + unsigned int *numberOfKeys) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetNumKeys - " << paramHandle << " ..."; +# endif + Param::Instance *pInstance = reinterpret_cast(paramHandle); + + if (!pInstance || !pInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + KeyframeParam *paramInstance = dynamic_cast(pInstance); + if(!paramInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = paramInstance->getNumKeys(*numberOfKeys); +# ifdef OFX_DEBUG_PARAMETERS + if (stat == kOfxStatOK) { + std::cout << ' ' << *numberOfKeys; + } + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramGetKeyTime(OfxParamHandle paramHandle, + unsigned int nthKey, + OfxTime *time) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetKeyTime - " << paramHandle << " ..."; +# endif + Param::Instance *pInstance = reinterpret_cast(paramHandle); + + if (!pInstance || !pInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + KeyframeParam *paramInstance = dynamic_cast(pInstance); + if(!paramInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = paramInstance->getKeyTime(nthKey,*time); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramGetKeyIndex(OfxParamHandle paramHandle, + OfxTime time, + int direction, + int *index) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramGetKeyIndex - " << paramHandle << " ..."; +# endif + Param::Instance *pInstance = reinterpret_cast(paramHandle); + + if (!pInstance || !pInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + KeyframeParam *paramInstance = dynamic_cast(pInstance); + if(!paramInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = paramInstance->getKeyIndex(time,direction,*index); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramDeleteKey(OfxParamHandle paramHandle, + OfxTime time) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramDeleteKey - " << paramHandle << " ..."; +# endif + Param::Instance *pInstance = reinterpret_cast(paramHandle); + + if (!pInstance || !pInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + KeyframeParam *paramInstance = dynamic_cast(pInstance); + if(!paramInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = paramInstance->deleteKey(time); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramDeleteAllKeys(OfxParamHandle paramHandle) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramDeleteAllKeys - " << paramHandle << " ..."; +# endif + Param::Instance *pInstance = reinterpret_cast(paramHandle); + + if (!pInstance || !pInstance->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + KeyframeParam *paramInstance = dynamic_cast(pInstance); + if(!paramInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = paramInstance->deleteAllKeys(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramCopy(OfxParamHandle paramTo, + OfxParamHandle paramFrom, + OfxTime dstOffset, const OfxRangeD *frameRange) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramCopy - " << paramTo << " ..."; +# endif + Instance *paramInstanceTo = reinterpret_cast(paramTo); + Instance *paramInstanceFrom = reinterpret_cast(paramFrom); + + if(!paramInstanceTo || !paramInstanceTo->verifyMagic() || + !paramInstanceFrom || !paramInstanceFrom->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + + OfxStatus stat = paramInstanceTo->copyFrom(*paramInstanceFrom,dstOffset,frameRange); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static OfxStatus paramEditBegin(OfxParamSetHandle paramSet, const char *name) + { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramEditBegin - " << paramSet << ' ' << name << " ..."; +# endif + SetInstance *setInstance = reinterpret_cast(paramSet); + if(!setInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = setInstance->editBegin(std::string(name)); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + + static OfxStatus paramEditEnd(OfxParamSetHandle paramSet) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << "OFX: paramEditEnd - " << paramSet << " ..."; +# endif + SetInstance *setInstance = reinterpret_cast(paramSet); + if(!setInstance) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + OfxStatus stat = setInstance->editEnd(); +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(stat) << std::endl; +# endif + return stat; + } + + static const OfxParameterSuiteV1 gParamSuiteV1 = { + paramDefine, + paramGetHandle, + paramSetGetPropertySet, + paramGetPropertySet, + paramGetValue, + paramGetValueAtTime, + paramGetDerivative, + paramGetIntegral, + paramSetValue, + paramSetValueAtTime, + paramGetNumKeys, + paramGetKeyTime, + paramGetKeyIndex, + paramDeleteKey, + paramDeleteAllKeys, + paramCopy, + paramEditBegin, + paramEditEnd + }; + + + const void *GetSuite(int version) { + if(version ==1) + return &gParamSuiteV1; + return NULL; + } + + } // Param + + } // Host + +} // OFX diff --git a/third_party/openfx/HostSupport/src/ofxhPluginAPICache.cpp b/third_party/openfx/HostSupport/src/ofxhPluginAPICache.cpp new file mode 100644 index 000000000..68d3b51f7 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhPluginAPICache.cpp @@ -0,0 +1,135 @@ + + +#include + +#include +#include + +// 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 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 << "getName()) + << XML::attribute("type", Property::gTypeNames[prop->getType()]) + << XML::attribute("dimension", prop->getFixedDimension()) + << ">\n"; + + for (int i=0;igetDimension();i++) { + o << indent << " getStringValue(i)) + << "/>\n"; + } + + o << indent << "\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); + } + } + + } + } +} diff --git a/third_party/openfx/HostSupport/src/ofxhPluginCache.cpp b/third_party/openfx/HostSupport/src/ofxhPluginCache.cpp new file mode 100644 index 000000000..5769639d1 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhPluginCache.cpp @@ -0,0 +1,694 @@ + + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#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 + +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 + +#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;ifindApiHandler(plug->pluginApi, plug->apiVersion); + assert(api); + + _plugins.push_back(api->newPlugin(this, i, plug)); + } + } +} + +PluginBinary::~PluginBinary() { + std::vector::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 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::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 &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;jgetNPlugins();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::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 foundBinFiles; + + for (std::list::iterator paths= _pluginPath.begin(); + paths != _pluginPath.end(); + paths++) { + scanDirectory(foundBinFiles, *paths, _nonrecursePath.find(*paths) == _nonrecursePath.end()); + } + + std::list::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;jgetNPlugins();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 &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 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;inewPlugin(_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 << "\n"; + for (std::list::const_iterator i=_binaries.begin();i!=_binaries.end();i++) { + PluginBinary *b = *i; + os << "\n"; + os << " getBundlePath()) + << XML::attribute("path", b->getFilePath()) + << XML::attribute("mtime", int(b->getFileModificationTime())) + << XML::attribute("size", int(b->getFileSize())) << "/>\n"; + + for (int j=0;jgetNPlugins();j++) { + Plugin *p = &b->getPlugin(j); + + + os << " 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 << " \n"; + api.saveXML(p, os); + os << " \n"; + + os << " \n"; + } + os << "\n"; + } + os << "\n"; +} + + +APICache::PluginAPICacheI *PluginCache::findApiHandler(const std::string &api, int version) { + std::list::iterator i = _apiHandlers.begin(); + while (i != _apiHandlers.end()) { + if (i->matches(api, version)) { + return i->handler; + } + i++; + } + return 0; +} diff --git a/third_party/openfx/HostSupport/src/ofxhPropertySuite.cpp b/third_party/openfx/HostSupport/src/ofxhPropertySuite.cpp new file mode 100644 index 000000000..e707206a4 --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhPropertySuite.cpp @@ -0,0 +1,1046 @@ + + +// ofx +#include "ofxCore.h" +#include "ofxImageEffect.h" + +// ofx host +#include "ofxhBinary.h" +#include "ofxhPropertySuite.h" +#include "ofxhUtilities.h" + +#include +#include + +namespace OFX { + namespace Host { + namespace Property { + + /// type holder, for integers + int IntValue::kEmpty = 0; + double DoubleValue::kEmpty = 0; + void *PointerValue::kEmpty = 0; + std::string StringValue::kEmpty; + const char *gTypeNames[] = {"int", "double", "string", "pointer" }; + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> int GetHook::getProperty(const std::string &name, int index) const + { + return getIntProperty(name, index); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> double GetHook::getProperty(const std::string &name, int index) const + { + return getDoubleProperty(name, index); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> void *GetHook::getProperty(const std::string &name, int index) const + { + return getPointerProperty(name, index); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> const std::string &GetHook::getProperty(const std::string &name, int index) const + { + return getStringProperty(name, index); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> void GetHook::getPropertyN(const std::string &name, int *values, int count) const + { + getIntPropertyN(name, values, count); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> void GetHook::getPropertyN(const std::string &name, double *values, int count) const + { + getDoublePropertyN(name, values, count); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> void GetHook::getPropertyN(const std::string &name, void **values, int count) const + { + getPointerPropertyN(name, values, count); + } + + /// this does some magic so that it calls get string/int/double/pointer appropriately + template<> void GetHook::getPropertyN(const std::string &name, const char **values, int count) const + { + getStringPropertyN(name, values, count); + } + + + /// override this to get a single value at the given index. + const std::string &GetHook::getStringProperty(const std::string &/*name*/, int /*index*/) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getStringProperty!!!! " << std::endl; +# endif + return StringValue::kEmpty; + } + + /// override this function to optimize multiple-string properties fetching + void GetHook::getStringPropertyN(const std::string &name, const char** values, int count) const + { + for (int i = 0; i < count; ++i) { + values[i] = getStringProperty(name, i).c_str(); + } + } + + /// override this to fetch a single value at the given index. + int GetHook::getIntProperty(const std::string &/*name*/, int /*index*/) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getIntProperty!!!! " << std::endl; +# endif + return 0; + } + + /// override this to fetch a single value at the given index. + double GetHook::getDoubleProperty(const std::string &/*name*/, int /*index*/) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getDoubleProperty!!!! " << std::endl; +# endif + return 0; + } + + /// override this to fetch a single value at the given index. + void *GetHook::getPointerProperty(const std::string &/*name*/, int /*index*/) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getPointerProperty!!!! " << std::endl; +# endif + return NULL; + } + + /// override this to fetch a multiple values in a multi-dimension property + void GetHook::getDoublePropertyN(const std::string &/*name*/, double *values, int count) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getDoublePropertyN!!!! " << std::endl; +# endif + memset(values, 0, sizeof(double) * count); + } + + /// override this to fetch a multiple values in a multi-dimension property + void GetHook::getIntPropertyN(const std::string &/*name*/, int *values, int count) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getIntPropertyN!!!! " << std::endl; +# endif + memset(values, 0, sizeof(int) * count); + } + + /// override this to fetch a multiple values in a multi-dimension property + void GetHook::getPointerPropertyN(const std::string &/*name*/, void **values, int count) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getPointerPropertyN!!!! " << std::endl; +# endif + memset(values, 0, sizeof(void *) * count); + } + + + /// override this to fetch the dimension size. + int GetHook::getDimension(const std::string &/*name*/) const + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::getDimension!!!! " << std::endl; +# endif + return 0; + } + + /// override this to handle a reset(). + void GetHook::reset(const std::string &/*name*/) + { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Calling un-overriden GetHook::reset!!!! " << std::endl; +# endif + } + + Property::Property(const std::string &name, + TypeEnum type, + int dimension, + bool pluginReadOnly) + : _name(name) + , _type(type) + , _dimension(dimension) + , _pluginReadOnly(pluginReadOnly) + , _getHook(0) + { + } + + Property::Property(const Property &other) + : _name(other._name) + , _type(other._type) + , _dimension(other._dimension) + , _pluginReadOnly(other._pluginReadOnly) + , _getHook(0) + { + } + + /// call notify on the contained notify hooks + void Property::notify(bool single, int indexOrN) + { + std::vector::iterator i; + for(i = _notifyHooks.begin(); i != _notifyHooks.end(); ++i) { + (*i)->notify(_name, single, indexOrN); + } + } + + inline int castToAPIType(int i) { return i; } + inline void *castToAPIType(void *v) { return v; } + inline double castToAPIType(double d) { return d; } + inline const char *castToAPIType(const std::string &s) { return s.c_str(); } + + template PropertyTemplate::PropertyTemplate(const std::string &name, + int dimension, + bool /*pluginReadOnly*/, + APIType defaultValue) + : Property(name, T::typeCode, dimension) + { + + if (dimension) { + _value.resize(dimension); + _defaultValue.resize(dimension); + } + + if (dimension) { + for (int i=0;i PropertyTemplate::PropertyTemplate(const PropertyTemplate &pt) + : Property(pt) + , _value(pt._value) + , _defaultValue(pt._defaultValue) + { + } + +#ifdef WINDOWS +#pragma warning( disable : 4181 ) +#endif + /// get one value + template + const typename T::ReturnType PropertyTemplate::getValue(int index) const + { + if (_getHook) { + return _getHook->getProperty(_name, index); + } + else { + return getValueRaw(index); + } + } +#ifdef WINDOWS +#pragma warning( default : 4181 ) +#endif + // get multiple values + template + void PropertyTemplate::getValueN(typename T::APIType *values, int count) const { + if (_getHook) { + _getHook->getPropertyN(_name, values, count); + } + else { + getValueNRaw(values, count); + } + } + +#ifdef WINDOWS +#pragma warning( disable : 4181 ) +#endif + /// get one value, without going through the getHook + template + const typename T::ReturnType PropertyTemplate::getValueRaw(int index) const + { + if (index < 0 || ((size_t)index >= _value.size())) { + throw Exception(kOfxStatErrBadIndex); + } + return _value[index]; + } +#ifdef WINDOWS +#pragma warning( default : 4181 ) +#endif + // get multiple values, without going through the getHook + template + void PropertyTemplate::getValueNRaw(APIType *value, int count) const + { + size_t size = count; + if (size > _value.size()) { + size = _value.size(); + } + + for (size_t i=0;i void PropertyTemplate::setValue(const typename T::Type &value, int index) + { + if (index < 0 || ((size_t)index > _value.size() && _dimension)) { + throw Exception(kOfxStatErrBadIndex); + } + + if (_value.size() <= (size_t)index) { + _value.resize(index+1); + } + _value[index] = value; + + notify(true, index); + } + + /// set multiple values + template void PropertyTemplate::setValueN(const typename T::APIType *value, int count) + { + if (_dimension && ((size_t)count > _value.size())) { + throw Exception(kOfxStatErrBadIndex); + } + if (_value.size() != (size_t)count) { + _value.resize(count); + } + for (int i=0;i int PropertyTemplate::getDimension() const { + if (_dimension != 0) { + return _dimension; + } + else { + // code to get it from the hook + if (_getHook) { + return _getHook->getDimension(_name); + } + else { + return (int)_value.size(); + } + } + } + + template void PropertyTemplate::reset() + { + if (_getHook) { + _getHook->reset(_name); + int dim = getDimension(); + + if(!isFixedSize()) { + _value.resize(dim); + } + for(int i = 0; i < dim; ++i) { + _value[i] = _getHook->getProperty(_name, i); + } + } + else { + if(isFixedSize()) { + _value = _defaultValue; + } + else { + _value.resize(0); + } + + // now notify on a reset + notify(false, _dimension); + } + } + + // explicit instanciations (required by ofxhPluginAPICache.cpp) + template class PropertyTemplate; + template class PropertyTemplate; + template class PropertyTemplate; + template class PropertyTemplate; + + inline int castAwayConst(int i) { return i; } + inline double castAwayConst(double d) { return d; } + inline void *castAwayConst(void *v) { return v; } + inline char *castAwayConst(const char *s) { return const_cast(s); } + + inline int *castToConst(int *i) { return i; } + inline double *castToConst(double *d) { return d; } + inline const char **castToConst(char **s) { return const_cast(s); } + inline void **castToConst(void **v) { return v; } + + + void Set::setGetHook(const std::string &s, GetHook *ghook) const + { + Property *prop = fetchProperty(s); + + if(prop) { + prop->setGetHook(ghook); + } + } + + + /// add a notify hook for a particular property. users may need to call particular + /// specialised versions of this. + void Set::addNotifyHook(const std::string &s, NotifyHook *hook) const + { + Property *prop = fetchProperty(s); + + if(prop) { + prop->addNotifyHook(hook); + } + } + + Property *Set::fetchProperty(const std::string&name, bool followChain) const + { + PropertyMap::const_iterator i = _props.find(name); + if (i == _props.end()) { + if(followChain && _chainedSet) { + return _chainedSet->fetchProperty(name, true); + } + return NULL; + } + return i->second; + } + + template bool Set::fetchTypedProperty(const std::string&name, T *&prop, bool followChain) const + { + Property *myprop = fetchProperty(name, followChain); + + if(!myprop) + return false; + + prop = dynamic_cast(myprop); + if (prop == 0) { + return false; + } + return true; + } + + String *Set::fetchStringProperty(const std::string &name, bool followChain) const { + String *p; + if (fetchTypedProperty(name, p, followChain)) { + return p; + } + return NULL; + } + + Int *Set::fetchIntProperty(const std::string &name, bool followChain) const { + Int *p; + if (fetchTypedProperty(name, p, followChain)) { + return p; + } + return NULL; + } + + Pointer *Set::fetchPointerProperty(const std::string &name, bool followChain) const { + Pointer *p; + if (fetchTypedProperty(name, p, followChain)) { + return p; + } + return NULL; + } + + Double *Set::fetchDoubleProperty(const std::string &name, bool followChain) const { + Double *p; + if (fetchTypedProperty(name, p, followChain)) { + return p; + } + return NULL; + } + + /// add one new property + void Set::createProperty(const PropSpec &spec) + { + if (_props.find(spec.name) != _props.end()) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: Tried to add a duplicate property to a Property::Set: " << spec.name << std::endl; +# endif + return; + } + + switch (spec.type) { + case eInt: + _props[spec.name] = new Int(spec.name, spec.dimension, spec.readonly, spec.defaultValue?atoi(spec.defaultValue):0); + break; + case eDouble: + _props[spec.name] = new Double(spec.name, spec.dimension, spec.readonly, spec.defaultValue?atof(spec.defaultValue):0); + break; + case eString: + _props[spec.name] = new String(spec.name, spec.dimension, spec.readonly, spec.defaultValue?spec.defaultValue:""); + break; + case ePointer: + _props[spec.name] = new Pointer(spec.name, spec.dimension, spec.readonly, (void*)spec.defaultValue); + break; + default: // XXX error - unrecognised type + break; + } + } + + void Set::addProperties(const PropSpec spec[]) + { + while (spec->name) { + createProperty(*spec); + spec++; + } + } + + /// add one new property + void Set::addProperty(Property *prop) + { + PropertyMap::iterator t = _props.find(prop->getName()); + if(t != _props.end()) + delete t->second; + _props[prop->getName()] = prop; + } + + /// empty ctor + Set::Set() + : _magic(kMagic) + , _chainedSet(NULL) + { + } + + Set::Set(const PropSpec spec[]) + : _magic(kMagic) + , _chainedSet(NULL) + { + addProperties(spec); + } + + Set::Set(const Set &other) + : _magic(kMagic) + , _chainedSet(NULL) + { + bool failed = false; + + for (std::map::const_iterator i = other._props.begin(); + i != other._props.end(); + i++) + { + Property *copyProp = i->second->deepCopy(); + if (!copyProp) { + failed = true; + break; + } + _props[i->first] = copyProp; + } + + if (failed) + + for (std::map::iterator j = _props.begin(); + j != _props.end(); + j++) { + delete j->second; + } + + } + + Set::~Set() + { + std::map::iterator i = _props.begin(); + while (i != _props.end()) { + delete i->second; + i++; + } + } + + /// set a particular property + template void Set::setProperty(const std::string &property, int index, const typename T::Type &value) + { + try { + PropertyTemplate *prop = 0; + if(fetchTypedProperty(property, prop)) { + prop->setValue(value, index); + } + else { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: setProperty " << property << "[" << index << "] ignored because host property not defined" << std::endl; +# endif + } + } + catch(...) {} + } + + /// set a particular property + template void Set::setPropertyN(const std::string &property, int count, const typename T::APIType *value) + { + try { + PropertyTemplate *prop = 0; + if(fetchTypedProperty(property, prop)) { + prop->setValueN(value, count); + } + else { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: setPropertyN " << property << " ignored because host property not defined" << std::endl; +# endif + } + } + catch(...) {} + } + + /// get a particular property + template typename T::ReturnType Set::getProperty(const std::string &property, int index) const + { + try { + PropertyTemplate *prop; + if(fetchTypedProperty(property, prop, true)) { + return prop->getValue(index); + } + } + catch(...) {} + return T::kEmpty; + } + + /// get a particular property + template void Set::getPropertyN(const std::string &property, int count, typename T::APIType *value) const + { + try { + PropertyTemplate *prop; + if(fetchTypedProperty(property, prop, true)) { + return prop->getValueN(value, count); + } + } + catch(...) {} + } + + /// get a particular property + template typename T::ReturnType Set::getPropertyRaw(const std::string &property, int index) const + { + try { + PropertyTemplate *prop; + if(fetchTypedProperty(property, prop, true)) { + return prop->getValueRaw(index); + } + } + catch(...) {} + return T::kEmpty; + } + + /// get a particular property + template void Set::getPropertyRawN(const std::string &property, int count, typename T::APIType *value) const + { + try { + PropertyTemplate *prop; + if(fetchTypedProperty(property, prop, true)) { + return prop->getValueNRaw(value, count); + } + } + catch(...) {} + } + + /// get a particular int property + int Set::getIntPropertyRaw(const std::string &property, int index) const + { + return getPropertyRaw(property, index); + } + + /// get a particular double property + double Set::getDoublePropertyRaw(const std::string &property, int index) const + { + return getPropertyRaw(property, index); + } + + /// get a particular double property + void *Set::getPointerPropertyRaw(const std::string &property, int index) const + { + return getPropertyRaw(property, index); + } + + /// get a particular double property + const std::string &Set::getStringPropertyRaw(const std::string &property, int index) const + { + String *prop; + if(fetchTypedProperty(property, prop, true)) { + return prop->getValueRaw(index); + } + return StringValue::kEmpty; + } + + /// get a particular int property + int Set::getIntProperty(const std::string &property, int index) const + { + return getProperty(property, index); + } + + /// get the value of a particular double property + void Set::getIntPropertyN(const std::string &property, int *v, int N) const + { + return getPropertyN(property, N, v); + } + + /// get a particular double property + double Set::getDoubleProperty(const std::string &property, int index) const + { + return getProperty(property, index); + } + + /// get the value of a particular double property + void Set::getDoublePropertyN(const std::string &property, double *v, int N) const + { + return getPropertyN(property, N, v); + } + + /// get a particular double property + void *Set::getPointerProperty(const std::string &property, int index) const + { + return getProperty(property, index); + } + + /// get a particular double property + const std::string &Set::getStringProperty(const std::string &property, int index) const + { + return getProperty(property, index); + } + + /// set a particular string property + void Set::setStringProperty(const std::string &property, const std::string &value, int index) + { + setProperty(property, index, value); + } + + /// get a particular int property + void Set::setIntProperty(const std::string &property, int v, int index) + { + setProperty(property, index, v); + } + + /// get a particular double property + void Set::setIntPropertyN(const std::string &property, const int *v, int N) + { + setPropertyN(property, N, v); + } + + /// get a particular double property + void Set::setDoubleProperty(const std::string &property, double v, int index) + { + setProperty(property, index, v); + } + + /// get a particular double property + void Set::setDoublePropertyN(const std::string &property, const double *v, int N) + { + setPropertyN(property, N, v); + } + + /// get a particular double property + void Set::setPointerProperty(const std::string &property, void *v, int index) + { + setProperty(property, index, v); + } + + /// get the dimension of a particular property + int Set::getDimension(const std::string &property) const + { + Property *prop = 0; + if(fetchTypedProperty(property, prop, true)) { + return prop->getDimension(); + } + return 0; + } + + /// 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 Set::findStringPropValueIndex(const std::string &propName, + const std::string &propValue) const + { + String *prop = fetchStringProperty(propName, true); + + if(prop) { + const std::vector &values = prop->getValues(); + std::vector::const_iterator i = find(values.begin(), values.end(), propValue); + if(i != values.end()) { + return int(i - values.begin()); + } + } + return -1; + } + + /// static functions for the suite + template static OfxStatus propSet(OfxPropertySetHandle properties, + const char *property, + int index, + typename T::APIType value) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propSet - " << properties << ' ' << property << "[" << index << "] = " << value << " ..."; +# endif + try { + Set *thisSet = reinterpret_cast(properties); + if(!thisSet || !thisSet->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + PropertyTemplate *prop = 0; + if(!thisSet->fetchTypedProperty(property, prop, false)) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propSet " << property << "[" << index << "] ignored because effect property not defined" << std::endl; + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + prop->setValue(value, index); + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } + + /// static functions for the suite + template static OfxStatus propSetN(OfxPropertySetHandle properties, + const char *property, + int count, + const typename T::APIType *values) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propSetN - " << properties << ' ' << property << "[0.." << count-1 << "] = "; + for (int i = 0; i < count; ++i) { + if (i != 0) { + std::cout << ','; + } + std::cout << values[i]; + } +# endif + try { + Set *thisSet = reinterpret_cast(properties); + if(!thisSet || !thisSet->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + PropertyTemplate *prop = 0; + if(!thisSet->fetchTypedProperty(property, prop, false)) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propSetN " << property << " ignored because effect property not defined" << std::endl; + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + prop->setValueN(values, count); + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } + + /// static functions for the suite + template static OfxStatus propGet(OfxPropertySetHandle properties, + const char *property, + int index, + typename T::APITypeConstless *value) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propGet - " << properties << ' ' << property << "[" << index << "] = ..."; +# endif + try { + Set *thisSet = reinterpret_cast(properties); + if(!thisSet || !thisSet->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + PropertyTemplate *prop = 0; + if(!thisSet->fetchTypedProperty(property, prop, true)) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + *value = castAwayConst(castToAPIType(prop->getValue(index))); + +# ifdef OFX_DEBUG_PROPERTIES + std::cout << *value << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + return kOfxStatOK; + } + + /// static functions for the suite + template static OfxStatus propGetN(OfxPropertySetHandle properties, + const char *property, + int count, + typename T::APITypeConstless *values) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propGetN - " << properties << ' ' << property << "[0.." << count-1 << "] = ..."; +# endif + try { + Set *thisSet = reinterpret_cast(properties); + if(!thisSet || !thisSet->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + PropertyTemplate *prop = 0; + if(!thisSet->fetchTypedProperty(property, prop, true)) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + prop->getValueN(castToConst(values), count); +# ifdef OFX_DEBUG_PROPERTIES + for (int i = 0; i < count; ++i) { + if (i != 0) { + std::cout << ','; + } + std::cout << values[i]; + } + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + return kOfxStatOK; + } + + /// static functions for the suite + static OfxStatus propReset(OfxPropertySetHandle properties, const char *property) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propReset - " << properties << ' ' << property << " ..."; +# endif + try { + Set *thisSet = reinterpret_cast(properties); + if(!thisSet || !thisSet->verifyMagic()) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + Property *prop = thisSet->fetchProperty(property, false); + if(!prop) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + prop->reset(); +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + return kOfxStatOK; + } + + /// static functions for the suite + static OfxStatus propGetDimension(OfxPropertySetHandle properties, const char *property, int *count) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "OFX: propGetDimension - " << properties << ' ' << property << " ..."; +# endif + if (!properties) { +# ifdef OFX_DEBUG_PARAMETERS + std::cout << ' ' << StatStr(kOfxStatErrBadHandle) << std::endl; +# endif + return kOfxStatErrBadHandle; + } + try { + Set *thisSet = reinterpret_cast(properties); + Property *prop = thisSet->fetchProperty(property, true); + if(!prop) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << "unknown property\n"; +# endif + return kOfxStatErrUnknown; + } + *count = prop->getDimension(); +# ifdef OFX_DEBUG_PROPERTIES + std::cout << *count << ' ' << StatStr(kOfxStatOK) << std::endl; +# endif + return kOfxStatOK; + } catch (const Exception& e) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(e.getStatus()) << std::endl; +# endif + return e.getStatus(); + } catch (...) { +# ifdef OFX_DEBUG_PROPERTIES + std::cout << ' ' << StatStr(kOfxStatErrUnknown) << std::endl; +# endif + return kOfxStatErrUnknown; + } + } + + /// the actual suite that is passed across the API to manage properties + struct OfxPropertySuiteV1 gSuite = { + propSet, + propSet, + propSet, + propSet, + propSetN, + propSetN, + propSetN, + propSetN, + propGet, + propGet, + propGet, + propGet, + propGetN, + propGetN, + propGetN, + propGetN, + propReset, + propGetDimension + }; + + /// return the OFX function suite that manages properties + const void *GetSuite(int version) + { + if(version == 1) + return (void *)(&gSuite); + return NULL; + } + + } + } +} diff --git a/third_party/openfx/HostSupport/src/ofxhUtilities.cpp b/third_party/openfx/HostSupport/src/ofxhUtilities.cpp new file mode 100644 index 000000000..e3d33ba7c --- /dev/null +++ b/third_party/openfx/HostSupport/src/ofxhUtilities.cpp @@ -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. + } + } + +} diff --git a/third_party/openfx/Support/CMakeLists.txt b/third_party/openfx/Support/CMakeLists.txt new file mode 100644 index 000000000..4c09b1897 --- /dev/null +++ b/third_party/openfx/Support/CMakeLists.txt @@ -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() diff --git a/third_party/openfx/Support/LICENSE b/third_party/openfx/Support/LICENSE new file mode 100644 index 000000000..6f3b8f093 --- /dev/null +++ b/third_party/openfx/Support/LICENSE @@ -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. diff --git a/third_party/openfx/Support/Library/.gdb_history b/third_party/openfx/Support/Library/.gdb_history new file mode 100644 index 000000000..b98ddf17a --- /dev/null +++ b/third_party/openfx/Support/Library/.gdb_history @@ -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 diff --git a/third_party/openfx/Support/Library/CMakeLists.txt b/third_party/openfx/Support/Library/CMakeLists.txt new file mode 100644 index 000000000..7f3dcbcf2 --- /dev/null +++ b/third_party/openfx/Support/Library/CMakeLists.txt @@ -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}) diff --git a/third_party/openfx/Support/Library/ofxSupport.dsp b/third_party/openfx/Support/Library/ofxSupport.dsp new file mode 100755 index 000000000..4f8b3b9dc --- /dev/null +++ b/third_party/openfx/Support/Library/ofxSupport.dsp @@ -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 diff --git a/third_party/openfx/Support/Library/ofxsCore.cpp b/third_party/openfx/Support/Library/ofxsCore.cpp new file mode 100644 index 000000000..65da7050d --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsCore.cpp @@ -0,0 +1,113 @@ + + +#include "ofxsSupportPrivate.h" +#ifdef DEBUG +#include +#if defined(__APPLE__) || defined(linux) +#include +#include +#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 + diff --git a/third_party/openfx/Support/Library/ofxsImageEffect.cpp b/third_party/openfx/Support/Library/ofxsImageEffect.cpp new file mode 100644 index 000000000..62599800e --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsImageEffect.cpp @@ -0,0 +1,3078 @@ + + +/** @brief This file contains code that skins the ofx effect suite */ + +#include "ofxsSupportPrivate.h" +#include // for find +#include // for strlen +#ifdef DEBUG +#include +#endif +#include +#include "ofxGPURender.h" +#include "ofxsCore.h" + +#if defined __APPLE__ || defined __linux__ || defined __FreeBSD__ +# if __GNUC__ >= 4 +# define EXPORT __attribute__((visibility("default"))) +# define LOCAL __attribute__((visibility("hidden"))) +# else +# define EXPORT +# define LOCAL +# endif +#elif defined _WIN32 +# define EXPORT OfxExport +# define LOCAL +#else +# error Not building on your operating system quite yet +#endif + +// string utility functions +static bool ends_with(std::string const & value, std::string const & ending) +{ + if (ending.size() > value.size()) return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +static bool starts_with(std::string const & value, std::string const & beginning) +{ + if (beginning.size() > value.size()) return false; + return std::equal(beginning.begin(), beginning.end(), value.begin()); +} + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. */ +namespace OFX { + + // globals to keep consistent data structures around. + OFX::PluginFactoryArray plugIDs; + //Put it all into a map, so we know when to delete what! + struct OfxPlugInfo + { + OfxPlugInfo() = default; + OfxPlugInfo(OFX::PluginFactory* f, std::unique_ptr p):_factory(f), _plug(std::move(p)){} + OFX::PluginFactory* _factory = nullptr; + std::unique_ptr _plug; + }; + typedef std::map OfxPlugInfoMap; + OfxPlugInfoMap plugInfoMap; + + typedef std::vector OfxPluginArray; + OfxPluginArray ofxPlugs; + + /** @brief the global host description */ + ImageEffectHostDescription gHostDescription; + bool gHostDescriptionHasInit = false; + + bool ImageEffectHostDescription::supportsPixelComponent(const PixelComponentEnum component) const + { + return std::find(_supportedComponents.begin(), _supportedComponents.end(), component) != _supportedComponents.end(); + } + bool ImageEffectHostDescription::supportsBitDepth( const BitDepthEnum bitDepth) const + { + return std::find(_supportedPixelDepths.begin(), _supportedPixelDepths.end(), bitDepth) != _supportedPixelDepths.end(); + } + bool ImageEffectHostDescription::supportsContext(const ContextEnum context) const + { + return std::find(_supportedContexts.begin(), _supportedContexts.end(), context) != _supportedContexts.end(); + } + + /** @return default pixel depth supported by host application. */ + BitDepthEnum ImageEffectHostDescription::getDefaultPixelDepth() const + { + if(!_supportedPixelDepths.empty()) { + return _supportedPixelDepths[0]; + } else { + OFX::Log::warning(true, "The host doesn't define supported pixel depth. (size: %d)", (int)_supportedPixelDepths.size()); + return eBitDepthFloat; + } + } + + /** @return default pixel component supported by host application. */ + PixelComponentEnum ImageEffectHostDescription::getDefaultPixelComponent() const + { + if(! _supportedComponents.empty()) { + return _supportedComponents[0]; + } else { + OFX::Log::warning(true, "The host doesn't define supported pixel component. (size: %d)", _supportedComponents.size()); + return ePixelComponentRGBA; + } + } + + ImageEffectHostDescription* getImageEffectHostDescription() + { + if(gHostDescriptionHasInit) + return &gHostDescription; + return NULL; + } + + namespace Private { + // Suite and host pointers + OfxHost *gHost = 0; + OfxImageEffectSuiteV1 *gEffectSuite = 0; + OfxPropertySuiteV1 *gPropSuite = 0; + OfxInteractSuiteV1 *gInteractSuite = 0; + OfxParameterSuiteV1 *gParamSuite = 0; + OfxMemorySuiteV1 *gMemorySuite = 0; + OfxMultiThreadSuiteV1 *gThreadSuite = 0; + OfxMessageSuiteV1 *gMessageSuite = 0; + OfxMessageSuiteV2 *gMessageSuiteV2 = 0; + OfxProgressSuiteV1 *gProgressSuiteV1 = 0; + OfxProgressSuiteV2 *gProgressSuiteV2 = 0; + OfxTimeLineSuiteV1 *gTimeLineSuite = 0; + OfxParametricParameterSuiteV1 *gParametricParameterSuite = 0; +#ifdef OFX_SUPPORTS_OPENGLRENDER + OfxImageEffectOpenGLRenderSuiteV1 *gOpenGLRenderSuite = 0; +#endif + + // @brief the set of descriptors, one per context used by kOfxActionDescribeInContext, + //'eContextNone' is the one used by the kOfxActionDescribe + EffectDescriptorMap gEffectDescriptors; + }; + + /** @brief map a std::string to a context */ + ContextEnum mapToContextEnum(const std::string &s) + { + if(s == kOfxImageEffectContextGenerator) return eContextGenerator; + if(s == kOfxImageEffectContextFilter) return eContextFilter; + if(s == kOfxImageEffectContextTransition) return eContextTransition; + if(s == kOfxImageEffectContextPaint) return eContextPaint; + if(s == kOfxImageEffectContextGeneral) return eContextGeneral; + if(s == kOfxImageEffectContextRetimer) return eContextRetimer; + OFX::Log::error(true, "Unknown image effect context '%s'", s.c_str()); + throw std::invalid_argument(s); + } + + const char* mapContextEnumToStr(ContextEnum context) + { + switch (context) { + case eContextGenerator: + return kOfxImageEffectContextGenerator; + case eContextFilter: + return kOfxImageEffectContextFilter; + case eContextTransition: + return kOfxImageEffectContextTransition; + case eContextPaint: + return kOfxImageEffectContextPaint; + case eContextGeneral: + return kOfxImageEffectContextGeneral; + case eContextRetimer: + return kOfxImageEffectContextRetimer; + default: + OFX::Log::error(true, "Unknown context enum '%d'", (int)context); + throw std::invalid_argument("unknown ContextEnum"); + } + } + + const char* mapMessageTypeEnumToStr(OFX::Message::MessageTypeEnum type) + { + if(type == OFX::Message::eMessageFatal) + return kOfxMessageFatal; + else if(type == OFX::Message::eMessageError) + return kOfxMessageError; + else if(type == OFX::Message::eMessageMessage) + return kOfxMessageMessage; + else if(type == OFX::Message::eMessageWarning) + return kOfxMessageWarning; + else if(type == OFX::Message::eMessageLog) + return kOfxMessageLog; + else if(type == OFX::Message::eMessageQuestion) + return kOfxMessageQuestion; + OFX::Log::error(true, "Unknown message type enum '%d'", type); + return 0; + } + + OFX::Message::MessageReplyEnum mapToMessageReplyEnum(OfxStatus stat) + { + if(stat == kOfxStatOK) + return OFX::Message::eMessageReplyOK; + else if(stat == kOfxStatReplyYes) + return OFX::Message::eMessageReplyYes; + else if(stat == kOfxStatReplyNo) + return OFX::Message::eMessageReplyNo; + else if(stat == kOfxStatFailed) + return OFX::Message::eMessageReplyFailed; + OFX::Log::error(true, "Unknown message reply status enum '%d'", stat); + return OFX::Message::eMessageReplyFailed; + } + + /** @brief map a std::string to a context */ + InstanceChangeReason mapToInstanceChangedReason(const std::string &s) + { + if(s == kOfxChangePluginEdited) return eChangePluginEdit; + if(s == kOfxChangeUserEdited) return eChangeUserEdit; + if(s == kOfxChangeTime) return eChangeTime; + OFX::Log::error(true, "Unknown instance changed reason '%s'", s.c_str()); + throw std::invalid_argument(s); + } + + /** @brief turns a bit depth string into and enum */ + BitDepthEnum mapStrToBitDepthEnum(const std::string &str) + { + if(str == kOfxBitDepthByte) { + return eBitDepthUByte; + } + else if(str == kOfxBitDepthShort) { + return eBitDepthUShort; + } + else if(str == kOfxBitDepthHalf) { + return eBitDepthHalf; + } + else if(str == kOfxBitDepthFloat) { + return eBitDepthFloat; + } + else if(str == kOfxBitDepthNone) { + return eBitDepthNone; + } + else { + return eBitDepthCustom; + } + } + + /** @brief turns a bit depth string into and enum */ + const char* mapBitDepthEnumToStr(BitDepthEnum bitDepth) + { + switch (bitDepth) { + case eBitDepthUByte: + return kOfxBitDepthByte; + case eBitDepthUShort: + return kOfxBitDepthShort; + case eBitDepthHalf: + return kOfxBitDepthHalf; + case eBitDepthFloat: + return kOfxBitDepthFloat; + case eBitDepthNone: + return kOfxBitDepthNone; + case eBitDepthCustom: + return "OfxBitDepthCustom"; + default: + OFX::Log::error(true, "Unknown bit depth enum '%d'", (int)bitDepth); + throw std::invalid_argument("unknown BitDepthEnum"); + } + } + + /** @brief turns a pixel component string into and enum */ + PixelComponentEnum mapStrToPixelComponentEnum(const std::string &str) + { + if(str == kOfxImageComponentRGBA) { + return ePixelComponentRGBA; + } + else if(str == kOfxImageComponentRGB) { + return ePixelComponentRGB; + } + else if(str == kOfxImageComponentAlpha) { + return ePixelComponentAlpha; + } + else if(str == kOfxImageComponentNone) { + return ePixelComponentNone; + } + else { + return ePixelComponentCustom; + } + } + + /** @brief turns a pixel component string into and enum */ + const char* mapPixelComponentEnumToStr(PixelComponentEnum pixelComponent) + { + switch (pixelComponent) { + case ePixelComponentRGBA: + return kOfxImageComponentRGBA; + case ePixelComponentRGB: + return kOfxImageComponentRGB; + case ePixelComponentAlpha: + return kOfxImageComponentAlpha; + case ePixelComponentCustom: + return "OfxImageComponentCustom"; + default: + OFX::Log::error(true, "Unknown pixel component enum '%d'", (int)pixelComponent); + throw std::invalid_argument("unknown PixelComponentEnum"); + } + } + + /** @brief turns a premultiplication string into and enum */ + static PreMultiplicationEnum mapStrToPreMultiplicationEnum(const std::string &str) + { + if(str == kOfxImageOpaque) { + return eImageOpaque; + } + else if(str == kOfxImagePreMultiplied) { + return eImagePreMultiplied; + } + else if(str == kOfxImageUnPreMultiplied) { + return eImageUnPreMultiplied; + } + else { + throw std::invalid_argument(""); + } + } + + /** @brief turns a field string into and enum */ + FieldEnum mapStrToFieldEnum(const std::string &str) + { + if(str == kOfxImageFieldNone) { + return eFieldNone; + } + else if(str == kOfxImageFieldBoth) { + return eFieldBoth; + } + else if(str == kOfxImageFieldLower) { + return eFieldLower; + } + else if(str == kOfxImageFieldUpper) { + return eFieldUpper; + } + else { + throw std::invalid_argument(""); + } + } + + + //////////////////////////////////////////////////////////////////////////////// + // clip descriptor + + /** @brief hidden constructor */ + ClipDescriptor::ClipDescriptor(const std::string &name, OfxPropertySetHandle props) + : _clipName(name) + , _clipProps(props) + { + OFX::Validation::validateClipDescriptorProperties(props); + } + + /** @brief set the label properties */ + void ClipDescriptor::setLabel(const std::string &label) + { + _clipProps.propSetString(kOfxPropLabel, label); + } + + /** @brief set the label properties */ + void ClipDescriptor::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel) + { + setLabel(label); + _clipProps.propSetString(kOfxPropShortLabel, shortLabel, false); + _clipProps.propSetString(kOfxPropLongLabel, longLabel, false); + } + + /** @brief set how fielded images are extracted from the clip defaults to eFieldExtractDoubled */ + void ClipDescriptor::setFieldExtraction(FieldExtractionEnum v) + { + switch(v) + { + case eFieldExtractBoth : + _clipProps.propSetString(kOfxImageClipPropFieldExtraction, kOfxImageFieldBoth); + break; + + case eFieldExtractSingle : + _clipProps.propSetString(kOfxImageClipPropFieldExtraction, kOfxImageFieldSingle); + break; + + case eFieldExtractDoubled : + _clipProps.propSetString(kOfxImageClipPropFieldExtraction, kOfxImageFieldDoubled); + break; + } + } + + /** @brief set which components are supported, defaults to none set, this must be called at least once! */ + void ClipDescriptor::addSupportedComponent(PixelComponentEnum v) + { + int n = _clipProps.propGetDimension(kOfxImageEffectPropSupportedComponents); + switch(v) + { + case ePixelComponentNone : + _clipProps.propSetString(kOfxImageEffectPropSupportedComponents, kOfxImageComponentNone, n); + break; + + case ePixelComponentRGBA : + _clipProps.propSetString(kOfxImageEffectPropSupportedComponents, kOfxImageComponentRGBA, n); + break; + + case ePixelComponentRGB : + _clipProps.propSetString(kOfxImageEffectPropSupportedComponents, kOfxImageComponentRGB, n); + break; + + case ePixelComponentAlpha : + _clipProps.propSetString(kOfxImageEffectPropSupportedComponents, kOfxImageComponentAlpha, n); + break; + case ePixelComponentCustom : + break; + } + } + + /** @brief set which components are supported, defaults to none set, this must be called at least once! */ + void ClipDescriptor::addSupportedComponent(const std::string &comp) + { + int n = _clipProps.propGetDimension(kOfxImageEffectPropSupportedComponents); + _clipProps.propSetString(kOfxImageEffectPropSupportedComponents, comp, n); + + } + + /** @brief say whether we are going to do random temporal access on this clip, defaults to false */ + void ClipDescriptor::setTemporalClipAccess(bool v) + { + _clipProps.propSetInt(kOfxImageEffectPropTemporalClipAccess, int(v)); + } + + /** @brief say whether if the clip is optional, defaults to false */ + void ClipDescriptor::setOptional(bool v) + { + _clipProps.propSetInt(kOfxImageClipPropOptional, int(v)); + } + + /** @brief say whether this clip supports tiling, defaults to true */ + void ClipDescriptor::setSupportsTiles(bool v) + { + _clipProps.propSetInt(kOfxImageEffectPropSupportsTiles, int(v)); + } + + /** @brief say whether this clip is a 'mask', so the host can know to replace with a roto or similar, defaults to false */ + void ClipDescriptor::setIsMask(bool v) + { + _clipProps.propSetInt(kOfxImageClipPropIsMask, int(v)); + } + + //////////////////////////////////////////////////////////////////////////////// + // image effect descriptor + + /** @brief effect descriptor ctor */ + ImageEffectDescriptor::ImageEffectDescriptor(OfxImageEffectHandle handle) + : _effectHandle(handle) + { + // fetch the property set handle of the effect + OfxPropertySetHandle props; + OfxStatus stat = OFX::Private::gEffectSuite->getPropertySet(handle, &props); + throwSuiteStatusException(stat); + _effectProps.propSetHandle(props); + + OFX::Validation::validatePluginDescriptorProperties(props); + + // fetch the param set handle and set it in our ParamSetDescriptor base + OfxParamSetHandle paramSetHandle; + stat = OFX::Private::gEffectSuite->getParamSet(handle, ¶mSetHandle); + throwSuiteStatusException(stat); + setParamSetHandle(paramSetHandle); + } + + + /** @brief dtor */ + ImageEffectDescriptor::~ImageEffectDescriptor() + { + // delete any clip descriptors we may have constructed + std::map::iterator iter; + for(iter = _definedClips.begin(); iter != _definedClips.end(); ++iter) { + if(iter->second) { + delete iter->second; + iter->second = NULL; + } + } + } + + /** @brief, set the label properties in a plugin */ + void ImageEffectDescriptor::setLabel(const std::string &label) + { + _effectProps.propSetString(kOfxPropLabel, label); + } + + /** @brief, set the label properties in a plugin */ + void ImageEffectDescriptor::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel) + { + setLabel(label); + _effectProps.propSetString(kOfxPropShortLabel, shortLabel, false); + _effectProps.propSetString(kOfxPropLongLabel, longLabel, false); + } + + + /** @brief, set the version properties in a plugin */ + void ImageEffectDescriptor::setVersion(int major, int minor, int micro, int build, const std::string &versionLabel) + { + _effectProps.propSetInt(kOfxPropVersion, major, 0, false); // introduced in OFX 1.2 + if (minor || micro || build) { + _effectProps.propSetInt(kOfxPropVersion, minor, 1, false); // introduced in OFX 1.2 + if (micro || build) { + _effectProps.propSetInt(kOfxPropVersion, micro, 2, false); // introduced in OFX 1.2 + if (build) { + _effectProps.propSetInt(kOfxPropVersion, build, 3, false); // introduced in OFX 1.2 + } + } + } + if (!versionLabel.empty()) { + _effectProps.propSetString(kOfxPropVersionLabel, versionLabel, false); + } + } + + /** @brief Set the plugin grouping */ + void ImageEffectDescriptor::setPluginGrouping(const std::string &group) + { + _effectProps.propSetString(kOfxImageEffectPluginPropGrouping, group); + } + + /** @brief Set the plugin description, defaults to "" */ + void ImageEffectDescriptor::setPluginDescription(const std::string &description) + { + _effectProps.propSetString(kOfxPropPluginDescription, description, false); // introduced in OFX 1.2 + } + + /** @brief Add a context to those supported */ + void ImageEffectDescriptor::addSupportedContext(ContextEnum v) + { + int n = _effectProps.propGetDimension(kOfxImageEffectPropSupportedContexts); + switch (v) + { + case eContextNone : + break; + case eContextGenerator : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextGenerator, n); + break; + case eContextFilter : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextFilter, n); + break; + case eContextTransition : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextTransition, n); + break; + case eContextPaint : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextPaint, n); + break; + case eContextGeneral : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextGeneral, n); + break; + case eContextRetimer : + _effectProps.propSetString(kOfxImageEffectPropSupportedContexts, kOfxImageEffectContextRetimer, n); + break; + } + } + + void ImageEffectDescriptor::setOverlayInteractDescriptor(EffectOverlayDescriptor* desc) + { + _overlayDescriptor.reset(desc); + if(OFX::gHostDescription.supportsOverlays && desc->getMainEntry()) + _effectProps.propSetPointer(kOfxImageEffectPluginPropOverlayInteractV1, (void*)desc->getMainEntry()); + } + + /** @brief Add a pixel depth to those supported */ + void ImageEffectDescriptor::addSupportedBitDepth(BitDepthEnum v) + { + int n = _effectProps.propGetDimension(kOfxImageEffectPropSupportedPixelDepths); + switch(v) + { + case eBitDepthNone : + _effectProps.propSetString(kOfxImageEffectPropSupportedPixelDepths, kOfxBitDepthNone , n); + break; + case eBitDepthUByte : + _effectProps.propSetString(kOfxImageEffectPropSupportedPixelDepths, kOfxBitDepthByte , n); + break; + case eBitDepthUShort : + _effectProps.propSetString(kOfxImageEffectPropSupportedPixelDepths, kOfxBitDepthShort , n); + break; + case eBitDepthHalf : + _effectProps.propSetString(kOfxImageEffectPropSupportedPixelDepths, kOfxBitDepthHalf , n); + break; + case eBitDepthFloat : + _effectProps.propSetString(kOfxImageEffectPropSupportedPixelDepths, kOfxBitDepthFloat , n); + break; + case eBitDepthCustom : + break; + } + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief Add a pixel depth to those supported */ + void ImageEffectDescriptor::addSupportedOpenGLBitDepth(BitDepthEnum v) + { + int n = _effectProps.propGetDimension(kOfxOpenGLPropPixelDepth); + switch(v) + { + case eBitDepthNone : + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, kOfxBitDepthNone , n); + break; + case eBitDepthUByte : + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, kOfxBitDepthByte , n); + break; + case eBitDepthUShort : + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, kOfxBitDepthShort , n); + break; + case eBitDepthHalf : + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, kOfxBitDepthHalf , n); + break; + case eBitDepthFloat : + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, kOfxBitDepthFloat , n); + break; + default: + break; + } + } +#endif + + /** @brief Is the plugin single instance only ? */ + void ImageEffectDescriptor::setSingleInstance(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPluginPropSingleInstance, int(v)); + } + + /** @brief Does the plugin expect the host to perform per frame SMP threading */ + void ImageEffectDescriptor::setHostFrameThreading(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPluginPropHostFrameThreading, int(v)); + } + + /** @brief Does the plugin support multi resolution images */ + void ImageEffectDescriptor::setSupportsMultiResolution(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropSupportsMultiResolution, int(v)); + } + + /** @brief Does the plugin support image tiling */ + void ImageEffectDescriptor::setSupportsTiles(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropSupportsTiles, int(v)); + } + + /** @brief Does the plugin perform temporal clip access */ + void ImageEffectDescriptor::setTemporalClipAccess(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropTemporalClipAccess, int(v)); + } + + /** @brief Does the plugin want to have render called twice per frame in all circumanstances for fielded images ? */ + void ImageEffectDescriptor::setRenderTwiceAlways(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPluginPropFieldRenderTwiceAlways, int(v)); + } + + /** @brief Does the plugin support inputs and output clips of differing depths */ + void ImageEffectDescriptor::setSupportsMultipleClipDepths(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropSupportsMultipleClipDepths, int(v)); + } + + /** @brief Does the plugin support inputs and output clips of pixel aspect ratios */ + void ImageEffectDescriptor::setSupportsMultipleClipPARs(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropSupportsMultipleClipPARs, int(v)); + } + + /** @brief What kind of thread safety does the plugin have */ + void ImageEffectDescriptor::setRenderThreadSafety(RenderSafetyEnum v) + { + switch(v) + { + case eRenderUnsafe : + _effectProps.propSetString(kOfxImageEffectPluginRenderThreadSafety, kOfxImageEffectRenderUnsafe); + break; + case eRenderInstanceSafe : + _effectProps.propSetString(kOfxImageEffectPluginRenderThreadSafety, kOfxImageEffectRenderInstanceSafe); + break; + case eRenderFullySafe : + _effectProps.propSetString(kOfxImageEffectPluginRenderThreadSafety, kOfxImageEffectRenderFullySafe); + break; + } + } + + /** @brief Does the plugin support OpenCL Buffers Render */ + void ImageEffectDescriptor::setSupportsOpenCLBuffersRender(bool v) + { + try { + + _effectProps.propSetString(kOfxImageEffectPropOpenCLRenderSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropOpenCLRenderSupported property"); + } + } + + /** @brief Does the plugin support OpenCL Images Render */ + void ImageEffectDescriptor::setSupportsOpenCLImagesRender(bool v) + { + try { + + _effectProps.propSetString(kOfxImageEffectPropOpenCLSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropOpenCLSupported property"); + } + } + + /** @brief Does the plugin support CUDA Render */ + void ImageEffectDescriptor::setSupportsCudaRender(bool v) + { + try { + + _effectProps.propSetString(kOfxImageEffectPropCudaRenderSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropCudaRenderSupported property"); + } + } + + /** @brief Does the plugin support CUDA Stream */ + void ImageEffectDescriptor::setSupportsCudaStream(bool v) + { + try { + _effectProps.propSetString(kOfxImageEffectPropCudaStreamSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropCudaStreamSupported property"); + } + } + + /** @brief Does the plugin support Metal Render */ + void ImageEffectDescriptor::setSupportsMetalRender(bool v) + { + try { + _effectProps.propSetString(kOfxImageEffectPropMetalRenderSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropMetalRenderSupported property"); + } + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief Does the plugin support OpenGL accelerated rendering (but is also capable of CPU rendering) ? */ + void ImageEffectDescriptor::setSupportsOpenGLRender(bool v) { + if (gHostDescription.supportsOpenGLRender) { + _effectProps.propSetString(kOfxImageEffectPropOpenGLRenderSupported, (v ? "true" : "false")); + } + } + + /** @brief Does the plugin require OpenGL accelerated rendering ? */ + void ImageEffectDescriptor::setNeedsOpenGLRender(bool v) { + if (gHostDescription.supportsOpenGLRender) { + _effectProps.propSetString(kOfxImageEffectPropOpenGLRenderSupported, (v ? "needed" : "false")); + } + } + + void ImageEffectDescriptor::addOpenGLBitDepth(BitDepthEnum v) { + int n = _effectProps.propGetDimension(kOfxImageEffectPropSupportedPixelDepths); + std::string value = mapBitDepthEnumToStr(v); + if (!value.empty()) { + _effectProps.propSetString(kOfxOpenGLPropPixelDepth, value, n); + } + } +#endif + + /** @brief If the slave param changes the clip preferences need to be re-evaluated */ + void ImageEffectDescriptor::addClipPreferencesSlaveParam(ParamDescriptor &p) + { + int n = _effectProps.propGetDimension(kOfxImageEffectPropClipPreferencesSlaveParam); + _effectProps.propSetString(kOfxImageEffectPropClipPreferencesSlaveParam, p.getName(), n); + } + + /** @brief Create a clip, only callable from describe in context */ + ClipDescriptor *ImageEffectDescriptor::defineClip(const std::string &name) + { + // do we have the clip already + std::map::const_iterator search; + search = _definedClips.find(name); + if(search != _definedClips.end()) + return search->second; + + // no, so make it + OfxPropertySetHandle propSet; + OfxStatus stat = OFX::Private::gEffectSuite->clipDefine(_effectHandle, name.c_str(), &propSet); + (void)stat; + + ClipDescriptor *clip = new ClipDescriptor(name, propSet); + + _definedClips[name] = clip; + _clipComponentsPropNames[name] = std::string("OfxImageClipPropComponents_") + name; + _clipDepthPropNames[name] = std::string("OfxImageClipPropDepth_") + name; + _clipPARPropNames[name] = std::string("OfxImageClipPropPAR_") + name; + _clipROIPropNames[name] = std::string("OfxImageClipPropRoI_") + name; + _clipFrameRangePropNames[name] = std::string("OfxImageClipPropFrameRange_") + name; + return clip; + } + + //////////////////////////////////////////////////////////////////////////////// + // wraps up an image + ImageBase::ImageBase(OfxPropertySetHandle props) + : _imageProps(props) + { + OFX::Validation::validateImageBaseProperties(props); + + // and fetch all the properties + _rowBytes = _imageProps.propGetInt(kOfxImagePropRowBytes, /*throwOnFailure*/false); // not required for OpenCL Images + _pixelAspectRatio = _imageProps.propGetDouble(kOfxImagePropPixelAspectRatio);; + + std::string str = _imageProps.propGetString(kOfxImageEffectPropComponents); + _pixelComponents = mapStrToPixelComponentEnum(str); + + switch (_pixelComponents) { + case ePixelComponentAlpha: + _pixelComponentCount = 1; + break; + case ePixelComponentNone: + _pixelComponentCount = 0; + break; + case ePixelComponentRGB: + _pixelComponentCount = 3; + break; + case ePixelComponentRGBA: + _pixelComponentCount = 4; + break; + case ePixelComponentCustom: + default: + _pixelComponentCount = 0; + break; + } + + str = _imageProps.propGetString(kOfxImageEffectPropPixelDepth); + _pixelDepth = mapStrToBitDepthEnum(str); + + // compute bytes per pixel + _pixelBytes = _pixelComponentCount; + + switch(_pixelDepth) + { + case eBitDepthNone : _pixelBytes *= 0; break; + case eBitDepthUByte : _pixelBytes *= 1; break; + case eBitDepthUShort : _pixelBytes *= 2; break; + case eBitDepthHalf : _pixelBytes *= 2; break; + case eBitDepthFloat : _pixelBytes *= 4; break; + case eBitDepthCustom : _pixelBytes *= 0; break; + } + + str = _imageProps.propGetString(kOfxImageEffectPropPreMultiplication); + _preMultiplication = mapStrToPreMultiplicationEnum(str); + + _regionOfDefinition.x1 = _imageProps.propGetInt(kOfxImagePropRegionOfDefinition, 0); + _regionOfDefinition.y1 = _imageProps.propGetInt(kOfxImagePropRegionOfDefinition, 1); + _regionOfDefinition.x2 = _imageProps.propGetInt(kOfxImagePropRegionOfDefinition, 2); + _regionOfDefinition.y2 = _imageProps.propGetInt(kOfxImagePropRegionOfDefinition, 3); + + _bounds.x1 = _imageProps.propGetInt(kOfxImagePropBounds, 0); + _bounds.y1 = _imageProps.propGetInt(kOfxImagePropBounds, 1); + _bounds.x2 = _imageProps.propGetInt(kOfxImagePropBounds, 2); + _bounds.y2 = _imageProps.propGetInt(kOfxImagePropBounds, 3); + + str = _imageProps.propGetString(kOfxImagePropField); + if(str == kOfxImageFieldNone) { + _field = eFieldNone; + } + else if(str == kOfxImageFieldBoth) { + _field = eFieldBoth; + } + else if(str == kOfxImageFieldLower) { + _field = eFieldLower; + } + else if(str == kOfxImageFieldUpper) { + _field = eFieldLower; + } + else { + OFX::Log::error(true, "Unknown field state '%s' reported on an image", str.c_str()); + _field = eFieldNone; + } + + _uniqueID = _imageProps.propGetString(kOfxImagePropUniqueIdentifier); + + _renderScale.x = _imageProps.propGetDouble(kOfxImageEffectPropRenderScale, 0); + _renderScale.y = _imageProps.propGetDouble(kOfxImageEffectPropRenderScale, 1); + } + + ImageBase::~ImageBase() + { + } + + //////////////////////////////////////////////////////////////////////////////// + // wraps up an image + Image::Image(OfxPropertySetHandle props) + : ImageBase(props) + { + OFX::Validation::validateImageProperties(props); + + // and fetch all the properties + _OpenCLImage = nullptr; + _OpenCLImage = _imageProps.propGetPointer(kOfxImageEffectPropOpenCLImage, /*throwOnFailure*/false); + // should throw if it is not an image + _pixelData = _imageProps.propGetPointer(kOfxImagePropData, /*throwOnFailure*/!_OpenCLImage); + } + + Image::~Image() + { + OFX::Private::gEffectSuite->clipReleaseImage(_imageProps.propSetHandle()); + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + //////////////////////////////////////////////////////////////////////////////// + // wraps up an OpenGL texture + Texture::Texture(OfxPropertySetHandle props) + : ImageBase(props) + { + OFX::Validation::validateTextureProperties(props); + + // should throw if it is not a texture + _index = _imageProps.propGetInt(kOfxImageEffectPropOpenGLTextureIndex); + _target = _imageProps.propGetInt(kOfxImageEffectPropOpenGLTextureTarget); + } + + Texture::~Texture() + { + OfxStatus stat = OFX::Private::gOpenGLRenderSuite->clipFreeTexture(_imageProps.propSetHandle()); + if (stat != kOfxStatOK) { + throwSuiteStatusException(stat); + } + } +#endif + + /** @brief return a pixel pointer + + No attempt made to be uber efficient here. + */ + void *Image::getPixelAddress(int x, int y) + { + // are we in the image bounds + if(x < _bounds.x1 || x >= _bounds.x2 || y < _bounds.y1 || y >= _bounds.y2 || _pixelBytes == 0) + return 0; + + char *pix = ((char *) _pixelData) + (size_t)(y - _bounds.y1) * _rowBytes; + pix += (x - _bounds.x1) * _pixelBytes; + return (void *) pix; + } + + const void *Image::getPixelAddress(int x, int y) const + { + // are we in the image bounds + if(x < _bounds.x1 || x >= _bounds.x2 || y < _bounds.y1 || y >= _bounds.y2 || _pixelBytes == 0) + return 0; + + const char *pix = ((const char *) _pixelData) + (size_t)(y - _bounds.y1) * _rowBytes; + pix += (x - _bounds.x1) * _pixelBytes; + return (const void *) pix; + } + + //////////////////////////////////////////////////////////////////////////////// + // clip instance + + /** @brief hidden constructor */ + Clip::Clip(ImageEffect *effect, const std::string &name, OfxImageClipHandle handle, OfxPropertySetHandle props) + : _clipName(name) + , _clipProps(props) + , _clipHandle(handle) + , _effect(effect) + { + OFX::Validation::validateClipInstanceProperties(_clipProps); + } + + /** @brief fetch the label */ + void Clip::getLabel(std::string &label) const + { + label = _clipProps.propGetString(kOfxPropLabel); + } + + /** @brief fetch the labels */ + void Clip::getLabels(std::string &label, std::string &shortLabel, std::string &longLabel) const + { + getLabel(label); + shortLabel = _clipProps.propGetString(kOfxPropShortLabel, false); + longLabel = _clipProps.propGetString(kOfxPropLongLabel, false); + } + + /** @brief get the pixel depth */ + BitDepthEnum Clip::getPixelDepth(void) const + { + std::string str = _clipProps.propGetString(kOfxImageEffectPropPixelDepth); + BitDepthEnum e; + try { + e = mapStrToBitDepthEnum(str); + if(e == eBitDepthNone && isConnected()) { + OFX::Log::error(true, "Clip %s is connected and has no pixel depth.", _clipName.c_str()); + } + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown pixel depth property '%s' reported on clip '%s'", str.c_str(), _clipName.c_str()); + e = eBitDepthNone; + } + return e; + } + + /** @brief get the components in the image */ + PixelComponentEnum Clip::getPixelComponents(void) const + { + std::string str = _clipProps.propGetString(kOfxImageEffectPropComponents); + PixelComponentEnum e; + try { + e = mapStrToPixelComponentEnum(str); + if(e == ePixelComponentNone && isConnected()) { + OFX::Log::error(true, "Clip %s is connected and has no pixel component type!", _clipName.c_str()); + } + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown pixel component type '%s' reported on clip '%s'", str.c_str(), _clipName.c_str()); + e = ePixelComponentNone; + } + return e; + } + + /** @brief get the number of components in the image */ + int Clip::getPixelComponentCount(void) const + { + std::string str = _clipProps.propGetString(kOfxImageEffectPropComponents); + PixelComponentEnum e; + try { + e = mapStrToPixelComponentEnum(str); + if(e == ePixelComponentNone && isConnected()) { + OFX::Log::error(true, "Clip %s is connected and has no pixel component type!", _clipName.c_str()); + } + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown pixel component type '%s' reported on clip '%s'", str.c_str(), _clipName.c_str()); + e = ePixelComponentNone; + } + + switch (e) { + case ePixelComponentAlpha: + return 1; + case ePixelComponentNone: + return 0; + case ePixelComponentRGB: + return 3; + case ePixelComponentRGBA: + return 4; + case ePixelComponentCustom: + default: + return 0; + } + } + + /** @brief what is the actual pixel depth of the clip */ + BitDepthEnum Clip::getUnmappedPixelDepth(void) const + { + std::string str = _clipProps.propGetString(kOfxImageClipPropUnmappedPixelDepth); + BitDepthEnum e; + try { + e = mapStrToBitDepthEnum(str); + if(e == eBitDepthNone && !isConnected()) { + OFX::Log::error(true, "Clip %s is connected and has no unmapped pixel depth.", _clipName.c_str()); + } + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown unmapped pixel depth property '%s' reported on clip '%s'", str.c_str(), _clipName.c_str()); + e = eBitDepthNone; + } + return e; + } + + /** @brief what is the component type of the clip */ + PixelComponentEnum Clip::getUnmappedPixelComponents(void) const + { + std::string str = _clipProps.propGetString(kOfxImageClipPropUnmappedComponents); + PixelComponentEnum e; + try { + e = mapStrToPixelComponentEnum(str); + if(e == ePixelComponentNone && !isConnected()) { + OFX::Log::error(true, "Clip %s is connected and has no unmapped pixel component type!", _clipName.c_str()); + } + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown unmapped pixel component type '%s' reported on clip '%s'", str.c_str(), _clipName.c_str()); + e = ePixelComponentNone; + } + return e; + } + + /** @brief get the components in the image */ + PreMultiplicationEnum Clip::getPreMultiplication(void) const + { + std::string str = _clipProps.propGetString(kOfxImageEffectPropPreMultiplication); + PreMultiplicationEnum e; + try { + e = mapStrToPreMultiplicationEnum(str); + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown premultiplication type '%s' reported on clip %s!", str.c_str(), _clipName.c_str()); + e = eImageOpaque; + } + return e; + } + + /** @brief which spatial field comes first temporally */ + FieldEnum Clip::getFieldOrder(void) const + { + std::string str = _clipProps.propGetString(kOfxImageClipPropFieldOrder); + FieldEnum e; + try { + e = mapStrToFieldEnum(str); + OFX::Log::error(e != eFieldNone && e != eFieldLower && e != eFieldUpper, + "Field order '%s' reported on a clip %s is invalid, it must be none, lower or upper.", str.c_str(), _clipName.c_str()); + } + // gone wrong ? + catch(std::invalid_argument&) { + OFX::Log::error(true, "Unknown field order '%s' reported on a clip %s.", str.c_str(), _clipName.c_str()); + e = eFieldNone; + } + return e; + } + + /** @brief is the clip connected */ + bool Clip::isConnected(void) const + { + return _clipProps.propGetInt(kOfxImageClipPropConnected) != 0; + } + + /** @brief can the clip be continuously sampled */ + bool Clip::hasContinuousSamples(void) const + { + return _clipProps.propGetInt(kOfxImageClipPropContinuousSamples) != 0; + } + + /** @brief get the scale factor that has been applied to this clip */ + double Clip::getPixelAspectRatio(void) const + { + try { + return _clipProps.propGetDouble(kOfxImagePropPixelAspectRatio); + } catch(...) { + return 1.0; // This error could happen in Eyeon Fusion. + } + } + + /** @brief get the frame rate, in frames per second on this clip, after any clip preferences have been applied */ + double Clip::getFrameRate(void) const + { + return _clipProps.propGetDouble(kOfxImageEffectPropFrameRate); + } + + /** @brief return the range of frames over which this clip has images, after any clip preferences have been applied */ + OfxRangeD Clip::getFrameRange(void) const + { + OfxRangeD v; + v.min = _clipProps.propGetDouble(kOfxImageEffectPropFrameRange, 0); + v.max = _clipProps.propGetDouble(kOfxImageEffectPropFrameRange, 1); + return v; + } + + /** @brief get the frame rate, in frames per second on this clip, before any clip preferences have been applied */ + double Clip::getUnmappedFrameRate(void) const + { + return _clipProps.propGetDouble(kOfxImageEffectPropUnmappedFrameRate); + } + + /** @brief return the range of frames over which this clip has images, before any clip preferences have been applied */ + OfxRangeD Clip::getUnmappedFrameRange(void) const + { + OfxRangeD v; + v.min = _clipProps.propGetDouble(kOfxImageEffectPropUnmappedFrameRange, 0); + v.max = _clipProps.propGetDouble(kOfxImageEffectPropUnmappedFrameRange, 1); + return v; + } + + /** @brief get the RoD for this clip in the cannonical coordinate system */ + OfxRectD Clip::getRegionOfDefinition(double t) + { + OfxRectD bounds; + OfxStatus stat = OFX::Private::gEffectSuite->clipGetRegionOfDefinition(_clipHandle, t, &bounds); + if(stat == kOfxStatFailed) { + bounds.x1 = bounds.x2 = bounds.y1 = bounds.y2 = 0; + } + throwSuiteStatusException(stat); + return bounds; + } + + /** @brief fetch an image */ + Image *Clip::fetchImage(double t) + { + OfxPropertySetHandle imageHandle; + OfxStatus stat = OFX::Private::gEffectSuite->clipGetImage(_clipHandle, t, NULL, &imageHandle); + if(stat == kOfxStatFailed) { + return NULL; // not an error, fetched images out of range/region, assume black and transparent + } + else + throwSuiteStatusException(stat); + + return new Image(imageHandle); + } + + /** @brief fetch an image, with a specific region in cannonical coordinates */ + Image *Clip::fetchImage(double t, const OfxRectD &bounds) + { + OfxPropertySetHandle imageHandle; + OfxStatus stat = OFX::Private::gEffectSuite->clipGetImage(_clipHandle, t, &bounds, &imageHandle); + if(stat == kOfxStatFailed) { + return NULL; // not an error, fetched images out of range/region, assume black and transparent + } + else + throwSuiteStatusException(stat); + + return new Image(imageHandle); + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + Texture *Clip::loadTexture(double t, BitDepthEnum format, const OfxRectD *region) + { + if (!gHostDescription.supportsOpenGLRender) { + throwHostMissingSuiteException("loadTexture"); + } + OfxPropertySetHandle hTex; + OfxStatus stat = Private::gOpenGLRenderSuite->clipLoadTexture(_clipHandle, t, format == eBitDepthNone ? NULL : mapBitDepthEnumToStr(format), region, &hTex); + if (stat != kOfxStatOK) { + throwSuiteStatusException(stat); + } + return new Texture(hTex); + } +#endif + //////////////////////////////////////////////////////////////////////////////// + /// image effect + + /** @brief ctor */ + ImageEffect::ImageEffect(OfxImageEffectHandle handle) + : _effectHandle(handle) + , _effectProps(0) + , _context(eContextNone) + , _progressStartSuccess(false) + { + // get the property handle + _effectProps = OFX::Private::fetchEffectProps(handle); + + // Set this as the instance data pointer on the effect handle + _effectProps.propSetPointer(kOfxPropInstanceData, this); + + // validate the plugin instance + OFX::Validation::validatePluginInstanceProperties(_effectProps); + + // fetch the context + std::string ctxt = _effectProps.propGetString(kOfxImageEffectPropContext); + _context = mapToContextEnum(ctxt); + + // the param set daddy-oh + OfxParamSetHandle paramSet; + OfxStatus stat = OFX::Private::gEffectSuite->getParamSet(handle, ¶mSet); + throwSuiteStatusException(stat); + setParamSetHandle(paramSet); + + } + + /** @brief dtor */ + ImageEffect::~ImageEffect() + { + // clobber the instance data property on the effect handle + _effectProps.propSetPointer(kOfxPropInstanceData, 0); + + // delete any clip instances we may have constructed + std::map::iterator iter; + for(iter = _fetchedClips.begin(); iter != _fetchedClips.end(); ++iter) { + if(iter->second) { + delete iter->second; + iter->second = NULL; + } + } + } + + /** @brief the context this effect was instantiate in */ + ContextEnum ImageEffect::getContext(void) const + { + return _context; + } + + /** @brief size of the project */ + OfxPointD ImageEffect::getProjectSize(void) const + { + OfxPointD v; + v.x = _effectProps.propGetDouble(kOfxImageEffectPropProjectSize, 0); + v.y = _effectProps.propGetDouble(kOfxImageEffectPropProjectSize, 1); + return v; + } + + /** @brief origin of the project */ + OfxPointD ImageEffect::getProjectOffset(void) const + { + OfxPointD v; + v.x = _effectProps.propGetDouble(kOfxImageEffectPropProjectOffset, 0); + v.y = _effectProps.propGetDouble(kOfxImageEffectPropProjectOffset, 1); + return v; + } + + /** @brief extent of the project */ + OfxPointD ImageEffect::getProjectExtent(void) const + { + OfxPointD v; + v.x = _effectProps.propGetDouble(kOfxImageEffectPropProjectExtent, 0); + v.y = _effectProps.propGetDouble(kOfxImageEffectPropProjectExtent, 1); + return v; + } + + /** @brief pixel aspect ratio of the project */ + double ImageEffect::getProjectPixelAspectRatio(void) const + { + return _effectProps.propGetDouble(kOfxImageEffectPropProjectPixelAspectRatio, 0); + } + + /** @brief how long does the effect last */ + double ImageEffect::getEffectDuration(void) const + { + return _effectProps.propGetDouble(kOfxImageEffectInstancePropEffectDuration, 0); + } + + /** @brief the frame rate of the project */ + double ImageEffect::getFrameRate(void) const + { + return _effectProps.propGetDouble(kOfxImageEffectPropFrameRate, 0); + } + + /** @brief is the instance currently being interacted with */ + bool ImageEffect::isInteractive(void) const + { + return _effectProps.propGetInt(kOfxPropIsInteractive) != 0; + } + + /** @brief set the instance to be sequentially renderred, this should have been part of clip preferences! */ + void ImageEffect::setSequentialRender(bool v) + { + _effectProps.propSetInt(kOfxImageEffectInstancePropSequentialRender, int(v)); + } + + /** @brief Have we informed the host we want to be seqentially renderred ? */ + bool ImageEffect::getSequentialRender(void) const + { + return _effectProps.propGetInt(kOfxImageEffectInstancePropSequentialRender) != 0; + } + + /** @brief Does the plugin support image tiling ? Can only be called from changedParam or changedClip. */ + void ImageEffect::setSupportsTiles(bool v) + { + _effectProps.propSetInt(kOfxImageEffectPropSupportsTiles, int(v), false); // read/write from OFX 1.4 + } + + /** @brief Have we informed the host we support image tiling ? */ + bool ImageEffect::getSupportsTiles(void) const + { + return _effectProps.propGetInt(kOfxImageEffectPropSupportsTiles) != 0; + } + + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief Does the plugin support OpenGL accelerated rendering (but is also capable of CPU rendering) ? Can only be called from changedParam or changedClip. */ + void ImageEffect::setSupportsOpenGLRender(bool v) { + if (gHostDescription.supportsOpenGLRender) { + _effectProps.propSetString(kOfxImageEffectPropOpenGLRenderSupported, (v ? "true" : "false"), false); // read/write from OFX 1.4 + } + } + + /** @brief Does the plugin require OpenGL accelerated rendering ? Can only be called from changedParam or changedClip. */ + void ImageEffect::setNeedsOpenGLRender(bool v) { + if (gHostDescription.supportsOpenGLRender) { + _effectProps.propSetString(kOfxImageEffectPropOpenGLRenderSupported, (v ? "needed" : "false"), false); // read/write from OFX 1.4 + } + } +#endif + + /** @brief notify host that the internal data structures need syncing back to parameters for persistance and so on. This is reset by the host after calling SyncPrivateData. */ + void ImageEffect::setParamSetNeedsSyncing() + { + _effectProps.propSetInt(kOfxPropParamSetNeedsSyncing, 1, false); // introduced in OFX 1.2 + } + + OFX::Message::MessageReplyEnum ImageEffect::sendMessage(OFX::Message::MessageTypeEnum type, const std::string& id, const std::string& msg) + { + if(!OFX::Private::gMessageSuite){ throwHostMissingSuiteException("message"); } + if(!OFX::Private::gMessageSuite->message){ throwHostMissingSuiteException("message"); } + OfxStatus stat = OFX::Private::gMessageSuite->message(_effectHandle, mapMessageTypeEnumToStr(type), id.c_str(), msg.c_str()); + return mapToMessageReplyEnum(stat); + } + + OFX::Message::MessageReplyEnum ImageEffect::setPersistentMessage(OFX::Message::MessageTypeEnum type, const std::string& id, const std::string& msg) + { + if(!OFX::Private::gMessageSuiteV2){ throwHostMissingSuiteException("setPersistentMessage"); } + if(!OFX::Private::gMessageSuiteV2->setPersistentMessage){ throwHostMissingSuiteException("setPersistentMessage"); } + OfxStatus stat = OFX::Private::gMessageSuiteV2->setPersistentMessage(_effectHandle, mapMessageTypeEnumToStr(type), id.c_str(), msg.c_str()); + return mapToMessageReplyEnum(stat); + } + + OFX::Message::MessageReplyEnum ImageEffect::clearPersistentMessage() + { + if(!OFX::Private::gMessageSuiteV2){ throwHostMissingSuiteException("clearPersistentMessage"); } + if(!OFX::Private::gMessageSuiteV2->clearPersistentMessage){ throwHostMissingSuiteException("clearPersistentMessage"); } + OfxStatus stat = OFX::Private::gMessageSuiteV2->clearPersistentMessage(_effectHandle); + return mapToMessageReplyEnum(stat); + } + + /** @brief Fetch the named clip from this instance */ + Clip *ImageEffect::fetchClip(const std::string &name) + { + // do we have the clip already + std::map::const_iterator search; + search = _fetchedClips.find(name); + if(search != _fetchedClips.end()) + return search->second; + + // fetch the property set handle of the effect + OfxImageClipHandle clipHandle = 0; + OfxPropertySetHandle propHandle = 0; + OfxStatus stat = OFX::Private::gEffectSuite->clipGetHandle(_effectHandle, name.c_str(), &clipHandle, &propHandle); + throwSuiteStatusException(stat); + + // and make one + Clip *newClip = new Clip(this, name, clipHandle, propHandle); + + // add it in + _fetchedClips[name] = newClip; + + // return it + return newClip; + } + + /** @brief does the host want us to abort rendering? */ + bool ImageEffect::abort(void) const + { + return OFX::Private::gEffectSuite->abort(_effectHandle) != 0; + } + + /** @brief adds a new interact to the set of interacts open on this effect */ + void ImageEffect::addOverlayInteract(OverlayInteract *interact) + { + // do we have it already ? + std::list::iterator i; + i = std::find(_overlayInteracts.begin(), _overlayInteracts.end(), interact); + + // we don't, put it in there + if(i == _overlayInteracts.end()) { + // we have a new one to add in here + _overlayInteracts.push_back(interact); + } + } + + /** @brief removes an interact to the set of interacts open on this effect */ + void ImageEffect::removeOverlayInteract(OverlayInteract *interact) + { + // find it + std::list::iterator i; + i = std::find(_overlayInteracts.begin(), _overlayInteracts.end(), interact); + + // and remove it + if(i != _overlayInteracts.end()) { + _overlayInteracts.erase(i); + } + } + + /** @brief force all overlays on this interact to be redrawn */ + void ImageEffect::redrawOverlays(void) + { + // find it + std::list::iterator i; + for(i = _overlayInteracts.begin(); i != _overlayInteracts.end(); ++i) { + (*i)->requestRedraw(); + } + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool ImageEffect::flushOpenGLResources(void) + { + if (!gHostDescription.supportsOpenGLRender) { + return false; + } + return Private::gOpenGLRenderSuite->flushResources() == kOfxStatOK; + } +#endif + + //////////////////////////////////////////////////////////////////////////////// + // below are the default members for the base image effect + + + /** @brief client is identity function, returns the clip and time for the identity function + */ + bool ImageEffect::isIdentity(const IsIdentityArguments &/*args*/, Clip * &/*identityClip*/, double &/*identityTime*/) + { + return false; // by default, we are not an identity operation + } + + /** @brief The get RoD action */ + bool ImageEffect::getRegionOfDefinition(const RegionOfDefinitionArguments &/*args*/, OfxRectD &/*rod*/) + { + return false; // by default, we are not setting the RoD + } + + /** @brief the get RoI action */ + void ImageEffect::getRegionsOfInterest(const RegionsOfInterestArguments &/*args*/, RegionOfInterestSetter &/*rois*/) + { + // fa niente + } + + /** @brief the get frames needed action */ + void ImageEffect::getFramesNeeded(const FramesNeededArguments &/*args*/, FramesNeededSetter &/*frames*/) + { + // fa niente + } + + /** @brief client begin sequence render function */ + void ImageEffect::beginSequenceRender(const BeginSequenceRenderArguments &/*args*/) + { + // fa niente + } + + /** @brief client end sequence render function, this is one of the few that must be set */ + void ImageEffect::endSequenceRender(const EndSequenceRenderArguments &/*args*/) + { + // fa niente + } + + /** @brief The purge caches action, a request for an instance to free up as much memory as possible in low memory situations */ + void ImageEffect::purgeCaches(void) + { + // fa niente + } + + /** @brief The sync private data action, called when the effect needs to sync any private data to persistant parameters */ + void ImageEffect::syncPrivateData(void) + { + // fa niente + } + + /** @brief get the clip preferences */ + void ImageEffect::getClipPreferences(ClipPreferencesSetter &/*clipPreferences*/) + { + // fa niente + } + + /** @brief the effect is about to be actively edited by a user, called when the first user interface is opened on an instance */ + void ImageEffect::beginEdit(void) + { + // fa niente + } + + /** @brief the effect is no longer being edited by a user, called when the last user interface is closed on an instance */ + void ImageEffect::endEdit(void) + { + // fa niente + } + + /** @brief the effect is about to have some values changed */ + void ImageEffect::beginChanged(InstanceChangeReason /*reason*/) + { + } + + /** @brief called when a param has just had its value changed */ + void ImageEffect::changedParam(const InstanceChangedArgs &/*args*/, const std::string &/*paramName*/) + { + } + + /** @brief called when a clip has just been changed in some way (a rewire maybe) */ + void ImageEffect::changedClip(const InstanceChangedArgs &/*args*/, const std::string &/*clipName*/) + { + } + + /** @brief the effect has just had some values changed */ + void ImageEffect::endChanged(InstanceChangeReason /*reason*/) + { + } + + /** @brief get the time domain */ + bool ImageEffect::getTimeDomain(OfxRangeD &/*range*/) + { + // by default, do the default + return false; + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief OpenGL context attached */ + void ImageEffect::contextAttached(void) + { + // fa niente + } + + /** @brief OpenGL context detached */ + void ImageEffect::contextDetached(void) + { + // fa niente + } +#endif + + /** @brief called when a custom param needs to be interpolated */ + std::string ImageEffect::interpolateCustomParam(const InterpolateCustomArgs &args, const std::string &/*paramName*/) + { + return args.value1; + } + + /// Start doing progress. + void ImageEffect::progressStart(const std::string &message, const std::string &messageid) + { + if(OFX::Private::gProgressSuiteV2) { + OfxStatus stat = OFX::Private::gProgressSuiteV2->progressStart((void *) _effectHandle, message.c_str(), messageid.c_str()); + _progressStartSuccess = ( stat == kOfxStatOK ); + } else if(OFX::Private::gProgressSuiteV1) { + OfxStatus stat = OFX::Private::gProgressSuiteV1->progressStart((void *) _effectHandle, message.c_str()); + _progressStartSuccess = ( stat == kOfxStatOK ); + } + + } + + /// finish yer progress + void ImageEffect::progressEnd() + { + if(_progressStartSuccess) { + if(OFX::Private::gProgressSuiteV2) { + OFX::Private::gProgressSuiteV2->progressEnd((void *) _effectHandle); + } else if(OFX::Private::gProgressSuiteV1) { + OFX::Private::gProgressSuiteV1->progressEnd((void *) _effectHandle); + } + } + } + + /// set the progress to some level of completion, returns + /// false if you should abandon processing, true to continue + bool ImageEffect::progressUpdate(double t) + { + if(_progressStartSuccess) { + if(OFX::Private::gProgressSuiteV2) { + OfxStatus stat = OFX::Private::gProgressSuiteV2->progressUpdate((void *) _effectHandle, t); + if(stat == kOfxStatReplyNo) + return false; + } else if(OFX::Private::gProgressSuiteV1) { + OfxStatus stat = OFX::Private::gProgressSuiteV1->progressUpdate((void *) _effectHandle, t); + if(stat == kOfxStatReplyNo) + return false; + } + } + return true; + } + + /// get the current time on the timeline. This is not necessarily the same + /// time as being passed to an action (eg render) + double ImageEffect::timeLineGetTime() + { + if(OFX::Private::gTimeLineSuite) { + double time; + if(OFX::Private::gTimeLineSuite->getTime((void *) _effectHandle, &time) == kOfxStatOK) + return time; + } + return 0; + } + + /// set the timeline to a specific time + void ImageEffect::timeLineGotoTime(double t) + { + if(OFX::Private::gTimeLineSuite) { + OFX::Private::gTimeLineSuite->gotoTime((void *) _effectHandle, t); + } + } + + /// get the first and last times available on the effect's timeline + void ImageEffect:: timeLineGetBounds(double &t1, double &t2) + { + if(OFX::Private::gTimeLineSuite) { + OFX::Private::gTimeLineSuite->getTimeBounds((void *) _effectHandle, &t1, &t2); + return; + } + t1 = t2 = 0; + } + + //////////////////////////////////////////////////////////////////////////////// + // Class used to set the clip preferences of the effect. */ + + const std::string& ClipPreferencesSetter::extractValueForName(const StringStringMap& m, const std::string& name) + { + StringStringMap::const_iterator it = m.find(name); + if(it==m.end()) + throw(Exception::PropertyUnknownToHost(name.c_str())); + return it->second; + } + + /** @brief, force the host to set a clip's mapped component type to be \em comps. */ + void ClipPreferencesSetter::setClipComponents(Clip &clip, PixelComponentEnum comps) + { + doneSomething_ = true; + const std::string& propName = extractValueForName(clipComponentPropNames_, clip.name()); + + switch(comps) + { + case ePixelComponentNone : + outArgs_.propSetString(propName.c_str(), kOfxImageComponentNone); + break; + case ePixelComponentRGBA : + outArgs_.propSetString(propName.c_str(), kOfxImageComponentRGBA); + break; + case ePixelComponentRGB : + outArgs_.propSetString(propName.c_str(), kOfxImageComponentRGB); + break; + case ePixelComponentAlpha : + outArgs_.propSetString(propName.c_str(), kOfxImageComponentAlpha); + break; + case ePixelComponentCustom : + break; + } + } + + /** @brief, force the host to set a clip's mapped bit depth be \em bitDepth */ + void ClipPreferencesSetter::setClipBitDepth(Clip &clip, BitDepthEnum bitDepth) + { + doneSomething_ = true; + const std::string& propName = extractValueForName(clipDepthPropNames_, clip.name()); + + switch(bitDepth) + { + case eBitDepthNone : + outArgs_.propSetString(propName.c_str(), kOfxBitDepthNone); + break; + case eBitDepthUByte : + outArgs_.propSetString(propName.c_str(), kOfxBitDepthByte); + break; + case eBitDepthUShort : + outArgs_.propSetString(propName.c_str(), kOfxBitDepthShort); + break; + case eBitDepthHalf : + outArgs_.propSetString(propName.c_str(), kOfxBitDepthHalf); + break; + case eBitDepthFloat : + outArgs_.propSetString(propName.c_str(), kOfxBitDepthFloat); + break; + case eBitDepthCustom : + break; + } + } + + /** @brief, force the host to set a clip's mapped Pixel Aspect Ratio to be \em PAR */ + void ClipPreferencesSetter::setPixelAspectRatio(Clip &clip, double PAR) + { + doneSomething_ = true; + const std::string& propName = extractValueForName(clipPARPropNames_, clip.name()); + outArgs_.propSetDouble(propName.c_str(), PAR); + } + + /** @brief Allows an effect to change the output frame rate */ + void ClipPreferencesSetter::setOutputFrameRate(double v) + { + doneSomething_ = true; + outArgs_.propSetDouble(kOfxImageEffectPropFrameRate, v); + } + + /** @brief Set the premultiplication state of the output clip. */ + void ClipPreferencesSetter::setOutputPremultiplication(PreMultiplicationEnum v) + { + doneSomething_ = true; + switch(v) + { + case eImageOpaque : + outArgs_.propSetString(kOfxImageEffectPropPreMultiplication, kOfxImageOpaque); + break; + case eImagePreMultiplied: + outArgs_.propSetString(kOfxImageEffectPropPreMultiplication, kOfxImagePreMultiplied); + break; + case eImageUnPreMultiplied: + outArgs_.propSetString(kOfxImageEffectPropPreMultiplication, kOfxImageUnPreMultiplied); + break; + } + } + + /** @brief Set whether the effect can be continously sampled. */ + void ClipPreferencesSetter::setOutputHasContinousSamples(bool v) + { + doneSomething_ = true; + outArgs_.propSetInt(kOfxImageClipPropContinuousSamples, int(v)); + } + + /** @brief Sets whether the effect will produce different images in all frames, even if the no params or input images are varying (eg: a noise generator). */ + void ClipPreferencesSetter::setOutputFrameVarying(bool v) + { + doneSomething_ = true; + outArgs_.propSetInt(kOfxImageEffectFrameVarying, int(v)); + } + + + void ClipPreferencesSetter::setOutputFielding(FieldEnum v) + { + doneSomething_ = true; + switch(v) + { + case eFieldNone : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldNone, 0, false); break; + case eFieldLower : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldLower, 0, false); break; + case eFieldUpper : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldUpper, 0, false); break; + case eFieldBoth : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldBoth, 0, false); break; + case eFieldSingle : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldSingle, 0, false); break; + case eFieldDoubled : outArgs_.propSetString(kOfxImageClipPropFieldOrder, kOfxImageFieldDoubled, 0, false); break; + } + } + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Class that skins image memory allocation */ + + /** @brief ctor */ + ImageMemory::ImageMemory(size_t nBytes, ImageEffect *associatedEffect) + : _handle(0) + { + OfxImageEffectHandle effectHandle = 0; + if(associatedEffect != 0) { + effectHandle = associatedEffect->_effectHandle; + } + + OfxStatus stat = OFX::Private::gEffectSuite->imageMemoryAlloc(effectHandle, nBytes, &_handle); + if(stat == kOfxStatErrMemory) + throw std::bad_alloc(); + throwSuiteStatusException(stat); + } + + /** @brief dtor */ + ImageMemory::~ImageMemory() + { + OfxStatus stat = OFX::Private::gEffectSuite->imageMemoryFree(_handle); + // ignore status code for exception purposes + (void)stat; + } + + /** @brief lock the memory and return a pointer to it */ + void *ImageMemory::lock(void) + { + void *ptr; + OfxStatus stat = OFX::Private::gEffectSuite->imageMemoryLock(_handle, &ptr); + if(stat == kOfxStatErrMemory) + throw std::bad_alloc(); + throwSuiteStatusException(stat); + return ptr; + } + + /** @brief unlock the memory */ + void ImageMemory::unlock(void) + { + OfxStatus stat = OFX::Private::gEffectSuite->imageMemoryUnlock(_handle); + (void)stat; + } + + + + /** @brief OFX::Private namespace, for things private to the support library code here generally calls image effect class members */ + namespace Private { + + /** @brief Creates the global host description and sets its properties */ + static + void + fetchHostDescription(OfxHost *host) + { + OFX::Log::error(OFX::gHostDescriptionHasInit, "Tried to create host description when we already have one."); + if(!OFX::gHostDescriptionHasInit) { + OFX::gHostDescriptionHasInit = true; + // wrap the property handle up with a property set + PropertySet hostProps(host->host); + + // and get some properties + gHostDescription.APIVersionMajor = hostProps.propGetInt(kOfxPropAPIVersion, 0, false); // OFX 1.2 + if (gHostDescription.APIVersionMajor == 0) { + // assume OFX 1.0 + gHostDescription.APIVersionMajor = 1; + } + gHostDescription.APIVersionMinor = hostProps.propGetInt(kOfxPropAPIVersion, 1, false); // OFX 1.2 + gHostDescription.hostName = hostProps.propGetString(kOfxPropName); + gHostDescription.hostLabel = hostProps.propGetString(kOfxPropLabel); + gHostDescription.versionMajor = hostProps.propGetInt(kOfxPropVersion, 0, false); // OFX 1.2 + gHostDescription.versionMinor = hostProps.propGetInt(kOfxPropVersion, 1, false); // OFX 1.2 + gHostDescription.versionMicro = hostProps.propGetInt(kOfxPropVersion, 2, false); // OFX 1.2 + gHostDescription.versionLabel = hostProps.propGetString(kOfxPropVersionLabel, false); // OFX 1.2 + gHostDescription.hostIsBackground = hostProps.propGetInt(kOfxImageEffectHostPropIsBackground) != 0; + gHostDescription.supportsOverlays = hostProps.propGetInt(kOfxImageEffectPropSupportsOverlays) != 0; + gHostDescription.supportsMultiResolution = hostProps.propGetInt(kOfxImageEffectPropSupportsMultiResolution) != 0; + gHostDescription.supportsTiles = hostProps.propGetInt(kOfxImageEffectPropSupportsTiles) != 0; + gHostDescription.temporalClipAccess = hostProps.propGetInt(kOfxImageEffectPropTemporalClipAccess) != 0; + gHostDescription.supportsMultipleClipDepths = hostProps.propGetInt(kOfxImageEffectPropSupportsMultipleClipDepths) != 0; + gHostDescription.supportsMultipleClipPARs = hostProps.propGetInt(kOfxImageEffectPropSupportsMultipleClipPARs) != 0; + gHostDescription.supportsSetableFrameRate = hostProps.propGetInt(kOfxImageEffectPropSetableFrameRate) != 0; + gHostDescription.supportsSetableFielding = hostProps.propGetInt(kOfxImageEffectPropSetableFielding) != 0; + gHostDescription.sequentialRender = hostProps.propGetInt(kOfxImageEffectInstancePropSequentialRender, false); // appeared in OFX 1.2 + gHostDescription.supportsStringAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsStringAnimation) != 0; + gHostDescription.supportsCustomInteract = hostProps.propGetInt(kOfxParamHostPropSupportsCustomInteract) != 0; + gHostDescription.supportsChoiceAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsChoiceAnimation) != 0; + // As of 1.5 + gHostDescription.supportsStrChoice = hostProps.propGetInt(kOfxParamHostPropSupportsStrChoice, false) != 0; + // As of 1.5 + gHostDescription.supportsStrChoiceAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsStrChoiceAnimation, false) != 0; + gHostDescription.supportsBooleanAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsBooleanAnimation) != 0; + gHostDescription.supportsCustomAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsCustomAnimation) != 0; + gHostDescription.osHandle = hostProps.propGetPointer(kOfxPropHostOSHandle, false); + gHostDescription.supportsParametricParameter = gParametricParameterSuite != 0; + gHostDescription.supportsParametricAnimation = hostProps.propGetInt(kOfxParamHostPropSupportsParametricAnimation, false) != 0; + gHostDescription.supportsOpenCLRender = hostProps.propGetString(kOfxImageEffectPropOpenCLRenderSupported, 0, false) == "true"; + gHostDescription.supportsCudaRender = hostProps.propGetString(kOfxImageEffectPropCudaRenderSupported, 0, false) == "true"; + gHostDescription.supportsCudaStream = hostProps.propGetString(kOfxImageEffectPropCudaStreamSupported, 0, false) == "true"; + gHostDescription.supportsMetalRender = hostProps.propGetString(kOfxImageEffectPropMetalRenderSupported, 0, false) == "true"; + gHostDescription.supportsRenderQualityDraft = hostProps.propGetInt(kOfxImageEffectPropRenderQualityDraft, false) != 0; // appeared in OFX 1.4 + { + std::string originStr = hostProps.propGetString(kOfxImageEffectHostPropNativeOrigin, false); // appeared in OFX 1.4 + if (originStr.empty()) { + // from http://openeffects.org/standard_changes/host-origin-hints : + // "All this hint does is tell plugin that the host world is different + // than OFX. Historically the first two hosts that exhibited this issue + // could be Fusion (upper left is 0,0 natively) and Toxic (Center is 0,0)." + if (gHostDescription.hostName == "com.eyeonline.Fusion" || + ends_with(gHostDescription.hostName, "Fusion")) { + // if host is Fusion, set to TopLeft + gHostDescription.nativeOrigin = eNativeOriginTopLeft; + } else if (starts_with(gHostDescription.hostName, "Autodesk Toxik") || + ends_with(gHostDescription.hostName, "Toxik")) { + // if host is Toxic, set to Center + gHostDescription.nativeOrigin = eNativeOriginCenter; + } else { + gHostDescription.nativeOrigin = eNativeOriginBottomLeft; + } + } else if (originStr == kOfxHostNativeOriginBottomLeft) { + gHostDescription.nativeOrigin = eNativeOriginBottomLeft; + } else if (originStr == kOfxHostNativeOriginTopLeft) { + gHostDescription.nativeOrigin = eNativeOriginTopLeft; + } else if (originStr == kOfxHostNativeOriginCenter) { + gHostDescription.nativeOrigin = eNativeOriginCenter; + } + } +#ifdef OFX_SUPPORTS_OPENGLRENDER + gHostDescription.supportsOpenGLRender = gOpenGLRenderSuite != 0 && hostProps.propGetString(kOfxImageEffectPropOpenGLRenderSupported, 0, false) == "true"; +#endif + gHostDescription.maxParameters = hostProps.propGetInt(kOfxParamHostPropMaxParameters); + gHostDescription.maxPages = hostProps.propGetInt(kOfxParamHostPropMaxPages); + gHostDescription.pageRowCount = hostProps.propGetInt(kOfxParamHostPropPageRowColumnCount, 0); + gHostDescription.pageColumnCount = hostProps.propGetInt(kOfxParamHostPropPageRowColumnCount, 1); + + int numComponents = hostProps.propGetDimension(kOfxImageEffectPropSupportedComponents); + for(int i=0; igetPropertySet(handle, &propHandle); + throwSuiteStatusException(stat); + return OFX::PropertySet(propHandle); + } + + /** @brief Keeps count of how many times load/unload have been called */ + int gLoadCount = 0; + + /** @brief Library side load action, this fetches all the suite pointers */ + void loadAction(void) + { + gLoadCount++; + + //OfxStatus status = kOfxStatOK; + + // fetch the suites + OFX::Log::error(gHost == 0, "Host pointer has not been set."); + if(!gHost) throw OFX::Exception::Suite(kOfxStatErrBadHandle); + + if(gLoadCount == 1) { + gEffectSuite = (OfxImageEffectSuiteV1 *) fetchSuite(kOfxImageEffectSuite, 1); + gPropSuite = (OfxPropertySuiteV1 *) fetchSuite(kOfxPropertySuite, 1); + gParamSuite = (OfxParameterSuiteV1 *) fetchSuite(kOfxParameterSuite, 1); + gMemorySuite = (OfxMemorySuiteV1 *) fetchSuite(kOfxMemorySuite, 1); + gThreadSuite = (OfxMultiThreadSuiteV1 *) fetchSuite(kOfxMultiThreadSuite, 1); + gMessageSuite = (OfxMessageSuiteV1 *) fetchSuite(kOfxMessageSuite, 1); + gMessageSuiteV2 = (OfxMessageSuiteV2 *) fetchSuite(kOfxMessageSuite, 2, true); + gProgressSuiteV1 = (OfxProgressSuiteV1 *) fetchSuite(kOfxProgressSuite, 1, true); + gProgressSuiteV2 = (OfxProgressSuiteV2 *) fetchSuite(kOfxProgressSuite, 2, true); + gTimeLineSuite = (OfxTimeLineSuiteV1 *) fetchSuite(kOfxTimeLineSuite, 1, true); + gParametricParameterSuite = (OfxParametricParameterSuiteV1*) fetchSuite(kOfxParametricParameterSuite, 1, true); +#ifdef OFX_SUPPORTS_OPENGLRENDER + gOpenGLRenderSuite = (OfxImageEffectOpenGLRenderSuiteV1*) fetchSuite(kOfxOpenGLRenderSuite, 1, true); +#endif + + // OK check and fetch host information + fetchHostDescription(gHost); + + /// and set some dendent flags + OFX::gHostDescription.supportsMessageSuiteV2 = gMessageSuiteV2 != NULL; + OFX::gHostDescription.supportsProgressSuite = (gProgressSuiteV1 != NULL || gProgressSuiteV2 != NULL); + OFX::gHostDescription.supportsTimeLineSuite = gTimeLineSuite != NULL; + + // fetch the interact suite if the host supports interaction + if(OFX::gHostDescription.supportsOverlays || OFX::gHostDescription.supportsCustomInteract) + gInteractSuite = (OfxInteractSuiteV1 *) fetchSuite(kOfxInteractSuite, 1); + } + + // initialise the validation code + OFX::Validation::initialise(); + + // validate the host + OFX::Validation::validateHostProperties(gHost); + + } + + /** @brief Library side unload action, this fetches all the suite pointers */ + static + void unloadAction(const char* id) + { + gLoadCount--; + if (gLoadCount<0) { + OFX::Log::warning(true, "OFX Plugin '%s' is already unloaded.", id); + return; + } + + if(gLoadCount==0) + { + // force these to null + gEffectSuite = 0; + gPropSuite = 0; + gParamSuite = 0; + gMemorySuite = 0; + gThreadSuite = 0; + gMessageSuite = 0; + gMessageSuiteV2 = 0; + gInteractSuite = 0; + gParametricParameterSuite = 0; + } + + { + EffectDescriptorMap::iterator it = gEffectDescriptors.find(id); + EffectContextMap& toBeDeleted = it->second; + for(EffectContextMap::iterator it2 = toBeDeleted.begin(); it2 != toBeDeleted.end(); ++it2) + { + OFX::ImageEffectDescriptor* desc = it2->second; + delete desc; + } + toBeDeleted.clear(); + } + { + OFX::OfxPlugInfoMap::iterator it = OFX::plugInfoMap.find(id); + OFX::OfxPluginArray::iterator it2 = std::find(ofxPlugs.begin(), ofxPlugs.end(), it->second._plug.get()); + if (it2 != ofxPlugs.end()) { + (*it2) = nullptr; + } + OFX::plugInfoMap.erase(it); + } + } + + + /** @brief fetches our pointer out of the props on the handle */ + ImageEffect *retrieveImageEffectPointer(OfxImageEffectHandle handle) + { + ImageEffect *instance; + + // get the prop set on the handle + OfxPropertySetHandle propHandle; + OfxStatus stat = OFX::Private::gEffectSuite->getPropertySet(handle, &propHandle); + throwSuiteStatusException(stat); + + // make our wrapper object + PropertySet props(propHandle); + + // fetch the instance data out of the properties + instance = (ImageEffect *) 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 Checks the handles passed into the plugin's main entry point */ + static + void + checkMainHandles(const std::string &action, const void *handle, + OfxPropertySetHandle inArgsHandle, OfxPropertySetHandle outArgsHandle, + bool handleCanBeNull, bool inArgsCanBeNull, bool outArgsCanBeNull) + { + if(handleCanBeNull) + OFX::Log::warning(handle != 0, "Handle passed to '%s' is not null.", action.c_str()); + else + OFX::Log::error(handle == 0, "'Handle passed to '%s' is null.", action.c_str()); + + if(inArgsCanBeNull) + OFX::Log::warning(inArgsHandle != 0, "'inArgs' Handle passed to '%s' is not null.", action.c_str()); + else + OFX::Log::error(inArgsHandle == 0, "'inArgs' handle passed to '%s' is null.", action.c_str()); + + if(outArgsCanBeNull) + OFX::Log::warning(outArgsHandle != 0, "'outArgs' Handle passed to '%s' is not null.", action.c_str()); + else + OFX::Log::error(outArgsHandle == 0, "'outArgs' handle passed to '%s' is null.", action.c_str()); + + // validate the property sets on the arguments + OFX::Validation::validateActionArgumentsProperties(action, inArgsHandle, outArgsHandle); + + // throw exceptions if null when not meant to be null + if(!handleCanBeNull && !handle) throwSuiteStatusException(kOfxStatErrBadHandle); + if(!inArgsCanBeNull && !inArgsHandle) throwSuiteStatusException(kOfxStatErrBadHandle); + if(!outArgsCanBeNull && !outArgsHandle) throwSuiteStatusException(kOfxStatErrBadHandle); + } + + + /** @brief Fetches the arguments used in a render action 'inargs' property set into a POD struct */ + static void + getRenderActionArguments(RenderArguments &args, OFX::PropertySet inArgs) + { + args.time = inArgs.propGetDouble(kOfxPropTime); + + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.renderWindow.x1 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 0); + args.renderWindow.y1 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 1); + args.renderWindow.x2 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 2); + args.renderWindow.y2 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 3); + + args.isEnabledOpenCLRender = inArgs.propGetInt(kOfxImageEffectPropOpenCLEnabled, false) != 0; + args.isEnabledCudaRender = inArgs.propGetInt(kOfxImageEffectPropCudaEnabled, false) != 0; + args.isEnabledMetalRender = inArgs.propGetInt(kOfxImageEffectPropMetalEnabled, false) != 0; + args.pOpenCLCmdQ = inArgs.propGetPointer(kOfxImageEffectPropOpenCLCommandQueue, false); + args.pCudaStream = inArgs.propGetPointer(kOfxImageEffectPropCudaStream, false); + args.pMetalCmdQ = inArgs.propGetPointer(kOfxImageEffectPropMetalCommandQueue, false); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + // Don't throw an exception if the following inArgs are not present. + // OpenGL rendering appeared in OFX 1.3 + args.openGLEnabled = inArgs.propGetInt(kOfxImageEffectPropOpenGLEnabled, false) != 0; +#endif + + // Don't throw an exception if the following inArgs are not present: + // They appeared in OFX 1.2. + args.sequentialRenderStatus = inArgs.propGetInt(kOfxImageEffectPropSequentialRenderStatus, false) != 0; + args.interactiveRenderStatus = inArgs.propGetInt(kOfxImageEffectPropInteractiveRenderStatus, false) != 0; + + // kOfxImageEffectPropRenderQualityDraft appeared in OFX 1.4 + args.renderQualityDraft = inArgs.propGetInt(kOfxImageEffectPropRenderQualityDraft, false) != 0; + + args.fieldToRender = eFieldNone; + std::string str = inArgs.propGetString(kOfxImageEffectPropFieldToRender); + try { + args.fieldToRender = mapStrToFieldEnum(str); + } + catch (std::invalid_argument&) { + // dud field? + OFX::Log::error(true, "Unknown field to render '%s'", str.c_str()); + + // HACK need to throw something to cause a failure + } + } + + /** @brief Library side render action, fetches relevant properties and calls the client code */ + static + void + renderAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + RenderArguments args; + + // get the arguments + getRenderActionArguments(args, inArgs); + + // and call the plugin client render code + effectInstance->render(args); + } + + /** @brief Library side render begin sequence render action, fetches relevant properties and calls the client code */ + static + void + beginSequenceRenderAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + BeginSequenceRenderArguments args; + + args.frameRange.min = inArgs.propGetDouble(kOfxImageEffectPropFrameRange, 0); + args.frameRange.max = inArgs.propGetDouble(kOfxImageEffectPropFrameRange, 1); + + args.frameStep = inArgs.propGetDouble(kOfxImageEffectPropFrameStep, 0); + + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.isEnabledOpenCLRender = inArgs.propGetInt(kOfxImageEffectPropOpenCLEnabled, false) != 0; + args.isEnabledCudaRender = inArgs.propGetInt(kOfxImageEffectPropCudaEnabled, false) != 0; + args.isEnabledMetalRender = inArgs.propGetInt(kOfxImageEffectPropMetalEnabled, false) != 0; + args.pOpenCLCmdQ = inArgs.propGetPointer(kOfxImageEffectPropOpenCLCommandQueue, false); + args.pCudaStream = inArgs.propGetPointer(kOfxImageEffectPropCudaStream, false); + args.pMetalCmdQ = inArgs.propGetPointer(kOfxImageEffectPropMetalCommandQueue, false); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + // Don't throw an exception if the following inArgs are not present. + // OpenGL rendering appeared in OFX 1.3 + args.openGLEnabled = inArgs.propGetInt(kOfxImageEffectPropOpenGLEnabled, false) != 0; +#endif + args.isInteractive = inArgs.propGetInt(kOfxPropIsInteractive) != 0; + // Don't throw an exception if the following inArgs are not present: + // They appeared in OFX 1.2 + args.sequentialRenderStatus = inArgs.propGetInt(kOfxImageEffectPropSequentialRenderStatus, false) != 0; + args.interactiveRenderStatus = inArgs.propGetInt(kOfxImageEffectPropInteractiveRenderStatus, false) != 0; + + // and call the plugin client render code + effectInstance->beginSequenceRender(args); + } + + /** @brief Library side render begin sequence render action, fetches relevant properties and calls the client code */ + static + void + endSequenceRenderAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + EndSequenceRenderArguments args; + + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.isEnabledOpenCLRender = inArgs.propGetInt(kOfxImageEffectPropOpenCLEnabled, false) != 0; + args.isEnabledCudaRender = inArgs.propGetInt(kOfxImageEffectPropCudaEnabled, false) != 0; + args.isEnabledMetalRender = inArgs.propGetInt(kOfxImageEffectPropMetalEnabled, false) != 0; + args.pOpenCLCmdQ = inArgs.propGetPointer(kOfxImageEffectPropOpenCLCommandQueue, false); + args.pCudaStream = inArgs.propGetPointer(kOfxImageEffectPropCudaStream, false); + args.pMetalCmdQ = inArgs.propGetPointer(kOfxImageEffectPropMetalCommandQueue, false); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + // Don't throw an exception if the following inArgs are not present. + // OpenGL rendering appeared in OFX 1.3 + args.openGLEnabled = inArgs.propGetInt(kOfxImageEffectPropOpenGLEnabled, false) != 0; +#endif + args.isInteractive = inArgs.propGetInt(kOfxPropIsInteractive) != 0; + // Don't throw an exception if the following inArgs are not present: + // They appeared in OFX 1.2 + args.sequentialRenderStatus = inArgs.propGetInt(kOfxImageEffectPropSequentialRenderStatus, false) != 0; + args.interactiveRenderStatus = inArgs.propGetInt(kOfxImageEffectPropInteractiveRenderStatus, false) != 0; + + // and call the plugin client render code + effectInstance->endSequenceRender(args); + } + + + /** @brief Fetches the arguments used in a isIdentity action 'inargs' property set into a POD struct */ + static void + getIsIdentityActionArguments(IsIdentityArguments &args, OFX::PropertySet inArgs) + { + args.time = inArgs.propGetDouble(kOfxPropTime); + + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.renderWindow.x1 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 0); + args.renderWindow.y1 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 1); + args.renderWindow.x2 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 2); + args.renderWindow.y2 = inArgs.propGetInt(kOfxImageEffectPropRenderWindow, 3); + + std::string str = inArgs.propGetString(kOfxImageEffectPropFieldToRender); + try { + args.fieldToRender = mapStrToFieldEnum(str); + } + catch (std::invalid_argument&) { + // dud field? + OFX::Log::error(true, "Unknown field to render '%s'", str.c_str()); + + // HACK need to throw something to cause a failure + } + } + + /** @brief Library side render begin sequence render action, fetches relevant properties and calls the client code */ + static + bool + isIdentityAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs, OFX::PropertySet &outArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + IsIdentityArguments args; + + // get the arguments + getIsIdentityActionArguments(args, inArgs); + + // and call the plugin client isIdentity code + Clip *identityClip = 0; + double identityTime = args.time; + bool v = effectInstance->isIdentity(args, identityClip, identityTime); + + if(v && identityClip) { + outArgs.propSetString(kOfxPropName, identityClip->name()); + outArgs.propSetDouble(kOfxPropTime, identityTime); + return true; + } + return false; + } + + /** @brief Library side get region of definition function */ + static + bool + regionOfDefinitionAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs, OFX::PropertySet &outArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + RegionOfDefinitionArguments args; + + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.time = inArgs.propGetDouble(kOfxPropTime); + + // and call the plugin client code + OfxRectD rod; + bool v = effectInstance->getRegionOfDefinition(args, rod); + + if(v) { + outArgs.propSetDouble(kOfxImageEffectPropRegionOfDefinition, rod.x1, 0); + outArgs.propSetDouble(kOfxImageEffectPropRegionOfDefinition, rod.y1, 1); + outArgs.propSetDouble(kOfxImageEffectPropRegionOfDefinition, rod.x2, 2); + outArgs.propSetDouble(kOfxImageEffectPropRegionOfDefinition, rod.y2, 3); + return true; + } + return false; + } + + /** @brief Library side get regions of interest function */ + static + bool + regionsOfInterestAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs, OFX::PropertySet &outArgs, const char* plugname) + { + /** @brief local class to set the roi of a clip */ + class LOCAL ActualROISetter : public OFX::RegionOfInterestSetter { + OFX::PropertySet &outArgs_; + bool doneSomething_; + const std::map& clipROIPropNames_; + public : + /** @brief ctor */ + ActualROISetter(OFX::PropertySet &args, const std::map& clipROIPropNames) + : outArgs_(args) + , doneSomething_(false) + , clipROIPropNames_(clipROIPropNames) + { } + + /** @brief did we set something ? */ + bool didSomething(void) const {return doneSomething_;} + + /** @brief set the RoI of the clip */ + virtual void setRegionOfInterest(const Clip &clip, const OfxRectD &roi) + { + std::map::const_iterator it = clipROIPropNames_.find(clip.name()); + if(it==clipROIPropNames_.end()) + throw(Exception::PropertyUnknownToHost(clip.name().c_str())); + + // construct the name of the property + const std::string& propName = it->second; + + // and set it + outArgs_.propSetDouble(propName.c_str(), roi.x1, 0); + outArgs_.propSetDouble(propName.c_str(), roi.y1, 1); + outArgs_.propSetDouble(propName.c_str(), roi.x2, 2); + outArgs_.propSetDouble(propName.c_str(), roi.y2, 3); + + // and record the face we have done something + doneSomething_ = true; + } + }; // end of local class + + // fetch our effect pointer + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + RegionsOfInterestArguments args; + + // fetch in arguments from the prop handle + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + args.regionOfInterest.x1 = inArgs.propGetDouble(kOfxImageEffectPropRegionOfInterest, 0); + args.regionOfInterest.y1 = inArgs.propGetDouble(kOfxImageEffectPropRegionOfInterest, 1); + args.regionOfInterest.x2 = inArgs.propGetDouble(kOfxImageEffectPropRegionOfInterest, 2); + args.regionOfInterest.y2 = inArgs.propGetDouble(kOfxImageEffectPropRegionOfInterest, 3); + + args.time = inArgs.propGetDouble(kOfxPropTime); + + // make a roi setter object + ActualROISetter setRoIs(outArgs, gEffectDescriptors[plugname][effectInstance->getContext()]->getClipROIPropNames()); + + // and call the plugin client code + effectInstance->getRegionsOfInterest(args, setRoIs); + + // did we do anything ? + if(setRoIs.didSomething()) + return true; + return false; + } + + /** @brief Library side frames needed action */ + static + bool + framesNeededAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs, OFX::PropertySet &outArgs, const char* plugname) + { + /** @brief local class to set the frames needed from a clip */ + class LOCAL ActualSetter : public OFX::FramesNeededSetter { + OFX::PropertySet &outArgs_; /**< @brief property set to set values in */ + std::map > frameRanges_; /**< @brief map holding a bunch of frame ranges, one for each clip */ + const std::map& _clipFrameRangePropNames; + public : + /** @brief ctor */ + ActualSetter(OFX::PropertySet &args, const std::map& clipFrameRangePropNames) + : outArgs_(args), _clipFrameRangePropNames(clipFrameRangePropNames) + { } + + /** @brief set the RoI of the clip */ + virtual void setFramesNeeded(const Clip &clip, const OfxRangeD &range) + { + // insert this into the vector which is in the map + frameRanges_[clip.name()].push_back(range); + } + + /** @brief write frameRanges_ back to the property set */ + bool setOutProperties(void) + { + bool didSomething = false; + + std::map >::iterator i; + + for(i = frameRanges_.begin(); i != frameRanges_.end(); ++i) { + if(i->first != kOfxImageEffectOutputClipName) { + didSomething = true; + + // Make the property name we are setting + const std::map::const_iterator it = _clipFrameRangePropNames.find(i->first); + if(it==_clipFrameRangePropNames.end()) + throw(Exception::PropertyUnknownToHost(i->first.c_str())); + + const std::string& propName = it->second; + + // fetch the list of frame ranges + std::vector &clipRange = i->second; + std::vector::iterator j; + int n = 0; + + // and set 'em + for(j = clipRange.begin(); j < clipRange.end(); ++j) { + outArgs_.propSetDouble(propName.c_str(), j->min, n++); + outArgs_.propSetDouble(propName.c_str(), j->max, n++); + } + } + } + + return didSomething; + } + + }; // end of local class + + // fetch our effect pointer + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + FramesNeededArguments args; + + // fetch in arguments from the prop handle + args.time = inArgs.propGetDouble(kOfxPropTime); + + // make a roi setter object + ActualSetter setFrames(outArgs, gEffectDescriptors[plugname][effectInstance->getContext()]->getClipFrameRangePropNames()); + + // and call the plugin client code + effectInstance->getFramesNeeded(args, setFrames); + + // Write it back to the properties and see if we set anything + if(setFrames.setOutProperties()) + return true; + return false; + } + + /** @brief Library side get regions of interest function */ + static + bool + getTimeDomainAction(OfxImageEffectHandle handle, OFX::PropertySet &outArgs) + { + // fetch our effect pointer + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + // we can only be a general context effect, so check that this is true + OFX::Log::error(effectInstance->getContext() != eContextGeneral, "Calling kOfxImageEffectActionGetTimeDomain on an effect that is not a general context effect."); + + OfxRangeD timeDomain; + + // and call the plugin client code + bool v = effectInstance->getTimeDomain(timeDomain); + + if(v) { + outArgs.propSetDouble(kOfxImageEffectPropFrameRange, timeDomain.min, 0); + outArgs.propSetDouble(kOfxImageEffectPropFrameRange, timeDomain.max, 1); + } + + return v; + } + + /** @brief Library side get regions of interest function */ + static + bool + clipPreferencesAction(OfxImageEffectHandle handle, OFX::PropertySet &outArgs, const char* plugname) + { + // fetch our effect pointer + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + // set up our clip preferences setter + ImageEffectDescriptor* desc = gEffectDescriptors[plugname][effectInstance->getContext()]; + ClipPreferencesSetter prefs(outArgs, desc->getClipDepthPropNames(), desc->getClipComponentPropNames(), desc->getClipPARPropNames()); + + // and call the plug-in client code + effectInstance->getClipPreferences(prefs); + + // did we do anything ? + if(prefs.didSomething()) + return true; + return false; + } + + /** @brief Library side begin instance changed action */ + static + void + beginInstanceChangedAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + std::string reasonStr = inArgs.propGetString(kOfxPropChangeReason); + InstanceChangeReason reason = mapToInstanceChangedReason(reasonStr); + + // and call the plugin client code + effectInstance->beginChanged(reason); + } + + /** @brief Library side instance changed action */ + static + void + instanceChangedAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + InstanceChangedArgs args; + + // why did it change + std::string reasonStr = inArgs.propGetString(kOfxPropChangeReason); + args.reason = mapToInstanceChangedReason(reasonStr); + args.time = inArgs.propGetDouble(kOfxPropTime); + args.renderScale.x = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 0); + args.renderScale.y = inArgs.propGetDouble(kOfxImageEffectPropRenderScale, 1); + + // what changed + std::string changedType = inArgs.propGetString(kOfxPropType); + std::string changedName = inArgs.propGetString(kOfxPropName); + + if(changedType == kOfxTypeParameter) { + // and call the plugin client code + effectInstance->changedParam(args, changedName); + } + else if(changedType == kOfxTypeClip) { + // and call the plugin client code + effectInstance->changedClip(args, changedName); + } + else { + OFX::Log::error(true, "Instance Changed called with unknown type '%s' of object '%s'", changedType.c_str(), changedName.c_str()); + } + } + + /** @brief Library side end instance changed action */ + static + void + endInstanceChangedAction(OfxImageEffectHandle handle, OFX::PropertySet inArgs) + { + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + std::string reasonStr = inArgs.propGetString(kOfxPropChangeReason); + InstanceChangeReason reason = mapToInstanceChangedReason(reasonStr); + + // and call the plugin client code + effectInstance->endChanged(reason); + } + + + /** @brief The main entry point for the plugin + */ + OfxStatus mainEntryStr(const char *actionRaw, + const void *handleRaw, + OfxPropertySetHandle inArgsRaw, + OfxPropertySetHandle outArgsRaw, + const char* plugname) + { + OFX::Log::print("********************************************************************************"); + OFX::Log::print("START mainEntry (%s for %s)", actionRaw, plugname); + OFX::Log::indent(); + OfxStatus stat = kOfxStatReplyDefault; + try { + + OfxPlugInfoMap::iterator it = plugInfoMap.find(plugname); + if(it==plugInfoMap.end()) + throw; + + OFX::PluginFactory* factory = it->second._factory; + + // Cast the raw handle to be an image effect handle, because that is what it is + OfxImageEffectHandle handle = (OfxImageEffectHandle) 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 == kOfxActionLoad) { + // call the support load function, param-less + OFX::Private::loadAction(); + + // call the plugin side load action, param-less + factory->load(); + + // got here, must be good + stat = kOfxStatOK; + } + + // figure the actions + else if (action == kOfxActionUnload) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, true, true, true); + + // call the plugin side unload action, param-less, should be called, eve if the stat above failed! + factory->unload(); + + // call the support unload function, param-less + OFX::Private::unloadAction(plugname); + + // got here, must be good + stat = kOfxStatOK; + } + + else if(action == kOfxActionDescribe) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // make the plugin descriptor + ImageEffectDescriptor *desc = new ImageEffectDescriptor(handle); + + // validate the host + OFX::Validation::validatePluginDescriptorProperties(fetchEffectProps(handle)); + + // and pass it to the plugin to do something with it + + factory->describe(*desc); + + // add it to our map + gEffectDescriptors[plugname][eContextNone] = desc; + + // got here, must be good + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionDescribeInContext) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // make the plugin descriptor and pass it to the plugin to do something with it + ImageEffectDescriptor *desc = new ImageEffectDescriptor(handle); + + // figure the context and map it to an enum + std::string contextStr = inArgs.propGetString(kOfxImageEffectPropContext); + ContextEnum context = mapToContextEnum(contextStr); + + // validate the host + OFX::Validation::validatePluginDescriptorProperties(fetchEffectProps(handle)); + + // call plugin describe in context + factory->describeInContext(*desc, context); + + // add it to our map + gEffectDescriptors[plugname][context] = desc; + + // got here, must be good + stat = kOfxStatOK; + } + else if(action == kOfxActionCreateInstance) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch the effect props to figure the context + PropertySet effectProps = fetchEffectProps(handle); + + // get the context and turn it into an enum + std::string str = effectProps.propGetString(kOfxImageEffectPropContext); + ContextEnum context = mapToContextEnum(str); + + // make the image effect instance for this context + ImageEffect *instance = factory->createInstance(handle, context); + (void)instance; + + // validate the plugin handle's properties + OFX::Validation::validatePluginInstanceProperties(fetchEffectProps(handle)); + + // got here, must be good + stat = kOfxStatOK; + } + else if(action == kOfxActionDestroyInstance) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // kill it + delete instance; + + // got here, must be good + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionRender) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the render action skin + renderAction(handle, inArgs); + + // got here, must be good + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionBeginSequenceRender) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the begin render action skin + beginSequenceRenderAction(handle, inArgs); + } + else if(action == kOfxImageEffectActionEndSequenceRender) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the begin render action skin + endSequenceRenderAction(handle, inArgs); + } + else if(action == kOfxImageEffectActionIsIdentity) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, false); + + // call the identity action, if it is, return OK + if(isIdentityAction(handle, inArgs, outArgs)) + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionGetRegionOfDefinition) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, false); + + // call the rod action, return OK if it does something + if(regionOfDefinitionAction(handle, inArgs, outArgs)) + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionGetRegionsOfInterest) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, false); + + // call the RoI action, return OK if it does something + if(regionsOfInterestAction(handle, inArgs, outArgs, plugname)) + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionGetFramesNeeded) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, false); + + // call the frames needed action, return OK if it does something + if(framesNeededAction(handle, inArgs, outArgs, plugname)) + stat = kOfxStatOK; + } + else if(action == kOfxImageEffectActionGetClipPreferences) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, false); + + // call the frames needed action, return OK if it does something + if(clipPreferencesAction(handle, outArgs, plugname)) + stat = kOfxStatOK; + } + else if(action == kOfxActionPurgeCaches) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // purge 'em + instance->purgeCaches(); + } + else if(action == kOfxActionSyncPrivateData) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // and sync it + instance->syncPrivateData(); + } + else if(action == kOfxImageEffectActionGetTimeDomain) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, false); + + // call the instance changed action + if(getTimeDomainAction(handle, outArgs)) + stat = kOfxStatOK; + } + else if(action == kOfxActionBeginInstanceChanged) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the instance changed action + beginInstanceChangedAction(handle, inArgs); + } + else if(action == kOfxActionInstanceChanged) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the instance changed action + instanceChangedAction(handle, inArgs); + } + else if(action == kOfxActionEndInstanceChanged) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, false, true); + + // call the instance changed action + endInstanceChangedAction(handle, inArgs); + } + else if(action == kOfxActionBeginInstanceEdit) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // call the begin edit function + instance->beginEdit(); + } + else if(action == kOfxActionEndInstanceEdit) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // call the end edit function + instance->endEdit(); + } +#ifdef OFX_SUPPORTS_OPENGLRENDER + else if(action == kOfxActionOpenGLContextAttached) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // call the context attached function + instance->contextAttached(); + } + else if(action == kOfxActionOpenGLContextDetached) { + checkMainHandles(actionRaw, handleRaw, inArgsRaw, outArgsRaw, false, true, true); + + // fetch our pointer out of the props on the handle + ImageEffect *instance = retrieveImageEffectPointer(handle); + + // call the context detached function + instance->contextDetached(); + } +#endif + else if(actionRaw) { + OFX::Log::error(true, "Unknown action '%s'.", actionRaw); + } + else { + OFX::Log::error(true, "Requested action was a null pointer."); + } + } + + // catch suite exceptions + catch (const OFX::Exception::Suite &ex) + { + OFX::Log::error(true, "Caught OFX::Exception::Suite: %s", ex.what()); +# ifdef DEBUG + std::cout << "Caught OFX::Exception::Suite: " << ex.what() << std::endl; +# endif + stat = ex.status(); + } + + // catch host inadequate exceptions + catch (const OFX::Exception::HostInadequate &e) + { + OFX::Log::error(true, "Caught OFX::Exception::HostInadequate: %s", e.what()); +# ifdef DEBUG + std::cout << "Caught OFX::Exception::HostInadequate: " << e.what() << std::endl; +# endif + stat = kOfxStatErrMissingHostFeature; + } + + // catch exception due to a property being unknown to the host, implies something wrong with host if not caught further down + catch (const OFX::Exception::PropertyUnknownToHost &e) + { + OFX::Log::error(true, "Caught OFX::Exception::PropertyUnknownToHost: %s", e.what()); +# ifdef DEBUG + std::cout << "Caught OFX::Exception::PropertyUnknownToHost: " << e.what() << std::endl; +# endif + stat = kOfxStatErrMissingHostFeature; + } + + // catch memory + catch (std::bad_alloc&) + { + stat = kOfxStatErrMemory; + } + + // catch a custom client exception, if defined +#ifdef OFX_CLIENT_EXCEPTION_TYPE + catch (OFX_CLIENT_EXCEPTION_TYPE &ex) + { + stat = OFX_CLIENT_EXCEPTION_HANDLER(ex, plugname); + } +#endif + // Catch anything else, unknown + catch (const std::exception &e) + { + OFX::Log::error(true, "Caught std::exception: %s", e.what()); +# ifdef DEBUG + std::cout << "Caught std::exception: " << e.what() << std::endl; +# endif + stat = kOfxStatFailed; + } + catch (...) + { + OFX::Log::error(true, "Caught unknown exception"); +# ifdef DEBUG + std::cout << "Caught Unknown exception" << std::endl; +# endif + stat = kOfxStatFailed; + } + + OFX::Log::outdent(); + OFX::Log::print("STOP mainEntry (%s for %s, returning %d=%s)\n", actionRaw, plugname, + stat, mapStatusToString(stat)); + return stat; + } + + + OfxStatus customParamInterpolationV1Entry( + const void* handleRaw, + OfxPropertySetHandle inArgsRaw, + OfxPropertySetHandle outArgsRaw) + { + OFX::Log::print("********************************************************************************"); + OFX::Log::print("START customParamInterpolationV1Entry"); + OFX::Log::indent(); + OfxStatus stat = kOfxStatReplyDefault; + try { + // Cast the raw handle to be an image effect handle, because that is what it is + OfxImageEffectHandle handle = (OfxImageEffectHandle) handleRaw; + + // Turn the arguments into wrapper objects to make our lives easier + OFX::PropertySet inArgs(inArgsRaw); + OFX::PropertySet outArgs(outArgsRaw); + + ImageEffect *effectInstance = retrieveImageEffectPointer(handle); + + InterpolateCustomArgs interpArgs; + + interpArgs.time = inArgs.propGetDouble(kOfxPropTime); + interpArgs.value1 = inArgs.propGetString(kOfxParamPropCustomValue, 0); + interpArgs.value2 = inArgs.propGetString(kOfxParamPropCustomValue, 1); + interpArgs.keytime1 = inArgs.propGetDouble(kOfxParamPropInterpolationTime, 0); + interpArgs.keytime2 = inArgs.propGetDouble(kOfxParamPropInterpolationTime, 1); + interpArgs.amount = inArgs.propGetDouble(kOfxParamPropInterpolationAmount); + + std::string paramName = inArgs.propGetString(kOfxPropName); + + // and call the plugin client code + std::string output = effectInstance->interpolateCustomParam(interpArgs, paramName); + + outArgs.propSetString(kOfxParamPropCustomValue, output); + } + + // catch suite exceptions + catch (OFX::Exception::Suite &ex) + { +# ifdef DEBUG + std::cout << "Caught OFX::Exception::Suite" << std::endl; +# endif + stat = ex.status(); + } + + // catch host inadequate exceptions + catch (OFX::Exception::HostInadequate&) + { +# ifdef DEBUG + std::cout << "Caught OFX::Exception::HostInadequate" << std::endl; +# endif + stat = kOfxStatErrMissingHostFeature; + } + + // catch exception due to a property being unknown to the host, implies something wrong with host if not caught further down + catch (OFX::Exception::PropertyUnknownToHost&) + { +# ifdef DEBUG + std::cout << "Caught OFX::Exception::PropertyUnknownToHost" << std::endl; +# endif + stat = kOfxStatErrMissingHostFeature; + } + + // catch memory + catch (std::bad_alloc&) + { + stat = kOfxStatErrMemory; + } + + // catch a custom client exception, if defined +#ifdef OFX_CLIENT_EXCEPTION_TYPE + catch (OFX_CLIENT_EXCEPTION_TYPE &ex) + { + stat = OFX_CLIENT_EXCEPTION_HANDLER(ex, plugname); + } +#endif + // Catch anything else, unknown + catch (...) + { +# ifdef DEBUG + std::cout << "Caught Unknown exception" << std::endl; +# endif + stat = kOfxStatFailed; + } + + OFX::Log::outdent(); + OFX::Log::print("STOP customParamInterpolationV1Entry\n"); + return stat; + } + + /** @brief The plugin function that gets passed the host structure. */ + void setHost(OfxHost *host) + { + gHost = host; + } + + }; // namespace Private + + /** @brief Fetch's a suite from the host and logs errors */ + const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional) + { + const void *suite = Private::gHost->fetchSuite(Private::gHost->host, suiteName, suiteVersion); + if(suite==0) + { + if(optional) + OFX::Log::warning(suite == 0, "Could not fetch the optional suite '%s' version %d.", suiteName, suiteVersion); + else + OFX::Log::error(suite == 0, "Could not fetch the mandatory suite '%s' version %d.", suiteName, suiteVersion); + } + if(!optional && suite == 0) throw OFX::Exception::HostInadequate(suiteName); + return suite; + } + +}; // namespace OFX + +static +OFX::OfxPlugInfo generatePlugInfo(OFX::PluginFactory* factory, std::string& newID) +{ + newID = factory->getUID(); + std::unique_ptr ofxPlugin(new OfxPlugin()); + ofxPlugin->pluginApi = kOfxImageEffectPluginApi; + ofxPlugin->apiVersion = 1; + ofxPlugin->pluginIdentifier = factory->getID().c_str(); + ofxPlugin->pluginVersionMajor = factory->getMajorVersion(); + ofxPlugin->pluginVersionMinor = factory->getMinorVersion(); + ofxPlugin->setHost = OFX::Private::setHost; + ofxPlugin->mainEntry = factory->getMainEntry(); + return OFX::OfxPlugInfo(factory, std::move(ofxPlugin)); +} + +bool gHasInit = false; + +static +void init() +{ + if(gHasInit) + return; + + OFX::Plugin::getPluginIDs(OFX::plugIDs); + if(OFX::ofxPlugs.empty()) + OFX::ofxPlugs.resize(OFX::plugIDs.size()); + + int counter = 0; + for (OFX::PluginFactoryArray::const_iterator it = OFX::plugIDs.begin(); it != OFX::plugIDs.end(); ++it, ++counter) + { + std::string newID; + OFX::OfxPlugInfo info = generatePlugInfo(*it, newID); + OFX::ofxPlugs[counter] = info._plug.get(); + OFX::plugInfoMap[newID] = std::move(info); + } + gHasInit = true; +} + +/** @brief, mandated function returning the number of plugins, which is always 1 */ +EXPORT int OfxGetNumberOfPlugins(void) +{ + init(); + return (int)OFX::plugIDs.size(); +} + +/** @brief, mandated function returning the nth plugin + +We call the plugin side defined OFX::Plugin::getPluginIDs function to find out what to set. +*/ + +EXPORT OfxPlugin* OfxGetPlugin(int nth) +{ + init(); + int numPlugs = (int)OFX::plugInfoMap.size(); + OFX::Log::error(nth >= numPlugs, "Host attempted to get plugin %d, when there is only %d plugin(s), so it should have asked for 0.", nth, numPlugs); + if(OFX::ofxPlugs[nth] == nullptr) + { + std::string newID; + OFX::OfxPlugInfo info = generatePlugInfo(OFX::plugIDs[nth], newID); + OFX::ofxPlugs[nth] = info._plug.get(); + OFX::plugInfoMap[newID] = std::move(info); + } + return OFX::ofxPlugs[nth]; +} diff --git a/third_party/openfx/Support/Library/ofxsInteract.cpp b/third_party/openfx/Support/Library/ofxsInteract.cpp new file mode 100644 index 000000000..784a9d093 --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsInteract.cpp @@ -0,0 +1,546 @@ + + +/** @brief This file contains code that skins the ofx interact suite (for image effects) */ + + +#include "ofxsSupportPrivate.h" +#include // 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::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::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 diff --git a/third_party/openfx/Support/Library/ofxsLog.cpp b/third_party/openfx/Support/Library/ofxsLog.cpp new file mode 100644 index 000000000..5444a78c4 --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsLog.cpp @@ -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 +#include +#include +#include +#include + +#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); + } + } + }; +}; diff --git a/third_party/openfx/Support/Library/ofxsMultiThread.cpp b/third_party/openfx/Support/Library/ofxsMultiThread.cpp new file mode 100644 index 000000000..ced3592fe --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsMultiThread.cpp @@ -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; + } + + }; +}; diff --git a/third_party/openfx/Support/Library/ofxsParams.cpp b/third_party/openfx/Support/Library/ofxsParams.cpp new file mode 100644 index 000000000..0af7d1c40 --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsParams.cpp @@ -0,0 +1,3226 @@ + + +/** @brief This file contains code that skins the ofx param suite */ + +#include +#include +#include "ofxsSupportPrivate.h" +#include "ofxParametricParam.h" + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. */ +namespace OFX { + + /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */ + DummyParamDescriptor PageParamDescriptor::gSkipRow(kOfxParamPageSkipRow); + + /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */ + DummyParamDescriptor PageParamDescriptor::gSkipColumn(kOfxParamPageSkipColumn); + + /** @brief turns a ParamTypeEnum into the char * that raw OFX uses */ + const char * mapParamTypeEnumToString(ParamTypeEnum v) + { + switch(v) + { + case eStringParam : return kOfxParamTypeString ; + case eIntParam : return kOfxParamTypeInteger ; + case eInt2DParam : return kOfxParamTypeInteger2D ; + case eInt3DParam : return kOfxParamTypeInteger3D ; + case eDoubleParam : return kOfxParamTypeDouble ; + case eDouble2DParam : return kOfxParamTypeDouble2D ; + case eDouble3DParam : return kOfxParamTypeDouble3D ; + case eRGBParam : return kOfxParamTypeRGB ; + case eRGBAParam : return kOfxParamTypeRGBA ; + case eBooleanParam : return kOfxParamTypeBoolean ; + case eChoiceParam : return kOfxParamTypeChoice ; + case eStrChoiceParam : return kOfxParamTypeStrChoice; + case eCustomParam : return kOfxParamTypeCustom ; + case eGroupParam : return kOfxParamTypeGroup ; + case ePageParam : return kOfxParamTypePage ; + case ePushButtonParam : return kOfxParamTypePushButton ; + case eParametricParam : return kOfxParamTypeParametric ; + default: assert(false); + } + return kOfxParamTypeInteger; + } + + static + bool isEqual(const char* t1, const char* t2) + { + return strcmp(t1, t2)==0; + } + + static + ParamTypeEnum mapParamTypeStringToEnum(const char * v) + { + if(isEqual(kOfxParamTypeString,v)) + return eStringParam ; + else if(isEqual(kOfxParamTypeInteger,v)) + return eIntParam ; + else if(isEqual(kOfxParamTypeInteger2D,v)) + return eInt2DParam ; + else if(isEqual(kOfxParamTypeInteger3D,v)) + return eInt3DParam ; + else if(isEqual(kOfxParamTypeDouble,v)) + return eDoubleParam ; + else if(isEqual(kOfxParamTypeDouble2D,v)) + return eDouble2DParam ; + else if(isEqual(kOfxParamTypeDouble3D,v)) + return eDouble3DParam ; + else if(isEqual(kOfxParamTypeRGB,v)) + return eRGBParam ; + else if(isEqual(kOfxParamTypeRGBA,v)) + return eRGBAParam ; + else if(isEqual(kOfxParamTypeBoolean,v)) + return eBooleanParam ; + else if(isEqual(kOfxParamTypeChoice,v)) + return eChoiceParam ; + else if (isEqual(kOfxParamTypeStrChoice, v)) + return eStrChoiceParam; + else if(isEqual(kOfxParamTypeCustom ,v)) + return eCustomParam ; + else if(isEqual(kOfxParamTypeGroup,v)) + return eGroupParam ; + else if(isEqual(kOfxParamTypePage,v)) + return ePageParam ; + else if(isEqual(kOfxParamTypePushButton,v)) + return ePushButtonParam ; + else if(isEqual(kOfxParamTypeParametric,v)) + return eParametricParam ; + else + assert(false); + return ePushButtonParam ; + } + + //////////////////////////////////////////////////////////////////////////////// + // the base class for all param descriptors + + /** @brief ctor */ + ParamDescriptor::ParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props) + : _paramName(name) + , _paramType(type) + , _paramProps(props) + { + // validate the properities on this descriptor + if(type != eDummyParam) + OFX::Validation::validateParameterProperties(type, props, true); + } + + ParamDescriptor::~ParamDescriptor() + { + } + + /** @brief set the label property */ + void + ParamDescriptor::setLabel(const std::string &label) + { + _paramProps.propSetString(kOfxPropLabel, label); + } + + /** @brief set the label properties */ + void + ParamDescriptor::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel) + { + setLabel(label); + _paramProps.propSetString(kOfxPropShortLabel, shortLabel, false); + _paramProps.propSetString(kOfxPropLongLabel, longLabel, false); + } + + /** @brief set the param hint */ + void + ParamDescriptor::setHint(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropHint, v, false); + } + + /** @brief set the script name, default is the name it was defined with */ + void + ParamDescriptor::setScriptName(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropScriptName, v, false); + } + + /** @brief set the secretness of the param, defaults to false */ + void + ParamDescriptor::setIsSecret(bool v) + { + _paramProps.propSetInt(kOfxParamPropSecret, v); + } + + /** @brief set the if the param is enabled, defaults to true */ + void + ParamDescriptor::setEnabled(bool v) + { + _paramProps.propSetInt(kOfxParamPropEnabled, v); + } + + /** @brief set the group param that is the parent of this one, default is to be ungrouped at the root level */ + void + ParamDescriptor::setParent(const GroupParamDescriptor &v) + { + _paramProps.propSetString(kOfxParamPropParent, v.getName()); + } + + /** @brief set the icon file name (SVG or PNG) */ + void + ParamDescriptor::setIcon(const std::string &v, bool pngFormat) + { + _paramProps.propSetString(kOfxPropIcon, v, (int)pngFormat, false); // introduced in OFX 1.2 + } + + bool + ParamDescriptor::getHostHasNativeOverlayHandle() const + { + bool v = _paramProps.propGetInt(kOfxParamPropHasHostOverlayHandle, 0, false) != 0; // OFX 1.2 + return v; + } + + void + ParamDescriptor::setUseHostNativeOverlayHandle(bool use) + { + _paramProps.propSetInt(kOfxParamPropUseHostOverlayHandle, use, 0, false); // OFX 1.2 + } + + //////////////////////////////////////////////////////////////////////////////// + // the base class for all params that can hold a value + + /** @brief ctor */ + ValueParamDescriptor::ValueParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props) + : ParamDescriptor(name, type, props) + { + } + + /** @brief dtor */ + ValueParamDescriptor::~ValueParamDescriptor() + { + } + + /** @brief set whether the param can animate, defaults to true in most cases */ + void ValueParamDescriptor::setAnimates(bool v) + { + _paramProps.propSetInt(kOfxParamPropAnimates, v); + } + + /** @brief set whether the param is persistant, defaults to true */ + void ValueParamDescriptor::setIsPersistant(bool v) + { + _paramProps.propSetInt(kOfxParamPropPersistant, v); + } + + /** @brief Set's whether the value of the param is significant (ie: affects the rendered image), defaults to true */ + void ValueParamDescriptor::setEvaluateOnChange(bool v) + { + _paramProps.propSetInt(kOfxParamPropEvaluateOnChange, v); + } + + /** @brief Set's whether the value of the param is significant (ie: affects the rendered image), defaults to true */ + void ValueParamDescriptor::setCanUndo(bool v) + { + _paramProps.propSetInt(kOfxParamPropCanUndo, v, 0, false); + } + + /** @brief Set's how any cache should be invalidated if the parameter is changed, defaults to eCacheInvalidateValueChange */ + void ValueParamDescriptor::setCacheInvalidation(CacheInvalidationEnum v) + { + switch(v) + { + case eCacheInvalidateValueChange : + _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateValueChange); + break; + + case eCacheInvalidateValueChangeToEnd : + _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateValueChangeToEnd); + break; + + case eCacheInvalidateValueAll : + _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateAll); + break; + } + } + + void ValueParamDescriptor::setInteractDescriptor(ParamInteractDescriptor* desc) + { + _interact.reset(desc); + _paramProps.propSetPointer(kOfxParamPropInteractV1, (void*)desc->getMainEntry()); + desc->setParamName(getName()); + } + + //////////////////////////////////////////////////////////////////////////////// + // int param descriptor + + /** @brief ctor */ + IntParamDescriptor::IntParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eIntParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + IntParamDescriptor::setDefault(int v) + { + _paramProps.propSetInt(kOfxParamPropDefault, v); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + IntParamDescriptor::setRange(int min, int max) + { + _paramProps.propSetInt(kOfxParamPropMin, min); + _paramProps.propSetInt(kOfxParamPropMax, max); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + IntParamDescriptor::setDisplayRange(int min, int max) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, min); + _paramProps.propSetInt(kOfxParamPropDisplayMax, max); + } + + //////////////////////////////////////////////////////////////////////////////// + // 2D int param descriptor + + /** @brief ctor */ + Int2DParamDescriptor::Int2DParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eInt2DParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + Int2DParamDescriptor::setDefault(int x, int y) + { + _paramProps.propSetInt(kOfxParamPropDefault, x, 0); + _paramProps.propSetInt(kOfxParamPropDefault, y, 1); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int2DParamDescriptor::setRange(int xmin, int ymin, + int xmax, int ymax) + { + _paramProps.propSetInt(kOfxParamPropMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropMax, ymax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int2DParamDescriptor::setDisplayRange(int xmin, int ymin, + int xmax, int ymax) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMax, ymax, 1); + } + + void Int2DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0, false); + _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1, false); + } + + //////////////////////////////////////////////////////////////////////////////// + // 3D int param descriptor + + /** @brief ctor */ + Int3DParamDescriptor::Int3DParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eInt3DParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + Int3DParamDescriptor::setDefault(int x, int y, int z) + { + _paramProps.propSetInt(kOfxParamPropDefault, x, 0); + _paramProps.propSetInt(kOfxParamPropDefault, y, 1); + _paramProps.propSetInt(kOfxParamPropDefault, z, 2); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int3DParamDescriptor::setRange(int xmin, int ymin, int zmin, + int xmax, int ymax, int zmax) + { + _paramProps.propSetInt(kOfxParamPropMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropMin, zmin, 2); + _paramProps.propSetInt(kOfxParamPropMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropMax, ymax, 1); + _paramProps.propSetInt(kOfxParamPropMax, zmax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int3DParamDescriptor::setDisplayRange(int xmin, int ymin, int zmin, + int xmax, int ymax, int zmax) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMin, zmin, 2); + _paramProps.propSetInt(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMax, ymax, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMax, zmax, 2); + } + + void Int3DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y, const std::string& z) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0, false); + _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1, false); + _paramProps.propSetString(kOfxParamPropDimensionLabel, z, 2, false); + } + + //////////////////////////////////////////////////////////////////////////////// + // base class for all double param descriptors + + /** @brief hidden constructor */ + BaseDoubleParamDescriptor::BaseDoubleParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props) + : ValueParamDescriptor(name, type, props) + { + } + + /** @brief set the type of the double param, defaults to eDoubleTypePlain */ + void BaseDoubleParamDescriptor::setDoubleType(DoubleTypeEnum v) + { + switch(v) + { + case eDoubleTypePlain : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypePlain); + break; + case eDoubleTypeAngle : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeAngle); + break; + case eDoubleTypeScale : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeScale); + break; + case eDoubleTypeTime : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeTime); + break; + case eDoubleTypeAbsoluteTime : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeAbsoluteTime); + break; + case eDoubleTypeX : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeX); + break; + case eDoubleTypeXAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXAbsolute); + break; + case eDoubleTypeY : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeY); + break; + case eDoubleTypeYAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeYAbsolute); + break; + case eDoubleTypeXY : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXY); + break; + case eDoubleTypeXYAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXYAbsolute); + break; +#ifdef kOfxParamDoubleTypeNormalisedX + case eDoubleTypeNormalisedX : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedX); + break; + case eDoubleTypeNormalisedY : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedY); + break; + case eDoubleTypeNormalisedXAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXAbsolute); + break; + case eDoubleTypeNormalisedYAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedYAbsolute); + break; + case eDoubleTypeNormalisedXY : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXY); + break; + case eDoubleTypeNormalisedXYAbsolute : + _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXYAbsolute); + break; +#endif + } + } + + /** @brief set the type of coordinate system for default values */ + void BaseDoubleParamDescriptor::setDefaultCoordinateSystem(DefaultCoordinateSystemEnum v) + { + try { + // this property was introduced with OpenFX 1.2 + switch(v) + { + case eCoordinatesCanonical : + _paramProps.propSetString(kOfxParamPropDefaultCoordinateSystem, kOfxParamCoordinatesCanonical); + break; + case eCoordinatesNormalised : + _paramProps.propSetString(kOfxParamPropDefaultCoordinateSystem, kOfxParamCoordinatesNormalised); + break; + } + } catch (std::exception&) { + } + } + + /** @brief set the sensitivity of any gui slider */ + void BaseDoubleParamDescriptor::setIncrement(double v) + { + _paramProps.propSetDouble(kOfxParamPropIncrement, v); + } + + /** @brief set the number of digits printed after a decimal point in any gui */ + void BaseDoubleParamDescriptor::setDigits(int v) + { + _paramProps.propSetInt(kOfxParamPropDigits, v); + } + + //////////////////////////////////////////////////////////////////////////////// + // double param descriptor + + /** @brief ctor */ + DoubleParamDescriptor::DoubleParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : BaseDoubleParamDescriptor(name, eDoubleParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + DoubleParamDescriptor::setDefault(double v) + { + _paramProps.propSetDouble(kOfxParamPropDefault, v); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + DoubleParamDescriptor::setRange(double min, double max) + { + _paramProps.propSetDouble(kOfxParamPropMin, min); + _paramProps.propSetDouble(kOfxParamPropMax, max); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + DoubleParamDescriptor::setDisplayRange(double min, double max) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, min); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, max); + } + + //////////////////////////////////////////////////////////////////////////////// + // 2D double param descriptor + + /** @brief ctor */ + Double2DParamDescriptor::Double2DParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : BaseDoubleParamDescriptor(name, eDouble2DParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + Double2DParamDescriptor::setDefault(double x, double y) + { + _paramProps.propSetDouble(kOfxParamPropDefault, x, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, y, 1); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + Double2DParamDescriptor::setRange(double xmin, double ymin, + double xmax, double ymax) + { + _paramProps.propSetDouble(kOfxParamPropMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, ymax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double2DParamDescriptor::setDisplayRange(double xmin, double ymin, + double xmax, double ymax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, ymax, 1); + } + + void Double2DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0); + _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1); + } + + /** @brief set kOfxParamPropUseHostOverlayHandle */ + void Double2DParamDescriptor::setUseHostOverlayHandle(bool v) + { + _paramProps.propSetInt(kOfxParamPropUseHostOverlayHandle, v); + } + + //////////////////////////////////////////////////////////////////////////////// + // 3D double param descriptor + + /** @brief ctor */ + Double3DParamDescriptor::Double3DParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : BaseDoubleParamDescriptor(name, eDouble3DParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void + Double3DParamDescriptor::setDefault(double x, double y, double z) + { + _paramProps.propSetDouble(kOfxParamPropDefault, x, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, y, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, z, 2); + } + + /** @brief set the hard min/max range, default is -DBL_MAX, DBL_MAX */ + void + Double3DParamDescriptor::setRange(double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax) + { + _paramProps.propSetDouble(kOfxParamPropMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropMin, zmin, 2); + _paramProps.propSetDouble(kOfxParamPropMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, ymax, 1); + _paramProps.propSetDouble(kOfxParamPropMax, zmax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double3DParamDescriptor::setDisplayRange(double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, zmin, 2); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, ymax, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, zmax, 2); + } + + void Double3DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y, const std::string& z) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0); + _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1); + _paramProps.propSetString(kOfxParamPropDimensionLabel, z, 2); + } + + //////////////////////////////////////////////////////////////////////////////// + // RGB param descriptor + + /** @brief hidden constructor */ + RGBParamDescriptor::RGBParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eRGBParam, props) + { + } + + /** @brief set the default value */ + void RGBParamDescriptor::setDefault(double r, double g, double b) + { + _paramProps.propSetDouble(kOfxParamPropDefault, r, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, g, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, b, 2); + } + + /** @brief set the hard min/max range, default is 0., 1. */ + void + RGBParamDescriptor::setRange(double rmin, double gmin, double bmin, + double rmax, double gmax, double bmax) + { + _paramProps.propSetDouble(kOfxParamPropMin, rmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, gmin, 1); + _paramProps.propSetDouble(kOfxParamPropMin, bmin, 2); + _paramProps.propSetDouble(kOfxParamPropMax, rmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, gmax, 1); + _paramProps.propSetDouble(kOfxParamPropMax, bmax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + RGBParamDescriptor::setDisplayRange(double rmin, double gmin, double bmin, + double rmax, double gmax, double bmax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, rmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, gmin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, bmin, 2); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, rmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, gmax, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, bmax, 2); + } + + void RGBParamDescriptor::setDimensionLabels(const std::string& r, const std::string& g, const std::string& b) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, r, 0); + _paramProps.propSetString(kOfxParamPropDimensionLabel, g, 1); + _paramProps.propSetString(kOfxParamPropDimensionLabel, b, 2); + } + + //////////////////////////////////////////////////////////////////////////////// + // RGBA param descriptor + + /** @brief hidden constructor */ + RGBAParamDescriptor::RGBAParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eRGBAParam, props) + { + } + + /** @brief set the default value */ + void RGBAParamDescriptor::setDefault(double r, double g, double b, double a) + { + _paramProps.propSetDouble(kOfxParamPropDefault, r, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, g, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, b, 2); + _paramProps.propSetDouble(kOfxParamPropDefault, a, 3); + } + + + /** @brief set the hard min/max range, default is 0., 1. */ + void + RGBAParamDescriptor::setRange(double rmin, double gmin, double bmin, double amin, + double rmax, double gmax, double bmax, double amax) + { + _paramProps.propSetDouble(kOfxParamPropMin, rmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, gmin, 1); + _paramProps.propSetDouble(kOfxParamPropMin, bmin, 2); + _paramProps.propSetDouble(kOfxParamPropMin, amin, 3); + _paramProps.propSetDouble(kOfxParamPropMax, rmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, gmax, 1); + _paramProps.propSetDouble(kOfxParamPropMax, bmax, 2); + _paramProps.propSetDouble(kOfxParamPropMax, amax, 3); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + RGBAParamDescriptor::setDisplayRange(double rmin, double gmin, double bmin, double amin, + double rmax, double gmax, double bmax, double amax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, rmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, gmin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, bmin, 2); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, amin, 3); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, rmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, gmax, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, bmax, 2); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, amax, 3); + } + + void RGBAParamDescriptor::setDimensionLabels(const std::string& r, const std::string& g, const std::string& b, const std::string& a) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, r, 0); + _paramProps.propSetString(kOfxParamPropDimensionLabel, g, 1); + _paramProps.propSetString(kOfxParamPropDimensionLabel, b, 2); + _paramProps.propSetString(kOfxParamPropDimensionLabel, a, 3); + } + + //////////////////////////////////////////////////////////////////////////////// + // bool param descriptor + + /** @brief hidden constructor */ + BooleanParamDescriptor::BooleanParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eBooleanParam, props) + { + } + + /** @brief set the default value */ + void BooleanParamDescriptor::setDefault(bool v) + { + _paramProps.propSetInt(kOfxParamPropDefault, int(v)); + } + + //////////////////////////////////////////////////////////////////////////////// + // choice param descriptor + + /** @brief hidden constructor */ + ChoiceParamDescriptor::ChoiceParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eChoiceParam, props) + { + } + + /** @brief set the default value */ + void ChoiceParamDescriptor::setDefault(int v) + { + _paramProps.propSetInt(kOfxParamPropDefault, v); + } + + /** @brief how many options do we have */ + int ChoiceParamDescriptor::getNOptions(void) + { + int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + return nCurrentValues; + } + + /** @brief append an option to the choice param */ + void ChoiceParamDescriptor::appendOption(const std::string &v, const std::string& label, const int order) + { + int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + _paramProps.propSetString(kOfxParamPropChoiceOption, v, nCurrentValues); + if(!label.empty()) { + { + // If the kOfxParamPropChoiceLabelOption doesn't exist, we put that information into the Hint. + // It's better than nothing... + std::string hint = _paramProps.propGetString(kOfxParamPropHint); + if(!hint.empty()) { + hint += "\n"; + if( nCurrentValues == 0 ) { + hint += "\n"; + } + } + hint += v + ": " + label; + _paramProps.propSetString(kOfxParamPropHint, hint); + } + } + if (order != INT_MIN) { + // Host may not support this prop (added in 1.5); continue without it. + _paramProps.propSetInt(kOfxParamPropChoiceOrder, order, nCurrentValues, false); + } + } + + /** @brief reset all options */ + void ChoiceParamDescriptor::resetOptions(void) + { + _paramProps.propReset(kOfxParamPropChoiceOption); + } + + //////////////////////////////////////////////////////////////////////////////// + // string choice param descriptor + + /** @brief hidden constructor */ + StrChoiceParamDescriptor::StrChoiceParamDescriptor(const std::string& p_Name, OfxPropertySetHandle p_Props) + : ValueParamDescriptor(p_Name, eStrChoiceParam, p_Props) + { + } + + /** @brief set the default value */ + void StrChoiceParamDescriptor::setDefault(const std::string& p_DefaultValue) + { + _paramProps.propSetString(kOfxParamPropDefault, p_DefaultValue); + } + + /** @brief append an option */ + void StrChoiceParamDescriptor::appendOption(const std::string& p_Enum, const std::string& p_Option, int order) + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + _paramProps.propSetString(kOfxParamPropChoiceEnum, p_Enum, numOptions); + _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, numOptions); + + if (order != INT_MIN) { + // Host may not support this prop (added in 1.5); continue without it. + _paramProps.propSetInt(kOfxParamPropChoiceOrder, order, numOptions, false); + } + } + + /** @brief how many options do we have */ + int StrChoiceParamDescriptor::getNOptions() + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + return numOptions; + } + + /** @brief clear all the options so as to add some new ones in */ + void StrChoiceParamDescriptor::resetOptions(void) + { + _paramProps.propReset(kOfxParamPropChoiceEnum); + _paramProps.propReset(kOfxParamPropChoiceOption); + } + + //////////////////////////////////////////////////////////////////////////////// + // string param descriptor + + /** @brief hidden ctor */ + StringParamDescriptor::StringParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eStringParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void StringParamDescriptor::setDefault(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropDefault, v); + } + + /** @brief sets the kind of the string param, defaults to eStringSingleLine */ + void StringParamDescriptor::setStringType(StringTypeEnum v) + { + switch (v) + { + case eStringTypeSingleLine : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsSingleLine); + break; + case eStringTypeMultiLine : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsMultiLine); + break; + case eStringTypeFilePath : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsFilePath); + break; + case eStringTypeDirectoryPath : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsDirectoryPath); + break; + case eStringTypeLabel : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsLabel); + break; + case eStringTypeRichTextFormat : + _paramProps.propSetString(kOfxParamPropStringMode, kOfxParamStringIsRichTextFormat); + break; + } + } + + /** @brief if the string param is a file path, say that we are picking an existing file, defaults to true */ + void StringParamDescriptor::setFilePathExists(bool v) + { + _paramProps.propSetInt(kOfxParamPropStringFilePathExists, int(v)); + } + + //////////////////////////////////////////////////////////////////////////////// + // custom param descriptor + + /** @brief hidden ctor */ + CustomParamDescriptor::CustomParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ValueParamDescriptor(name, eCustomParam, props) + { + } + + /** @brief set the default value, default is 0 */ + void CustomParamDescriptor::setDefault(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropDefault, v); + } + + void CustomParamDescriptor::setCustomInterpolation(bool v) + { + _paramProps.propSetPointer(kOfxParamPropCustomInterpCallbackV1, v ? (void*)OFX::Private::customParamInterpolationV1Entry : NULL); + } + + //////////////////////////////////////////////////////////////////////////////// + // group param descriptor + + /** @brief hidden constructor */ + GroupParamDescriptor::GroupParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ParamDescriptor(name, eGroupParam, props) + { + } + + /** @brief whether the initial state of a group is open or closed in a hierarchical layout, defaults to true */ + void GroupParamDescriptor::setOpen(const bool v) + { + _paramProps.propSetInt(kOfxParamPropGroupOpen, v, false); // introduced in OFX 1.2 + } + + //////////////////////////////////////////////////////////////////////////////// + // page param descriptor + + /** @brief hidden constructor */ + PageParamDescriptor::PageParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ParamDescriptor(name, ePageParam, props) + { + } + + /** @brief adds a child parameter. Note the two existing pseudo params, gColumnSkip and gRowSkip */ + void PageParamDescriptor::addChild(const ParamDescriptor &p) + { + int nKids = _paramProps.propGetDimension(kOfxParamPropPageChild); + _paramProps.propSetString(kOfxParamPropPageChild, p.getName(), nKids); + } + + //////////////////////////////////////////////////////////////////////////////// + // pushbutton param descriptor + + /** @brief hidden constructor */ + PushButtonParamDescriptor::PushButtonParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ParamDescriptor(name, ePushButtonParam, props) + { + } + + //////////////////////////////////////////////////////////////////////////////// + // parametric param descriptor + + /** @brief hidden constructor */ + ParametricParamDescriptor::ParametricParamDescriptor(const std::string &name, OfxPropertySetHandle props) + : ParamDescriptor(name, eParametricParam, props) + , _ofxParamHandle(0) + , _paramSet(0) + { + } + + void ParametricParamDescriptor::setParamSet(ParamSetDescriptor& paramSet) + { + _paramSet = ¶mSet; + OFX::Private::gParamSuite->paramGetHandle(_paramSet->getParamSetHandle(), getName().c_str(), &_ofxParamHandle, 0); + } + + void ParametricParamDescriptor::setRange(const double min, const double max) + { + _paramProps.propSetDouble(kOfxParamPropParametricRange, min, 0); + _paramProps.propSetDouble(kOfxParamPropParametricRange, max, 1); + } + + void ParametricParamDescriptor::setDimension(const int dimension) + { + _paramProps.propSetInt(kOfxParamPropParametricDimension, dimension); + } + + void ParametricParamDescriptor::setDimensionLabel(const std::string& label, const int id) + { + _paramProps.propSetString(kOfxParamPropDimensionLabel, label, id); + } + + void ParametricParamDescriptor::setUIColour(const int id, const OfxRGBColourD& color) + { + _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.r, id*3 + 0); + _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.g, id*3 + 1); + _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.b, id*3 + 2); + } + + void ParametricParamDescriptor::addControlPoint(const int id, const OfxTime time, const double x, const double y, const bool addKey) + { + OFX::Private::gParametricParameterSuite->parametricParamAddControlPoint(_ofxParamHandle, id, time, x, y, addKey); + } + + void ParametricParamDescriptor::setIdentity(const int id) + { + addControlPoint(id, 0, 0, 0, false); + addControlPoint(id, 0, 1, 1, false); + } + + void ParametricParamDescriptor::setIdentity() + { + const int nbCurves = _paramProps.propGetInt(kOfxParamPropParametricDimension); + for(int i = 0; i < nbCurves; ++i) { + setIdentity(i); + } + } + + void ParametricParamDescriptor::setInteractDescriptor(ParamInteractDescriptor* desc) + { + _interact.reset(desc); + _paramProps.propSetPointer(kOfxParamPropParametricInteractBackground, (void*)desc->getMainEntry()); + desc->setParamName(getName()); + } + + //////////////////////////////////////////////////////////////////////////////// + // Descriptor for a set of parameters + /** @brief hidden ctor */ + ParamSetDescriptor::ParamSetDescriptor(void) + : _paramSetHandle(0) + { + } + + ParamDescriptor* ParamSetDescriptor::getParamDescriptor(const std::string& name) const + { + std::map::const_iterator it = _definedParams.find(name); + if(it!=_definedParams.end()) + return it->second; + return 0; + } + + /** @brief set the param set handle */ + void + ParamSetDescriptor::setParamSetHandle(OfxParamSetHandle h) + { + // set me handle + _paramSetHandle = h; + + if(h) { + // fetch me props + OfxPropertySetHandle props; + OfxStatus stat = OFX::Private::gParamSuite->paramSetGetPropertySet(h, &props); + _paramSetProps.propSetHandle(props); + throwSuiteStatusException(stat); + } + else { + _paramSetProps.propSetHandle(0); + } + } + + /** @brief dtor */ + ParamSetDescriptor::~ParamSetDescriptor() + { + // delete any descriptor we may have constructed + std::map::iterator iter; + for(iter = _definedParams.begin(); iter != _definedParams.end(); ++iter) { + if(iter->second) { + delete iter->second; + iter->second = NULL; + } + } + } + + /** @brief estabilishes the order of page params. Do it by calling it in turn for each page */ + void + ParamSetDescriptor::setPageParamOrder(PageParamDescriptor &p) + { + int nPages = _paramSetProps.propGetDimension(kOfxPluginPropParamPageOrder); + _paramSetProps.propSetString(kOfxPluginPropParamPageOrder, p.getName().c_str(), nPages); + } + + + /** @brief calls the raw OFX routine to define a param */ + void ParamSetDescriptor::defineRawParam(const std::string &name, ParamTypeEnum paramType, OfxPropertySetHandle &props) + { + OfxStatus stat = OFX::Private::gParamSuite->paramDefine(_paramSetHandle, mapParamTypeEnumToString(paramType), name.c_str(), &props); + throwSuiteStatusException(stat); + } + + /** @brief if a param has been defined in this set, go find it */ + ParamDescriptor * + ParamSetDescriptor::findPreviouslyDefinedParam(const std::string &name) + { + // search + std::map::const_iterator search; + search = _definedParams.find(name); + if(search == _definedParams.end()) + return NULL; + return search->second; + } + + /** @brief Define an integer param, only callable from describe in context */ + IntParamDescriptor * + ParamSetDescriptor::defineIntParam(const std::string &name) + { + IntParamDescriptor *param = NULL; + defineParamDescriptor(name, eIntParam, param); + return param; + } + + /** @brief Define a 2D integer param */ + Int2DParamDescriptor *ParamSetDescriptor::defineInt2DParam(const std::string &name) + { + Int2DParamDescriptor *param = NULL; + defineParamDescriptor(name, eInt2DParam, param); + return param; + } + + /** @brief Define a 3D integer param */ + Int3DParamDescriptor *ParamSetDescriptor::defineInt3DParam(const std::string &name) + { + Int3DParamDescriptor *param = NULL; + defineParamDescriptor(name, eInt3DParam, param); + return param; + } + + /** @brief Define an double param, only callable from describe in context */ + DoubleParamDescriptor * + ParamSetDescriptor::defineDoubleParam(const std::string &name) + { + DoubleParamDescriptor *param = NULL; + defineParamDescriptor(name, eDoubleParam, param); + return param; + } + + /** @brief Define a 2D double param */ + Double2DParamDescriptor *ParamSetDescriptor::defineDouble2DParam(const std::string &name) + { + Double2DParamDescriptor *param = NULL; + defineParamDescriptor(name, eDouble2DParam, param); + return param; + } + + /** @brief Define a 3D double param */ + Double3DParamDescriptor *ParamSetDescriptor::defineDouble3DParam(const std::string &name) + { + Double3DParamDescriptor *param = NULL; + defineParamDescriptor(name, eDouble3DParam, param); + return param; + } + + /** @brief Define a string param */ + StringParamDescriptor *ParamSetDescriptor::defineStringParam(const std::string &name) + { + StringParamDescriptor *param = NULL; + defineParamDescriptor(name, eStringParam, param); + return param; + } + + /** @brief Define a RGBA param */ + RGBAParamDescriptor *ParamSetDescriptor::defineRGBAParam(const std::string &name) + { + RGBAParamDescriptor *param = NULL; + defineParamDescriptor(name, eRGBAParam, param); + return param; + } + + /** @brief Define an RGB param */ + RGBParamDescriptor *ParamSetDescriptor::defineRGBParam(const std::string &name) + { + RGBParamDescriptor *param = NULL; + defineParamDescriptor(name, eRGBParam, param); + return param; + } + + /** @brief Define a Boolean param */ + BooleanParamDescriptor *ParamSetDescriptor::defineBooleanParam(const std::string &name) + { + BooleanParamDescriptor *param = NULL; + defineParamDescriptor(name, eBooleanParam, param); + return param; + } + + /** @brief Define a Choice param */ + ChoiceParamDescriptor *ParamSetDescriptor::defineChoiceParam(const std::string &name) + { + ChoiceParamDescriptor *param = NULL; + defineParamDescriptor(name, eChoiceParam, param); + return param; + } + + /** @brief Define a String Choice param */ + StrChoiceParamDescriptor* ParamSetDescriptor::defineStrChoiceParam(const std::string& p_Name) + { + StrChoiceParamDescriptor* param = NULL; + defineParamDescriptor(p_Name, eStrChoiceParam, param); + return param; + } + + /** @brief Define a group param */ + GroupParamDescriptor *ParamSetDescriptor::defineGroupParam(const std::string &name) + { + GroupParamDescriptor *param = NULL; + defineParamDescriptor(name, eGroupParam, param); + return param; + } + + /** @brief Define a Page param */ + PageParamDescriptor *ParamSetDescriptor::definePageParam(const std::string &name) + { + PageParamDescriptor *param = NULL; + defineParamDescriptor(name, ePageParam, param); + return param; + } + + /** @brief Define a push button param */ + PushButtonParamDescriptor *ParamSetDescriptor::definePushButtonParam(const std::string &name) + { + PushButtonParamDescriptor *param = NULL; + defineParamDescriptor(name, ePushButtonParam, param); + return param; + } + + /** @brief Define a parametric param */ + ParametricParamDescriptor* ParamSetDescriptor::defineParametricParam(const std::string &name) + { + ParametricParamDescriptor* param = NULL; + if (defineParamDescriptor(name, eParametricParam, param)) { + // Parametric parameters need the ParamSet ! + param->setParamSet(*this); + } + return param; + } + + /** @brief Define a custom param */ + CustomParamDescriptor *ParamSetDescriptor::defineCustomParam(const std::string &name) + { + CustomParamDescriptor *param = NULL; + defineParamDescriptor(name, eCustomParam, param); + return param; + } + + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Base class for all param instances */ + Param::Param(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle) + : _paramSet(paramSet) + , _paramName(name) + , _paramType(type) + , _paramHandle(handle) + { + // fetch our property handle + OfxPropertySetHandle propHandle; + OfxStatus stat = OFX::Private::gParamSuite->paramGetPropertySet(handle, &propHandle); + throwSuiteStatusException(stat); + _paramProps.propSetHandle(propHandle); + + // and validate the properties + OFX::Validation::validateParameterProperties(type, _paramProps, false); + } + + /** @brief dtor */ + Param::~Param() + { + } + + /** @brief get name */ + const std::string &Param::getName(void) const + { + return _paramName; + } + + /** @brief, set the label properties in a param */ + void Param::setLabel(const std::string &label) + { + _paramProps.propSetString(kOfxPropLabel, label); + } + + /** @brief, set the label properties in a param */ + void Param::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel) + { + setLabel(label); + _paramProps.propSetString(kOfxPropShortLabel, shortLabel, false); + _paramProps.propSetString(kOfxPropLongLabel, longLabel, false); + } + + /** @brief set the secretness of the param, defaults to false */ + void Param::setIsSecret(bool v) + { + _paramProps.propSetInt(kOfxParamPropSecret, v); + } + + /** @brief set the param hint */ + void Param::setHint(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropHint, v, false); + } + + /** @brief whether the param is enabled */ + void Param::setEnabled(bool v) + { + _paramProps.propSetInt(kOfxParamPropEnabled, v); + } + + /** @brief set the private data pointer */ + void Param::setDataPtr(void* ptr) + { + _paramProps.propSetPointer(kOfxParamPropDataPtr, ptr); + } + + /** @brief fetch the label */ + void Param::getLabel(std::string &label) const + { + label = _paramProps.propGetString(kOfxPropLabel); + } + + /** @brief fetch the labels */ + void Param::getLabels(std::string &label, std::string &shortLabel, std::string &longLabel) const + { + getLabel(label); + shortLabel = _paramProps.propGetString(kOfxPropShortLabel, false); + longLabel = _paramProps.propGetString(kOfxPropLongLabel, false); + } + + /** @brief get whether the param is secret */ + bool Param::getIsSecret(void) const + { + bool v = _paramProps.propGetInt(kOfxParamPropSecret) != 0; + return v; + } + + /** @brief whether the param is enabled */ + bool Param::getIsEnable(void) const + { + bool v = _paramProps.propGetInt(kOfxParamPropEnabled) != 0; + return v; + } + + /** @brief get the private data pointer */ + void* Param::getDataPtr(void) const + { + return _paramProps.propGetPointer(kOfxParamPropDataPtr); + } + + /** @brief get the param hint */ + std::string Param::getHint(void) const + { + std::string v = _paramProps.propGetString(kOfxParamPropHint, false); + return v; + } + + /** @brief get the script name */ + std::string Param::getScriptName(void) const + { + std::string v = _paramProps.propGetString(kOfxParamPropScriptName, false); + return v; + } + + /** @brief get the group param that is the parent of this one */ + GroupParam *Param::getParent(void) const + { + std::string v = _paramProps.propGetString(kOfxParamPropParent); + if(v == "") return NULL; + return _paramSet->fetchGroupParam(v); + } + + /** @brief get the icon file name (SVG or PNG) */ + std::string Param::getIcon(bool pngFormat) const + { + std::string v = _paramProps.propGetString(kOfxPropIcon, (int)pngFormat, false); // OFX 1.2 + return v; + } + + bool Param::getHostHasNativeOverlayHandle() const + { + bool v = _paramProps.propGetInt(kOfxParamPropHasHostOverlayHandle, 0, false) != 0; // OFX 1.2 + return v; + } + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a value holding param */ + + /** @brief hidden constructor */ + ValueParam::ValueParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle) + : Param(paramSet, name, type, handle) + { + } + + /** @brief dtor */ + ValueParam::~ValueParam() + { + } + + /** @brief Set's whether the value of the param is significant (ie: affects the rendered image) */ + void + ValueParam::setEvaluateOnChange(bool v) + { + _paramProps.propSetInt(kOfxParamPropEvaluateOnChange, v); + } + + /** @brief is the param animating */ + bool + ValueParam::getIsAnimating(void) const + { + return _paramProps.propGetInt(kOfxParamPropIsAnimating) != 0; + } + + /** @brief is the param auto keing */ + bool + ValueParam::getIsAutoKeying(void) const + { + return _paramProps.propGetInt(kOfxParamPropIsAutoKeying) != 0; + } + + /** @brief is the param persistant */ + bool + ValueParam::getIsPersistant(void) const + { + return _paramProps.propGetInt(kOfxParamPropPersistant) != 0; + } + + /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */ + bool + ValueParam::getEvaluateOnChange(void) const + { + return _paramProps.propGetInt(kOfxParamPropEvaluateOnChange) != 0; + } + + /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */ + CacheInvalidationEnum + ValueParam::getCacheInvalidation(void) const + { + std::string v = _paramProps.propGetString(kOfxParamPropCacheInvalidation); + if(v == kOfxParamInvalidateValueChange) + return eCacheInvalidateValueChange; + else if(v == kOfxParamInvalidateValueChangeToEnd) + return eCacheInvalidateValueChangeToEnd; + else // if(v == kOfxParamInvalidateAll) + return eCacheInvalidateValueAll; + } + + /** @brief if the param is animating, the number of keys in it, otherwise 0 */ + unsigned int + ValueParam::getNumKeys(void) + { + if(!OFX::Private::gParamSuite->paramGetNumKeys) throwHostMissingSuiteException("paramGetNumKeys"); + unsigned int v = 0; + OfxStatus stat = OFX::Private::gParamSuite->paramGetNumKeys(_paramHandle, &v); + throwSuiteStatusException(stat); + return v; + } + + /** @brief get the time of the nth key, nth must be between 0 and getNumKeys-1 */ + double + ValueParam::getKeyTime(int nthKey) + { + if(!OFX::Private::gParamSuite->paramGetKeyTime) throwHostMissingSuiteException("paramGetKeyTime"); + double v = 0; + OfxStatus stat = OFX::Private::gParamSuite->paramGetKeyTime(_paramHandle, nthKey, &v); + + // oops? + if(stat == kOfxStatFailed) throw std::out_of_range("ValueParam::getKeyTime key index out of range"); + throwSuiteStatusException(stat); + return v; + } + + /** @brief find the index of a key by a time */ + int + ValueParam::getKeyIndex(double time, + KeySearchEnum searchDir) + { + if(!OFX::Private::gParamSuite->paramGetKeyIndex) throwHostMissingSuiteException("paramGetKeyIndex"); + int v = 0; + + // turn enum into -1,0,1 + int dir = searchDir == eKeySearchBackwards ? -1 : (searchDir == eKeySearchNear ? 0 : 1); + + // call raw param function + OfxStatus stat = OFX::Private::gParamSuite->paramGetKeyIndex(_paramHandle, time, dir, &v); + + // oops? + if(stat == kOfxStatFailed) return -1; // if search failed, return -1 + throwSuiteStatusException(stat); + return v; + } + + /** @brief deletes a key at the given time */ + void + ValueParam::deleteKeyAtTime(double time) + { + if(!OFX::Private::gParamSuite->paramDeleteKey) throwHostMissingSuiteException("paramDeleteKey"); + OfxStatus stat = OFX::Private::gParamSuite->paramDeleteKey(_paramHandle, time); + if(stat == kOfxStatFailed) return; // if no key at time, fail quietly + throwSuiteStatusException(stat); + } + + /** @brief delete all the keys */ + void + ValueParam::deleteAllKeys(void) + { + if(!OFX::Private::gParamSuite->paramDeleteAllKeys) throwHostMissingSuiteException("paramDeleteAllKeys"); + OfxStatus stat = OFX::Private::gParamSuite->paramDeleteAllKeys(_paramHandle); + throwSuiteStatusException(stat); + } + + /** @brief copy parameter from another, including any animation etc... */ + void ValueParam::copyFrom(const ValueParam& from, OfxTime dstOffset, const OfxRangeD *frameRange) + { + if(!OFX::Private::gParamSuite->paramCopy) throwHostMissingSuiteException("paramCopy"); + OfxStatus stat = OFX::Private::gParamSuite->paramCopy(_paramHandle, from._paramHandle, dstOffset, frameRange); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up an integer param */ + + /** @brief hidden constructor */ + IntParam::IntParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eIntParam, handle) + { + } + + /** @brief set the default value */ + void IntParam::setDefault(int v) + { + _paramProps.propSetInt(kOfxParamPropDefault, v); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void IntParam::setRange(int min, int max) + { + _paramProps.propSetInt(kOfxParamPropMin, min); + _paramProps.propSetInt(kOfxParamPropMax, max); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void IntParam::setDisplayRange(int min, int max) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, min); + _paramProps.propSetInt(kOfxParamPropDisplayMax, max); + } + + /** @brief get the default value */ + void IntParam::getDefault(int &v) + { + v = _paramProps.propGetInt(kOfxParamPropDefault); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void IntParam::getRange(int &min, int &max) + { + min = _paramProps.propGetInt(kOfxParamPropMin); + max = _paramProps.propGetInt(kOfxParamPropMax); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void IntParam::getDisplayRange(int &min, int &max) + { + min = _paramProps.propGetInt(kOfxParamPropDisplayMin); + max = _paramProps.propGetInt(kOfxParamPropDisplayMax); + } + + /** @brief get value */ + void IntParam::getValue(int &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void IntParam::getValueAtTime(double t, int &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void IntParam::setValue(int v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void IntParam::setValueAtTime(double t, int v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // 2D Int params + + /** @brief hidden constructor */ + Int2DParam::Int2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eInt2DParam, handle) + { + } + + /** @brief set the default value */ + void Int2DParam::setDefault(int x, int y) + { + _paramProps.propSetInt(kOfxParamPropDefault, x, 0); + _paramProps.propSetInt(kOfxParamPropDefault, y, 1); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int2DParam::setRange(int xmin, int ymin, + int xmax, int ymax) + { + _paramProps.propSetInt(kOfxParamPropMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropMax, ymax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int2DParam::setDisplayRange(int xmin, int ymin, + int xmax, int ymax) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMax, ymax, 1); + } + + /** @brief het the default value */ + void Int2DParam::getDefault(int &x, int &y) + { + x = _paramProps.propGetInt(kOfxParamPropDefault, 0); + y = _paramProps.propGetInt(kOfxParamPropDefault, 1); + } + + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int2DParam::getRange(int &xmin, int &ymin, + int &xmax, int &ymax) + { + xmin = _paramProps.propGetInt(kOfxParamPropMin, 0); + ymin = _paramProps.propGetInt(kOfxParamPropMin, 1); + xmax = _paramProps.propGetInt(kOfxParamPropMax, 0); + ymax = _paramProps.propGetInt(kOfxParamPropMax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int2DParam::getDisplayRange(int &xmin, int &ymin, + int &xmax, int &ymax) + { + xmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 0); + ymin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 1); + xmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 0); + ymax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 1); + } + + /** @brief get value */ + void Int2DParam::getValue(int &x, int &y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Int2DParam::getValueAtTime(double t, int &x, int &y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void Int2DParam::setValue(int x, int y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void Int2DParam::setValueAtTime(double t, int x, int y) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y); + throwSuiteStatusException(stat); + } + + + //////////////////////////////////////////////////////////////////////////////// + // 3D Int params + + /** @brief hidden constructor */ + Int3DParam::Int3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eInt3DParam, handle) + { + } + + /** @brief set the default value */ + void Int3DParam::setDefault(int x, int y, int z) + { + _paramProps.propSetInt(kOfxParamPropDefault, x, 0); + _paramProps.propSetInt(kOfxParamPropDefault, y, 1); + _paramProps.propSetInt(kOfxParamPropDefault, z, 2); + } + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int3DParam::setRange(int xmin, int ymin, int zmin, + int xmax, int ymax, int zmax) + { + _paramProps.propSetInt(kOfxParamPropMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropMin, zmin, 2); + _paramProps.propSetInt(kOfxParamPropMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropMax, ymax, 1); + _paramProps.propSetInt(kOfxParamPropMax, zmax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int3DParam::setDisplayRange(int xmin, int ymin, int zmin, + int xmax, int ymax, int zmax) + { + _paramProps.propSetInt(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMin, zmin, 2); + _paramProps.propSetInt(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetInt(kOfxParamPropDisplayMax, ymax, 1); + _paramProps.propSetInt(kOfxParamPropDisplayMax, zmax, 2); + } + + /** @brief get the default value */ + void Int3DParam::getDefault(int &x, int &y, int &z) + { + x = _paramProps.propGetInt(kOfxParamPropDefault, 0); + y = _paramProps.propGetInt(kOfxParamPropDefault, 1); + z = _paramProps.propGetInt(kOfxParamPropDefault, 2); + } + + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void + Int3DParam::getRange(int &xmin, int &ymin, int &zmin, + int &xmax, int &ymax, int &zmax) + { + xmin = _paramProps.propGetInt(kOfxParamPropMin, 0); + ymin = _paramProps.propGetInt(kOfxParamPropMin, 1); + zmin = _paramProps.propGetInt(kOfxParamPropMin, 2); + xmax = _paramProps.propGetInt(kOfxParamPropMax, 0); + ymax = _paramProps.propGetInt(kOfxParamPropMax, 1); + zmax = _paramProps.propGetInt(kOfxParamPropMax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Int3DParam::getDisplayRange(int &xmin, int &ymin, int &zmin, + int &xmax, int &ymax, int &zmax) + { + xmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 0); + ymin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 1); + zmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 2); + xmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 0); + ymax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 1); + zmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 2); + } + + /** @brief get value */ + void Int3DParam::getValue(int &x, int &y, int &z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y, &z); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Int3DParam::getValueAtTime(double t, int &x, int &y, int &z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y, &z); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void Int3DParam::setValue(int x, int y, int z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y, z); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void Int3DParam::setValueAtTime(double t, int x, int y, int z) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y, z); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // common base to all double params + + /** @brief hidden constructor */ + BaseDoubleParam::BaseDoubleParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle) + : ValueParam(paramSet, name, type, handle) + { + } + + /** @brief set the sensitivity of any gui slider */ + void BaseDoubleParam::setIncrement(double v) + { + _paramProps.propSetDouble(kOfxParamPropIncrement, v); + } + + /** @brief set the number of digits printed after a decimal point in any gui */ + void BaseDoubleParam::setDigits(int v) + { + _paramProps.propSetInt(kOfxParamPropDigits, v); + } + + /** @brief get the sensitivity of any gui slider */ + void BaseDoubleParam::getIncrement(double &v) + { + v = _paramProps.propGetDouble(kOfxParamPropIncrement); + } + + /** @brief get the number of digits printed after a decimal point in any gui */ + void BaseDoubleParam::getDigits(int &v) + { + v = _paramProps.propGetInt(kOfxParamPropDigits); + } + + /** @brief get the type of the double param, defaults to eDoubleTypePlain */ + void BaseDoubleParam::getDoubleType(DoubleTypeEnum &v) + { + std::string str = _paramProps.propGetString(kOfxParamPropDoubleType); + + if(str == kOfxParamDoubleTypePlain) + v = eDoubleTypePlain; + else if(str == kOfxParamDoubleTypeAngle) + v = eDoubleTypeAngle; + else if(str == kOfxParamDoubleTypeScale) + v = eDoubleTypeScale; + else if(str == kOfxParamDoubleTypeTime) + v = eDoubleTypeTime; + else if(str == kOfxParamDoubleTypeAbsoluteTime) + v = eDoubleTypeAbsoluteTime; + else if(str == kOfxParamDoubleTypeX) + v = eDoubleTypeX; + else if(str == kOfxParamDoubleTypeXAbsolute) + v = eDoubleTypeXAbsolute; + else if(str == kOfxParamDoubleTypeY) + v = eDoubleTypeY; + else if(str == kOfxParamDoubleTypeYAbsolute) + v = eDoubleTypeYAbsolute; + else if(str == kOfxParamDoubleTypeXY) + v = eDoubleTypeXY; + else if(str == kOfxParamDoubleTypeXYAbsolute) + v = eDoubleTypeXYAbsolute; +#ifdef kOfxParamDoubleTypeNormalisedX + else if(str == kOfxParamDoubleTypeNormalisedX) + v = eDoubleTypeNormalisedX; + else if(str == kOfxParamDoubleTypeNormalisedY) + v = eDoubleTypeNormalisedY; + else if(str == kOfxParamDoubleTypeNormalisedXAbsolute) + v = eDoubleTypeNormalisedXAbsolute; + else if(str == kOfxParamDoubleTypeNormalisedYAbsolute) + v = eDoubleTypeNormalisedYAbsolute; + else if(str == kOfxParamDoubleTypeNormalisedXY) + v = eDoubleTypeNormalisedXY; + else if(str == kOfxParamDoubleTypeNormalisedXYAbsolute) + v = eDoubleTypeNormalisedXYAbsolute; +#endif + else + v = eDoubleTypePlain; + } + + /** @brief get the type of coordinate system for default values */ + void BaseDoubleParam::getDefaultCoordinateSystem(DefaultCoordinateSystemEnum &v) + { + std::string str = _paramProps.propGetString(kOfxParamPropDefaultCoordinateSystem); + + if(str == kOfxParamCoordinatesNormalised) + v = eCoordinatesNormalised; + else + v = eCoordinatesCanonical; + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up an double param */ + + /** @brief hidden constructor */ + DoubleParam::DoubleParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : BaseDoubleParam(paramSet, name, eDoubleParam, handle) + { + } + + /** @brief set the default value */ + void DoubleParam::setDefault(double v) + { + _paramProps.propSetDouble(kOfxParamPropDefault, v); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void DoubleParam::setRange(double min, double max) + { + _paramProps.propSetDouble(kOfxParamPropMin, min); + _paramProps.propSetDouble(kOfxParamPropMax, max); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void DoubleParam::setDisplayRange(double min, double max) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, min); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, max); + } + + /** @brief get the default value */ + void DoubleParam::getDefault(double &v) + { + v = _paramProps.propGetDouble(kOfxParamPropDefault); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void DoubleParam::getRange(double &min, double &max) + { + min = _paramProps.propGetDouble(kOfxParamPropMin); + max = _paramProps.propGetDouble(kOfxParamPropMax); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void DoubleParam::getDisplayRange(double &min, double &max) + { + min = _paramProps.propGetDouble(kOfxParamPropDisplayMin); + max = _paramProps.propGetDouble(kOfxParamPropDisplayMax); + } + + /** @brief get value */ + void DoubleParam::getValue(double &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void DoubleParam::getValueAtTime(double t, double &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void DoubleParam::setValue(double v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void DoubleParam::setValueAtTime(double t, double v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void DoubleParam::differentiate(double t, double &v) + { + if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &v); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void DoubleParam::integrate(double t1, double t2, double &v) + { + if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &v); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // 2D Double params + + /** @brief hidden constructor */ + Double2DParam::Double2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : BaseDoubleParam(paramSet, name, eDouble2DParam, handle) + { + } + + /** @brief set the default value */ + void Double2DParam::setDefault(double x, double y) + { + _paramProps.propSetDouble(kOfxParamPropDefault, x, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, y, 1); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + Double2DParam::setRange(double xmin, double ymin, + double xmax, double ymax) + { + _paramProps.propSetDouble(kOfxParamPropMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, ymax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double2DParam::setDisplayRange(double xmin, double ymin, + double xmax, double ymax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, ymax, 1); + } + + /** @brief get the default value */ + void Double2DParam::getDefault(double &x, double &y) + { + x = _paramProps.propGetDouble(kOfxParamPropDefault, 0); + y = _paramProps.propGetDouble(kOfxParamPropDefault, 1); + } + + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + Double2DParam::getRange(double &xmin, double &ymin, + double &xmax, double &ymax) + { + xmin = _paramProps.propGetDouble(kOfxParamPropMin, 0); + ymin = _paramProps.propGetDouble(kOfxParamPropMin, 1); + xmax = _paramProps.propGetDouble(kOfxParamPropMax, 0); + ymax = _paramProps.propGetDouble(kOfxParamPropMax, 1); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double2DParam::getDisplayRange(double &xmin, double &ymin, + double &xmax, double &ymax) + { + xmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 0); + ymin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 1); + xmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 0); + ymax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 1); + } + + /** @brief get value */ + void Double2DParam::getValue(double &x, double &y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double2DParam::getValueAtTime(double t, double &x, double &y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void Double2DParam::setValue(double x, double y) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void Double2DParam::setValueAtTime(double t, double x, double y) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double2DParam::differentiate(double t, double &x, double &y) + { + if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &x, &y); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double2DParam::integrate(double t1, double t2, double &x, double &y) + { + if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &x, &y); + throwSuiteStatusException(stat); + } + + + //////////////////////////////////////////////////////////////////////////////// + // 3D Double params + + /** @brief hidden constructor */ + Double3DParam::Double3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : BaseDoubleParam(paramSet, name, eDouble3DParam, handle) + { + } + + /** @brief set the default value */ + void Double3DParam::setDefault(double x, double y, double z) + { + _paramProps.propSetDouble(kOfxParamPropDefault, x, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, y, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, z, 2); + } + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + Double3DParam::setRange(double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax) + { + _paramProps.propSetDouble(kOfxParamPropMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropMin, zmin, 2); + _paramProps.propSetDouble(kOfxParamPropMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropMax, ymax, 1); + _paramProps.propSetDouble(kOfxParamPropMax, zmax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double3DParam::setDisplayRange(double xmin, double ymin, double zmin, + double xmax, double ymax, double zmax) + { + _paramProps.propSetDouble(kOfxParamPropDisplayMin, xmin, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, ymin, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMin, zmin, 2); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, xmax, 0); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, ymax, 1); + _paramProps.propSetDouble(kOfxParamPropDisplayMax, zmax, 2); + } + + /** @brief get the default value */ + void Double3DParam::getDefault(double &x, double &y, double &z) + { + x = _paramProps.propGetDouble(kOfxParamPropDefault, 0); + y = _paramProps.propGetDouble(kOfxParamPropDefault, 1); + z = _paramProps.propGetDouble(kOfxParamPropDefault, 2); + } + + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void + Double3DParam::getRange(double &xmin, double &ymin, double &zmin, + double &xmax, double &ymax, double &zmax) + { + xmin = _paramProps.propGetDouble(kOfxParamPropMin, 0); + ymin = _paramProps.propGetDouble(kOfxParamPropMin, 1); + zmin = _paramProps.propGetDouble(kOfxParamPropMin, 2); + xmax = _paramProps.propGetDouble(kOfxParamPropMax, 0); + ymax = _paramProps.propGetDouble(kOfxParamPropMax, 1); + zmax = _paramProps.propGetDouble(kOfxParamPropMax, 2); + } + + /** @brief set the display min and max, default is to be the same as the range param */ + void + Double3DParam::getDisplayRange(double &xmin, double &ymin, double &zmin, + double &xmax, double &ymax, double &zmax) + { + xmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 0); + ymin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 1); + zmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 2); + xmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 0); + ymax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 1); + zmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 2); + } + + /** @brief get value */ + void Double3DParam::getValue(double &x, double &y, double &z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y, &z); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double3DParam::getValueAtTime(double t, double &x, double &y, double &z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y, &z); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void Double3DParam::setValue(double x, double y, double z) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y, z); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void Double3DParam::setValueAtTime(double t, double x, double y, double z) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y, z); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double3DParam::differentiate(double t, double &x, double &y, double &z) + { + if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &x, &y, &z); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void Double3DParam::integrate(double t1, double t2, double &x, double &y, double &z) + { + if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral"); + OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &x, &y, &z); + throwSuiteStatusException(stat); + } + //////////////////////////////////////////////////////////////////////////////// + // RGB colour param + /** @brief hidden constructor */ + RGBParam::RGBParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eRGBParam, handle) + { + } + + /** @brief set the default value */ + void RGBParam::setDefault(double r, double g, double b) + { + _paramProps.propSetDouble(kOfxParamPropDefault, r, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, g, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, b, 2); + } + + + /** @brief get the default value */ + void RGBParam::getDefault(double &r, double &g, double &b) + { + r = _paramProps.propGetDouble(kOfxParamPropDefault, 0); + g = _paramProps.propGetDouble(kOfxParamPropDefault, 1); + b = _paramProps.propGetDouble(kOfxParamPropDefault, 2); + } + + /** @brief get value */ + void RGBParam::getValue(double &r, double &g, double &b) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &r, &g, &b); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void RGBParam::getValueAtTime(double t, double &r, double &g, double &b) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &r, &g, &b); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void RGBParam::setValue(double r, double g, double b) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, r, g, b); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void RGBParam::setValueAtTime(double t, double r, double g, double b) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, r, g, b); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // RGBA colour param + /** @brief hidden constructor */ + RGBAParam::RGBAParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eRGBAParam, handle) + { + } + + /** @brief set the default value */ + void RGBAParam::setDefault(double r, double g, double b, double a) + { + _paramProps.propSetDouble(kOfxParamPropDefault, r, 0); + _paramProps.propSetDouble(kOfxParamPropDefault, g, 1); + _paramProps.propSetDouble(kOfxParamPropDefault, b, 2); + _paramProps.propSetDouble(kOfxParamPropDefault, a, 3); + } + + + /** @brief get the default value */ + void RGBAParam::getDefault(double &r, double &g, double &b, double &a) + { + r = _paramProps.propGetDouble(kOfxParamPropDefault, 0); + g = _paramProps.propGetDouble(kOfxParamPropDefault, 1); + b = _paramProps.propGetDouble(kOfxParamPropDefault, 2); + a = _paramProps.propGetDouble(kOfxParamPropDefault, 3); + } + + /** @brief get value */ + void RGBAParam::getValue(double &r, double &g, double &b, double &a) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &r, &g, &b, &a); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void RGBAParam::getValueAtTime(double t, double &r, double &g, double &b, double &a) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &r, &g, &b, &a); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void RGBAParam::setValue(double r, double g, double b, double a) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, r, g, b, a); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void RGBAParam::setValueAtTime(double t, double r, double g, double b, double a) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, r, g, b, a); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a string param */ + + /** @brief hidden constructor */ + StringParam::StringParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eStringParam, handle) + { + } + + /** @brief set the default value */ + void StringParam::setDefault(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropDefault, v); + } + + /** @brief get the default value */ + void StringParam::getDefault(std::string &v) + { + v = _paramProps.propGetString(kOfxParamPropDefault); + } + + /** @brief get value */ + void StringParam::getValue(std::string &v) + { + char *cStr; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &cStr); + throwSuiteStatusException(stat); + v = cStr; + } + + /** @brief get the value at a time */ + void StringParam::getValueAtTime(double t, std::string &v) + { + char *cStr; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &cStr); + throwSuiteStatusException(stat); + v = cStr; + } + + /** @brief set value */ + void StringParam::setValue(const std::string &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v.c_str()); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void StringParam::setValueAtTime(double t, const std::string &v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v.c_str()); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a Boolean integer param */ + + /** @brief hidden constructor */ + BooleanParam::BooleanParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eBooleanParam, handle) + { + } + + /** @brief set the default value */ + void BooleanParam::setDefault(bool v) + { + _paramProps.propSetInt(kOfxParamPropDefault, v); + } + + /** @brief get the default value */ + void BooleanParam::getDefault(bool &v) + { + v = _paramProps.propGetInt(kOfxParamPropDefault) != 0; + } + + /** @brief get value */ + void BooleanParam::getValue(bool &v) + { + int iVal; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &iVal); + throwSuiteStatusException(stat); + v = iVal != 0; + } + + /** @brief get the value at a time */ + void BooleanParam::getValueAtTime(double t, bool &v) + { + int iVal; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &iVal); + throwSuiteStatusException(stat); + v = iVal != 0; + } + + /** @brief set value */ + void BooleanParam::setValue(bool v) + { + int iVal = v; + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, iVal); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void BooleanParam::setValueAtTime(double t, bool v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + int iVal = v; + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, iVal); + throwSuiteStatusException(stat); + } + + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a choice integer param */ + + /** @brief hidden constructor */ + ChoiceParam::ChoiceParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eChoiceParam, handle) + { + } + + /** @brief set the default value */ + void ChoiceParam::setDefault(int v) + { + _paramProps.propSetInt(kOfxParamPropDefault, v); + } + + /** @brief get the default value */ + void ChoiceParam::getDefault(int &v) + { + v = _paramProps.propGetInt(kOfxParamPropDefault); + } + + /** @brief get value */ + void ChoiceParam::getValue(int &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v); + throwSuiteStatusException(stat); + } + + /** @brief get the value at a time */ + void ChoiceParam::getValueAtTime(double t, int &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void ChoiceParam::setValue(int v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void ChoiceParam::setValueAtTime(double t, int v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v); + throwSuiteStatusException(stat); + } + + /** @brief how many options do we have */ + int ChoiceParam::getNOptions(void) + { + int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + return nCurrentValues; + } + + /** @brief get the option value */ + void ChoiceParam::getOption(int ix, std::string &v) + { + v = _paramProps.propGetString(kOfxParamPropChoiceOption, ix); + } + + /** @brief add another option */ + void ChoiceParam::appendOption(const std::string &v, const std::string& label, const int order) + { + int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + _paramProps.propSetString(kOfxParamPropChoiceOption, v, nCurrentValues); + if(!label.empty()) { + { + // If the kOfxParamPropChoiceLabelOption doesn't exist, we put that information into the Hint. + // It's better than nothing... + std::string hint = _paramProps.propGetString(kOfxParamPropHint); + if(!hint.empty()) { + hint += "\n"; + if( nCurrentValues == 0 ) { + hint += "\n"; + } + } + hint += v + ": " + label; + _paramProps.propSetString(kOfxParamPropHint, hint); + } + } + if (order >= 0) { + // Host may not support this prop (added in 1.5); continue without it. + _paramProps.propSetInt(kOfxParamPropChoiceOrder, order, false); + } + } + + /** @brief set the string of a specific option */ + void ChoiceParam::setOption(int item, const std::string &str) + { + _paramProps.propSetString(kOfxParamPropChoiceOption, str, item); + } + + /** @brief set to the default value */ + void ChoiceParam::resetOptions(void) + { + _paramProps.propReset(kOfxParamPropChoiceOption); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a string choice param */ + + /** @brief hidden constructor */ + StrChoiceParam::StrChoiceParam(const ParamSet* p_ParamSet, const std::string& p_Name, OfxParamHandle p_Handle) + : StringParam(p_ParamSet, p_Name, p_Handle) + { + _paramType = eStrChoiceParam; + } + + /** @brief how many options do we have */ + int StrChoiceParam::getNOptions() + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + return numOptions; + } + + /** @brief add another option */ + void StrChoiceParam::appendOption(const std::string& p_Enum, const std::string& p_Option, int order) + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + _paramProps.propSetString(kOfxParamPropChoiceEnum, p_Enum, numOptions); + _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, numOptions); + + if (order != INT_MIN) { + // Host may not support this prop (added in 1.5); continue without it. + _paramProps.propSetInt(kOfxParamPropChoiceOrder, order, numOptions, false); + } + } + + /** @brief set the string of a specific option */ + void StrChoiceParam::setOption(const std::string& p_Index, const std::string& p_Option) + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + for (int i = 0; i < numOptions; ++i) + { + const std::string& enumStr = _paramProps.propGetString(kOfxParamPropChoiceEnum, i); + if (enumStr == p_Index) + { + _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, i); + + return; + } + } + + throwSuiteStatusException(kOfxStatErrBadIndex); + } + + /** @brief get the option value */ + void StrChoiceParam::getOption(const std::string& p_Index, std::string& p_Option) + { + const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption); + assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum)); + + for (int i = 0; i < numOptions; ++i) + { + const std::string& enumStr = _paramProps.propGetString(kOfxParamPropChoiceEnum, i); + if (enumStr == p_Index) + { + p_Option = _paramProps.propGetString(kOfxParamPropChoiceOption, i); + + return; + } + } + + throwSuiteStatusException(kOfxStatErrBadIndex); + } + + /** @brief set to the default value */ + void StrChoiceParam::resetOptions() + { + _paramProps.propReset(kOfxParamPropChoiceEnum); + _paramProps.propReset(kOfxParamPropChoiceOption); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a custom param */ + + /** @brief hidden constructor */ + CustomParam::CustomParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : ValueParam(paramSet, name, eCustomParam, handle) + { + } + + /** @brief set the default value */ + void CustomParam::setDefault(const std::string &v) + { + _paramProps.propSetString(kOfxParamPropDefault, v); + } + + /** @brief get the default value */ + void CustomParam::getDefault(std::string &v) + { + v = _paramProps.propGetString(kOfxParamPropDefault); + } + + /** @brief get value */ + void CustomParam::getValue(std::string &v) + { + char *cStr; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &cStr); + throwSuiteStatusException(stat); + v = cStr; + } + + /** @brief get the value at a time */ + void CustomParam::getValueAtTime(double t, std::string &v) + { + char *cStr; + OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &cStr); + throwSuiteStatusException(stat); + v = cStr; + } + + /** @brief set value */ + void CustomParam::setValue(const std::string &v) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v.c_str()); + throwSuiteStatusException(stat); + } + + /** @brief set value */ + void CustomParam::setValue(const char* str) + { + OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, str); + throwSuiteStatusException(stat); + } + + /** @brief set the value at a time, implicitly adds a keyframe */ + void CustomParam::setValueAtTime(double t, const std::string &v) + { + if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime"); + OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v.c_str()); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a group param + /** @brief hidden constructor */ + GroupParam::GroupParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : Param(paramSet, name, eGroupParam, handle) + { + } + + /** @brief whether the initial state of a group is open or closed in a hierarchical layout, defaults to true */ + bool GroupParam::getIsOpen() + { + bool v = _paramProps.propGetInt(kOfxParamPropGroupOpen) != 0; + return v; + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a page param + + /** @brief hidden constructor */ + PageParam::PageParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : Param(paramSet, name, ePageParam, handle) + { + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a PushButton param + + /** @brief hidden constructor */ + PushButtonParam::PushButtonParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle) + : Param(paramSet, name, ePushButtonParam, handle) + { + } + + //////////////////////////////////////////////////////////////////////////////// + // Wraps up a Parametric param + + /** @brief hidden constructor */ + ParametricParam::ParametricParam(const ParamSet* paramSet, const std::string &name, OfxParamHandle handle) + : Param(paramSet, name, eParametricParam, handle) + {} + + /** @brief Evaluates a parametric parameter + + \arg curveIndex which dimension to evaluate + \arg time the time to evaluate to the parametric param at + \arg parametricPosition the position to evaluate the parametric param at + + @returns the double value is returned + */ + double ParametricParam::getValue(const int curveIndex, + const OfxTime time, + const double parametricPosition) + { + double returnValue = 0.0; + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetValue(_paramHandle, + curveIndex, + time, + parametricPosition, + &returnValue); + throwSuiteStatusException(stat); + return returnValue; + } + + /** @brief Returns the number of control points in the parametric param. + + \arg curveIndex which dimension to check + \arg time the time to check + + @returns the integer value is returned + */ + int ParametricParam::getNControlPoints(const int curveIndex, + const OfxTime time) + { + int returnValue = 0; + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetNControlPoints(_paramHandle, + curveIndex, + time, + &returnValue); + throwSuiteStatusException(stat); + return returnValue; + } + + /** @brief Returns the key/value pair of the nth control point. + + \arg curveIndex which dimension to check + \arg time the time to check + \arg nthCtl the nth control point to get the value of + + @returns a pair with key and value + */ + std::pair ParametricParam::getNthControlPoint(const int curveIndex, + const OfxTime time, + const int nthCtl) + { + std::pair returnValue; + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetNthControlPoint(_paramHandle, + curveIndex, + time, + nthCtl, + &returnValue.first, + &returnValue.second); + throwSuiteStatusException(stat); + return returnValue; + } + + /** @brief Modifies an existing control point on a curve + + \arg curveIndex which dimension to set + \arg time the time to set the value at + \arg nthCtl the control point to modify + \arg key key of the control point + \arg value value of the control point + \arg addAnimationKey if the param is an animatable, setting this to true will + force an animation keyframe to be set as well as a curve key, + otherwise if false, a key will only be added if the curve is already + animating. + + @returns + - ::kOfxStatOK - all was fine + - ::kOfxStatErrBadHandle - if the paramter handle was invalid + - ::kOfxStatErrUnknown - if the type is unknown + + This modifies an existing control point. Note that by changing key, the order of the + control point may be modified (as you may move it before or after anther point). So be + careful when iterating over a curves control points and you change a key. + */ + void ParametricParam::setNthControlPoints(const int curveIndex, + const OfxTime time, + const int nthCtl, + const double key, + const double value, + const bool addAnimationKey) + { + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamSetNthControlPoint(_paramHandle, + curveIndex, + time, + nthCtl, + key, + value, + addAnimationKey); + throwSuiteStatusException(stat); + } + + void ParametricParam::setNthControlPoints(const int curveIndex, + const OfxTime time, + const int nthCtl, + const std::pair ctrlPoint, + const bool addAnimationKey) + { + setNthControlPoints(curveIndex, + time, + nthCtl, + ctrlPoint.first, + ctrlPoint.second, + addAnimationKey); + } + + /** @brief Adds a control point to the curve. + + \arg curveIndex which dimension to set + \arg time the time to set the value at + \arg key key of the control point + \arg value value of the control point + \arg addAnimationKey if the param is an animatable, setting this to true will + force an animation keyframe to be set as well as a curve key, + otherwise if false, a key will only be added if the curve is already + animating. + + This will add a new control point to the given dimension of a parametric parameter. If a key exists + sufficiently close to 'key', then it will be set to the indicated control point. + */ + void ParametricParam::addControlPoint(const int curveIndex, + const OfxTime time, + const double key, + const double value, + const bool addAnimationKey) + { + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamAddControlPoint(_paramHandle, curveIndex, time, key, value, addAnimationKey); + throwSuiteStatusException(stat); + } + + /** @brief Deletes the nth control point from a parametric param. + + \arg curveIndex which dimension to delete + \arg nthCtl the control point to delete + */ + void ParametricParam::deleteControlPoint(const int curveIndex, + const int nthCtl) + { + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamDeleteControlPoint(_paramHandle, curveIndex, nthCtl); + throwSuiteStatusException(stat); + } + + /** @brief Delete all curve control points on the given param. + + \arg curveIndex which dimension to clear + */ + void ParametricParam::deleteControlPoint(const int curveIndex) + { + OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamDeleteAllControlPoints(_paramHandle, curveIndex); + throwSuiteStatusException(stat); + } + + //////////////////////////////////////////////////////////////////////////////// + // for a set of parameters + /** @brief hidden ctor */ + ParamSet::ParamSet(void) + : _paramSetHandle(0) + { + } + + /** @brief set the param set handle */ + void + ParamSet::setParamSetHandle(OfxParamSetHandle h) + { + // set me handle + _paramSetHandle = h; + + if(h) { + // fetch me props + OfxPropertySetHandle props; + OfxStatus stat = OFX::Private::gParamSuite->paramSetGetPropertySet(h, &props); + _paramSetProps.propSetHandle(props); + throwSuiteStatusException(stat); + } + else { + _paramSetProps.propSetHandle(0); + } + } + + /** @brief dtor */ + ParamSet::~ParamSet() + { + // delete any descriptor we may have constructed + std::map::iterator iter; + for(iter = _fetchedParams.begin(); iter != _fetchedParams.end(); ++iter) { + if(iter->second) { + delete iter->second; + iter->second = NULL; + } + } + } + + /** @brief calls the raw OFX routine to fetch a param */ + void ParamSet::fetchRawParam(const std::string &name, ParamTypeEnum paramType, OfxParamHandle &handle) const + { + OfxPropertySetHandle propHandle; + + OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle); + throwSuiteStatusException(stat); + + PropertySet props(propHandle); + + // make sure it is of our type + std::string paramTypeStr = props.propGetString(kOfxParamPropType); + if(paramTypeStr != mapParamTypeEnumToString(paramType)) { + throw OFX::Exception::TypeRequest("Parameter exists but is of the wrong type"); + } + } + + ParamTypeEnum ParamSet::getParamType(const std::string& name) const + { + OfxPropertySetHandle propHandle; + OfxParamHandle handle; + OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle); + throwSuiteStatusException(stat); + PropertySet props(propHandle); + // make sure it is of our type + std::string paramTypeStr = props.propGetString(kOfxParamPropType); + return mapParamTypeStringToEnum(paramTypeStr.c_str()); + } + + bool ParamSet::paramExists(const std::string& name) const + { + OfxParamHandle handle; + OfxPropertySetHandle propHandle; + OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle); + if(stat!=kOfxStatOK) + return false; + return true; + } + + Param* ParamSet::getParam(const std::string& name) const + { + OfxParamHandle handle; + OfxPropertySetHandle propHandle; + OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle); + throwSuiteStatusException(stat); + + PropertySet props(propHandle); + + // make sure it is of our type + std::string paramTypeStr = props.propGetString(kOfxParamPropType); + ParamTypeEnum t = mapParamTypeStringToEnum(paramTypeStr.c_str()); + switch(t) + { + case eStringParam : + { + StringParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eIntParam : + { + IntParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eInt2DParam : + { + Int2DParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eInt3DParam : + { + Int3DParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eDoubleParam : + { + DoubleParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eDouble2DParam : + { + Double2DParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eDouble3DParam : + { + Double3DParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eRGBParam : + { + RGBParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eRGBAParam : + { + RGBAParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eBooleanParam : + { + BooleanParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eChoiceParam : + { + ChoiceParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eStrChoiceParam : + { + StrChoiceParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eCustomParam : + { + CustomParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eGroupParam : + { + GroupParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case ePageParam : + { + PageParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case ePushButtonParam : + { + PushButtonParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + case eParametricParam : + { + ParametricParam* ptr = 0; + fetchParam(name, t, ptr); + return ptr; + } + default: + assert(false); + } + return 0; + } + + /** @brief if a param has been fetched in this set, go find it */ + Param * + ParamSet::findPreviouslyFetchedParam(const std::string &name) const + { + // search + std::map::const_iterator search; + search = _fetchedParams.find(name); + if(search == _fetchedParams.end()) + return NULL; + return search->second; + } + + /** @brief Fetch an integer param, only callable from describe in context */ + IntParam * + ParamSet::fetchIntParam(const std::string &name) const + { + IntParam *param = NULL; + fetchParam(name, eIntParam, param); + return param; + } + + /** @brief Fetch a 2D integer param */ + Int2DParam *ParamSet::fetchInt2DParam(const std::string &name) const + { + Int2DParam *param = NULL; + fetchParam(name, eInt2DParam, param); + return param; + } + + /** @brief Fetch a 3D integer param */ + Int3DParam *ParamSet::fetchInt3DParam(const std::string &name) const + { + Int3DParam *param = NULL; + fetchParam(name, eInt3DParam, param); + return param; + } + + /** @brief Fetch an double param, only callable from describe in context */ + DoubleParam * + ParamSet::fetchDoubleParam(const std::string &name) const + { + DoubleParam *param = NULL; + fetchParam(name, eDoubleParam, param); + return param; + } + + /** @brief Fetch a 2D double param */ + Double2DParam *ParamSet::fetchDouble2DParam(const std::string &name) const + { + Double2DParam *param = NULL; + fetchParam(name, eDouble2DParam, param); + return param; + } + + /** @brief Fetch a 3D double param */ + Double3DParam *ParamSet::fetchDouble3DParam(const std::string &name) const + { + Double3DParam *param = NULL; + fetchParam(name, eDouble3DParam, param); + return param; + } + + /** @brief Fetch a string param */ + StringParam *ParamSet::fetchStringParam(const std::string &name) const + { + StringParam *param = NULL; + fetchParam(name, eStringParam, param); + return param; + } + + /** @brief Fetch a RGBA param */ + RGBAParam *ParamSet::fetchRGBAParam(const std::string &name) const + { + RGBAParam *param = NULL; + fetchParam(name, eRGBAParam, param); + return param; + } + + /** @brief Fetch an RGB param */ + RGBParam *ParamSet::fetchRGBParam(const std::string &name) const + { + RGBParam *param = NULL; + fetchParam(name, eRGBParam, param); + return param; + } + + /** @brief Fetch a Boolean param */ + BooleanParam *ParamSet::fetchBooleanParam(const std::string &name) const + { + BooleanParam *param = NULL; + fetchParam(name, eBooleanParam, param); + return param; + } + + /** @brief Fetch a Choice param */ + ChoiceParam *ParamSet::fetchChoiceParam(const std::string &name) const + { + ChoiceParam *param = NULL; + fetchParam(name, eChoiceParam, param); + return param; + } + + /** @brief Fetch a StrChoice param */ + StrChoiceParam* ParamSet::fetchStrChoiceParam(const std::string& p_Name) const + { + StrChoiceParam* param = NULL; + fetchParam(p_Name, eStrChoiceParam, param); + return param; + } + + /** @brief Fetch a group param */ + GroupParam *ParamSet::fetchGroupParam(const std::string &name) const + { + GroupParam *param = NULL; + fetchParam(name, eGroupParam, param); + return param; + } + + /** @brief Fetch a Page param */ + PageParam *ParamSet::fetchPageParam(const std::string &name) const + { + PageParam *param = NULL; + fetchParam(name, ePageParam, param); + return param; + } + + /** @brief Fetch a push button param */ + PushButtonParam *ParamSet::fetchPushButtonParam(const std::string &name) const + { + PushButtonParam *param = NULL; + fetchParam(name, ePushButtonParam, param); + return param; + } + + /** @brief Fetch a custom param */ + CustomParam *ParamSet::fetchCustomParam(const std::string &name) const + { + CustomParam *param = NULL; + fetchParam(name, eCustomParam, param); + return param; + } + + /** @brief Fetch a parametric param */ + ParametricParam *ParamSet::fetchParametricParam(const std::string &name) const + { + ParametricParam *param = NULL; + fetchParam(name, eParametricParam, param); + return param; + } + + /// open an undoblock + void ParamSet::beginEditBlock(const std::string &name) + { + OfxStatus stat = OFX::Private::gParamSuite->paramEditBegin(_paramSetHandle, name.c_str()); + (void)stat; + } + + /// close an undoblock + void ParamSet::endEditBlock() + { + OfxStatus stat = OFX::Private::gParamSuite->paramEditEnd(_paramSetHandle); + (void)stat; + } + +}; diff --git a/third_party/openfx/Support/Library/ofxsProperty.cpp b/third_party/openfx/Support/Library/ofxsProperty.cpp new file mode 100644 index 000000000..e3afee5ee --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsProperty.cpp @@ -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 PropertySet::propGetNString(const char* property, bool throwOnFailure) const + { + assert(_propHandle != 0); + std::list ret; + int dimension = propGetDimension(property,throwOnFailure); + if (dimension <= 0) { + return ret; + } + std::vector 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; + + } + +}; diff --git a/third_party/openfx/Support/Library/ofxsPropertyValidation.cpp b/third_party/openfx/Support/Library/ofxsPropertyValidation.cpp new file mode 100644 index 000000000..356253106 --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsPropertyValidation.cpp @@ -0,0 +1,1313 @@ + + +/** @file + +This file contains headers for classes that are used to validate property sets and make sure they have the right members and default values. + +*/ + +#include "ofxsSupportPrivate.h" +#include +#ifdef OFX_SUPPORTS_OPENGLRENDER +#include "ofxGPURender.h" +#endif + +/** @brief Null pointer definition */ +#define NULLPTR ((void *)(0)) + +// #define kOfxsDisableValidation + +// disable validation if not a debug build +#ifndef DEBUG +#define kOfxsDisableValidation +#endif + +//#define kOfxsDisableValidation +/** @brief OFX namespace +*/ +namespace OFX { + + /** @brief The validation code has its own namespace */ + namespace Validation { + +#ifndef kOfxsDisableValidation + /** @brief Set the vector by getting dimension things specified by ilk from the argp list, used by PropertyDescription ctor */ + static void + setVectorFromVarArgs(OFX::PropertyTypeEnum ilk, + int dimension, + va_list &argp, + std::vector &vec) + { + char *vS; + int vI; + double vD; + void *vP; + for(int i = 0; i < dimension; i++) { + switch (ilk) + { + case eString : + vS = va_arg(argp, char *); + vec.push_back(vS); + break; + + case eInt : + vI = va_arg(argp, int); + vec.push_back(vI); + break; + + case ePointer : + vP = va_arg(argp, void *); + vec.push_back(vP); + break; + + case eDouble : + vD = va_arg(argp, double); + vec.push_back(vD); + break; + } + } + } + + + /** @brief PropertyDescription var-args constructor */ + PropertyDescription::PropertyDescription(const char *name, OFX::PropertyTypeEnum ilk, int dimension, ...) + : _name(name) + , _exists(false) // only set when we have validated it + , _dimension(dimension) + , _ilk(ilk) + { + // go through the var args to extract defaults to check against and values to set to + va_list argp; + va_start(argp, dimension); + + bool going = true; + while(going) { + // what is being set ? + DescriptionTag tag = DescriptionTag(va_arg(argp, int)); + + switch (tag) + { + case eDescDefault : // we are setting default values to check against + setVectorFromVarArgs(ilk, dimension, argp, _defaultValue); + break; + + case eDescFinished : // we are finished + default : + going = false; + break; + } + } + + va_end(argp); + } + + + /** @brief See if the property exists in the containing property set and has the correct dimension */ + void + PropertyDescription::validate(bool checkDefaults, + PropertySet &propSet) + { + // see if it exists by fetching the dimension, + + try { + int hostDimension = propSet.propGetDimension(_name.c_str()); + _exists = true; + + if(_dimension != -1) // -1 implies variable dimension + OFX::Log::error(hostDimension != _dimension, "Host reports property '%s' has dimension %d, it should be %d;", _name.c_str(), hostDimension, _dimension); + // check type by getting the first element, the property getting will print any failure messages to the log + if(hostDimension > 0) { + switch(_ilk) + { + case OFX::ePointer : { void *vP = propSet.propGetPointer(_name.c_str()); (void)vP; }break; + case OFX::eInt : { int vI = propSet.propGetInt(_name.c_str()); (void)vI; } break; + case OFX::eString : { std::string vS = propSet.propGetString(_name.c_str()); (void)vS; } break; + case OFX::eDouble : { double vD = propSet.propGetDouble(_name.c_str()); (void)vD; } break; + } + } + + // check the defaults are OK, if there are any + int nDefs = (int)_defaultValue.size(); + if(checkDefaults && nDefs > 0) { + OFX::Log::error(hostDimension != nDefs, "Host reports default dimension of '%s' as %d, which is different to the default dimension size of %d;", + _name.c_str(), hostDimension, nDefs); + + int N = hostDimension < nDefs ? hostDimension : nDefs; + + for(int i = 0; i < N; i++) { + switch(_ilk) + { + case OFX::ePointer : { + void *vP = propSet.propGetPointer(_name.c_str(), i); + OFX::Log::error(vP != (void *) _defaultValue[i], "Default value of %s[%d] = %p, it should be %p;", + _name.c_str(), i, vP, (void *) _defaultValue[i]); + } + break; + case OFX::eInt : { + int vI = propSet.propGetInt(_name.c_str(), i); + OFX::Log::error(vI != (int) _defaultValue[i], "Default value of %s[%d] = %d, it should be %d;", + _name.c_str(), i, vI, (int) _defaultValue[i]); + } + break; + case OFX::eString : { + std::string vS = propSet.propGetString(_name.c_str(), i); + OFX::Log::error(vS != _defaultValue[i].vString, "Default value of %s[%d] = '%s', it should be '%s';", + _name.c_str(), i, vS.c_str(), _defaultValue[i].vString.c_str()); + } + break; + case OFX::eDouble : { + double vD = propSet.propGetDouble(_name.c_str(), i); + OFX::Log::error(vD != (double) _defaultValue[i], "Default value of %s[%d] = %g, it should be %g;", + _name.c_str(), i, vD, (double) _defaultValue[i]); + } + break; + } + } + } + } + catch (OFX::Exception::Suite &e) + { + // just catch it, the error will be reported + _exists = false; + } + catch (OFX::Exception::PropertyUnknownToHost &e) + { + // just catch it, the error will be reported + _exists = false; + } + catch (OFX::Exception::PropertyValueIllegalToHost &e) + { + // just catch it, the error will be reported + _exists = false; + } + } + + + /** @brief This macro is used to short hand passing the var args to @ref OFX::Validation::PropertySetDescription::PropertySetDescription */ +#define mPropDescriptionArg(descs) descs, sizeof(descs)/sizeof(PropertyDescription) + + /** @brief A set of property descriptions, constructor + + Passed in as a zero terminated pairs of (PropertyDescription *descArray, int nDescriptions) + + */ + PropertySetDescription::PropertySetDescription(const char *setName, ...) // PropertyDescription *v, int nV) + : _setName(setName) + { + + // go through the var args to extract defaults to check against and values to set to + va_list argp; + va_start(argp, setName); + + while(1) { + // get a pointer + PropertyDescription *descs = (PropertyDescription *) va_arg(argp, PropertyDescription *); + + // have we finished + if(!descs) break; + + // get the count + int nDescs = (int) va_arg(argp, int); + + // and set it up + for(int i = 0; i < nDescs; i++) { + _descriptions.push_back(descs + i); + } + + } + + va_end(argp); + } + + /** @brief destructor */ + PropertySetDescription::~PropertySetDescription() + { + int nToDelete = (int)_deleteThese.size(); + for(int i = 0; i < nToDelete; i++) { + delete _deleteThese[i]; + } + } + + /** @brief Add more properties into the property vector */ + void + PropertySetDescription::addProperty(PropertyDescription *desc, + bool deleteOnDestruction) + { + _descriptions.push_back(desc); + if(deleteOnDestruction) + _deleteThese.push_back(desc); + } + + /** @brief Validate all the properties in the set */ + void + PropertySetDescription::validate(PropertySet &propSet, + bool checkDefaults, + bool logOrdinaryMessages) + { + OFX::Log::print("START validating properties of %s.", _setName.c_str()); + OFX::Log::indent(); + + // don't print ordinary messages whilst we are checking them + if(!logOrdinaryMessages) PropertySet::propDisableLogging(); + + // check each property in the description + int n = (int)_descriptions.size(); + for(int i = 0; i < n; i++) + _descriptions[i]->validate(checkDefaults, propSet); + + if(!logOrdinaryMessages) PropertySet::propEnableLogging(); + + OFX::Log::outdent(); + OFX::Log::print("STOP property validation of %s.", _setName.c_str()); + } + + + /** @brief A list of properties that all hosts must have, and will be validated against. None of these has a default, but they must exist. */ + static PropertyDescription gHostProps[ ] = + { + // single dimensional string properties + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLabel, OFX::eString, 1, eDescFinished), + + // single dimensional int properties + PropertyDescription(kOfxImageEffectHostPropIsBackground, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsOverlays, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultiResolution, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsTiles, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropTemporalClipAccess, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultipleClipDepths, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultipleClipPARs, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSetableFrameRate, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSetableFielding, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsStringAnimation, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsCustomInteract, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsChoiceAnimation, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsStrChoiceAnimation, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsBooleanAnimation, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropSupportsCustomAnimation, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropMaxParameters, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamHostPropMaxPages, OFX::eInt, 1, eDescFinished), + + // variable multi dimensional string properties + PropertyDescription(kOfxImageEffectPropSupportedComponents, OFX::eString, -1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportedContexts, OFX::eString, -1, eDescFinished), + + // multi dimensional int properities + PropertyDescription(kOfxParamHostPropPageRowColumnCount, OFX::eInt, 2, eDescFinished), + }; + + /** @brief the property set for the global host pointer */ + static PropertySetDescription gHostPropSet("Host Property", + gHostProps, sizeof(gHostProps)/sizeof(PropertyDescription), + NULLPTR); + + + /** @brief A list of properties to validate the effect descriptor against */ + static PropertyDescription gPluginDescriptorProps[ ] = + { + // string props that have no defaults that can be checked against + PropertyDescription(kOfxPropLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropShortLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLongLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPluginPropGrouping, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPluginPropFilePath, OFX::eString, 1, eDescFinished), + + // string props with defaults that can be checked against + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeImageEffect, eDescFinished), + PropertyDescription(kOfxImageEffectPluginRenderThreadSafety, OFX::eString, 1, eDescDefault, kOfxImageEffectRenderFullySafe, eDescFinished), + + // int props with defaults that can be checked against + PropertyDescription(kOfxImageEffectPluginPropSingleInstance, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPluginPropHostFrameThreading, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultiResolution, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsTiles, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropTemporalClipAccess, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPluginPropFieldRenderTwiceAlways, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultipleClipDepths, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsMultipleClipPARs, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + + // Pointer props with defaults that can be checked against + PropertyDescription(kOfxImageEffectPluginPropOverlayInteractV1, OFX::ePointer, 1, eDescDefault, (void *)(0), eDescFinished), + + // string props that have variable dimension, and can't be checked against for defaults + PropertyDescription(kOfxImageEffectPropSupportedContexts, OFX::eString, -1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportedPixelDepths, OFX::eString, -1, eDescFinished), + PropertyDescription(kOfxImageEffectPropClipPreferencesSlaveParam, OFX::eString, -1, eDescFinished), + }; + + /** @brief the property set for the global plugin descriptor */ + static PropertySetDescription gPluginDescriptorPropSet("Plugin Descriptor", + gPluginDescriptorProps, sizeof(gPluginDescriptorProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief A list of properties to validate the plugin instance */ + static PropertyDescription gPluginInstanceProps[ ] = + { + // string props with defaults that can be checked against + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeImageEffectInstance, eDescFinished), + + // int props with defaults that can be checked against + PropertyDescription(kOfxImageEffectInstancePropSequentialRender, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + + // Pointer props with defaults that can be checked against + PropertyDescription(kOfxPropInstanceData, OFX::ePointer, 1, eDescDefault, (void *)(0), eDescFinished), + PropertyDescription(kOfxImageEffectPropPluginHandle, OFX::ePointer, 1, eDescFinished), + + // string props that have no defaults that can be checked against + PropertyDescription(kOfxImageEffectPropContext, OFX::eString, 1, eDescFinished), + + // int props with not defaults that can be checked against + PropertyDescription(kOfxPropIsInteractive, OFX::eInt, 1, eDescFinished), + + // double props that can't be checked against for defaults + PropertyDescription(kOfxImageEffectPropProjectSize, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropProjectExtent, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropProjectOffset, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropProjectPixelAspectRatio, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectInstancePropEffectDuration, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropFrameRate, OFX::eDouble, 1, eDescFinished), + }; + + /** @brief the property set for a plugin instance */ + static PropertySetDescription gPluginInstancePropSet("Plugin Instance", + gPluginInstanceProps, sizeof(gPluginInstanceProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief A list of properties to validate a clip descriptor */ + static PropertyDescription gClipDescriptorProps[ ] = + { + // string props with checkable defaults + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeClip, eDescFinished), + PropertyDescription(kOfxImageClipPropFieldExtraction, OFX::eString, 1, eDescDefault, kOfxImageFieldDoubled, eDescFinished), + + // string props with no checkable defaults + PropertyDescription(kOfxImageEffectPropSupportedComponents, OFX::eString,-1, eDescFinished), + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropShortLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLongLabel, OFX::eString, 1, eDescFinished), + + // int props with checkable defaults + PropertyDescription(kOfxImageEffectPropTemporalClipAccess, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageClipPropOptional, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageClipPropIsMask, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsTiles, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + }; + + /** @brief the property set for a clip descriptor */ + static PropertySetDescription gClipDescriptorPropSet("Clip Descriptor", + gClipDescriptorProps, sizeof(gClipDescriptorProps)/sizeof(PropertyDescription), + NULLPTR); + + + /** @brief A list of properties to validate a clip instance */ + static PropertyDescription gClipInstanceProps[ ] = + { + // we can only validate this one against a fixed default + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeClip, eDescFinished), + + // the rest are set by the plugin during description or by the host + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropShortLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLongLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportedComponents, OFX::eString,-1, eDescFinished), + PropertyDescription(kOfxImageClipPropFieldExtraction, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropPixelDepth, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropComponents, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropUnmappedPixelDepth, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropUnmappedComponents, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropPreMultiplication, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropFieldOrder, OFX::eString, 1, eDescFinished), + + // int props + PropertyDescription(kOfxImageEffectPropTemporalClipAccess, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropOptional, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropIsMask, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropSupportsTiles, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropConnected, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropContinuousSamples, OFX::eInt, 1, eDescFinished), + + // double props + PropertyDescription(kOfxImagePropPixelAspectRatio, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropFrameRate, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropFrameRange, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropUnmappedFrameRate, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropUnmappedFrameRange, OFX::eDouble, 2, eDescFinished), + }; + + /** @brief the property set for a clip instance */ + static PropertySetDescription gClipInstancePropSet("Clip Instance", gClipInstanceProps, sizeof(gClipInstanceProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief List of properties to validate an image or texture instance */ + static PropertyDescription gImageBaseInstanceProps[ ] = + { + // this is the only property with a checkable default + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeImage, eDescFinished), + + // all other properties are set by the host + PropertyDescription(kOfxImageEffectPropPixelDepth, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropComponents, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropPreMultiplication, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImagePropField, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImagePropUniqueIdentifier, OFX::eString, 1, eDescFinished), + + // double props + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImagePropPixelAspectRatio, OFX::eDouble, 1, eDescFinished), + + // pointer props + PropertyDescription(kOfxImagePropData, OFX::ePointer, 1, eDescFinished), + + // int props + PropertyDescription(kOfxImagePropBounds, OFX::eInt, 4, eDescFinished), + PropertyDescription(kOfxImagePropRegionOfDefinition, OFX::eInt, 4, eDescFinished), + PropertyDescription(kOfxImagePropRowBytes, OFX::eInt, 1, eDescFinished), + }; + + /** @brief the property set for an image instance */ + static PropertySetDescription gImageBaseInstancePropSet("Image or Texture Instance", + gImageBaseInstanceProps, sizeof(gImageBaseInstanceProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief List of properties to validate an image or texture instance */ + static PropertyDescription gImageInstanceProps[ ] = + { + // pointer props + PropertyDescription(kOfxImagePropData, OFX::ePointer, 1, eDescFinished), + }; + + /** @brief the property set for an image instance */ + static PropertySetDescription gImageInstancePropSet("Image Instance", + gImageInstanceProps, sizeof(gImageInstanceProps)/sizeof(PropertyDescription), + NULLPTR); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief List of properties to validate an image or texture instance */ + static PropertyDescription gTextureInstanceProps[ ] = + { + // pointer props + PropertyDescription(kOfxImageEffectPropOpenGLTextureIndex, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropOpenGLTextureTarget, OFX::eInt, 1, eDescFinished), + }; + + /** @brief the property set for an image instance */ + static PropertySetDescription gTextureInstancePropSet("Texture Instance", + gTextureInstanceProps, sizeof(gTextureInstanceProps)/sizeof(PropertyDescription), + NULLPTR); +#endif + + //////////////////////////////////////////////////////////////////////////////// + // Action in/out args properties + //////////////////////////////////////////////////////////////////////////////// + + /** @brief kOfxImageEffectActionDescribeInContext actions's inargs properties */ + static PropertyDescription gDescribeInContextActionInArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropContext, OFX::eString, 1, eDescFinished), + }; + + /** @brief the property set for describe in context action */ + static PropertySetDescription gDescribeInContextActionInArgPropSet(kOfxImageEffectActionDescribeInContext " in argument", + gDescribeInContextActionInArgProps, sizeof(gDescribeInContextActionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionRender action's inargs properties */ + static PropertyDescription gRenderActionInArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderWindow, OFX::eInt, 4, eDescFinished), + PropertyDescription(kOfxImageEffectPropFieldToRender, OFX::eString, 1, eDescFinished), + // The following appeared in OFX 1.2, and are thus not mandatory + //PropertyDescription(kOfxImageEffectPropSequentialRenderStatus, OFX::eInt, 1, eDescFinished), + //PropertyDescription(kOfxImageEffectPropInteractiveRenderStatus, OFX::eInt, 1, eDescFinished), + // The following appeared in OFX 1.4, and is thus not mandatory + //PropertyDescription(kOfxImageEffectPropRenderQualityDraft, OFX::eInt, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionRender property set */ + static PropertySetDescription gRenderActionInArgPropSet(kOfxImageEffectActionRender " in argument", + gRenderActionInArgProps, sizeof(gRenderActionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionBeginSequenceRender action's inargs properties */ + static PropertyDescription gBeginSequenceRenderActionInArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropFrameRange, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropFrameStep, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxPropIsInteractive, OFX::eInt, 1, eDescFinished), + // The following appeared in OFX 1.2, and are thus not mandatory + //PropertyDescription(kOfxImageEffectPropSequentialRenderStatus, OFX::eInt, 1, eDescFinished), + //PropertyDescription(kOfxImageEffectPropInteractiveRenderStatus, OFX::eInt, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionBeginSequenceRender property set */ + static PropertySetDescription gBeginSequenceRenderActionInArgPropSet(kOfxImageEffectActionBeginSequenceRender " in argument", + gBeginSequenceRenderActionInArgProps, sizeof(gBeginSequenceRenderActionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionEndSequenceRender action's inargs properties */ + static PropertyDescription gEndSequenceRenderActionInArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropFrameRange, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropFrameStep, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxPropIsInteractive, OFX::eInt, 1, eDescFinished), + // The following appeared in OFX 1.2, and are thus not mandatory + //PropertyDescription(kOfxImageEffectPropSequentialRenderStatus, OFX::eInt, 1, eDescFinished), + //PropertyDescription(kOfxImageEffectPropInteractiveRenderStatus, OFX::eInt, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionEndSequenceRender property set */ + static PropertySetDescription gEndSequenceRenderActionInArgPropSet(kOfxImageEffectActionEndSequenceRender " in argument", + gEndSequenceRenderActionInArgProps, sizeof(gEndSequenceRenderActionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionIsIdentity action's inargs properties */ + static PropertyDescription gIsIdentityActionInArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderWindow, OFX::eInt, 4, eDescFinished), + PropertyDescription(kOfxImageEffectPropFieldToRender, OFX::eString, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionIsIdentity property set */ + static PropertySetDescription gIsIdentityActionInArgPropSet(kOfxImageEffectActionIsIdentity " in argument", + gIsIdentityActionInArgProps, sizeof(gIsIdentityActionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionIsIdentity action's outargs properties */ + static PropertyDescription gIsIdentityActionOutArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionIsIdentity property set */ + static PropertySetDescription gIsIdentityActionOutArgPropSet(kOfxImageEffectActionIsIdentity " out argument", + gIsIdentityActionOutArgProps, sizeof(gIsIdentityActionOutArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetRegionOfDefinition action's inargs properties */ + static PropertyDescription gGetRegionOfDefinitionInArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetRegionOfDefinition property set */ + static PropertySetDescription gGetRegionOfDefinitionInArgPropSet(kOfxImageEffectActionGetRegionOfDefinition " in argument", + gGetRegionOfDefinitionInArgProps, sizeof(gGetRegionOfDefinitionInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetRegionOfDefinition action's outargs properties */ + static PropertyDescription gGetRegionOfDefinitionOutArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropRegionOfDefinition, OFX::eDouble, 4, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetRegionOfDefinition property set */ + static PropertySetDescription gGetRegionOfDefinitionOutArgPropSet(kOfxImageEffectActionGetRegionOfDefinition " out argument", + gGetRegionOfDefinitionOutArgProps, sizeof(gGetRegionOfDefinitionOutArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetRegionsOfInterest action's inargs properties */ + static PropertyDescription gGetRegionOfInterestInArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxImageEffectPropRegionOfInterest, OFX::eDouble, 4, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetRegionsOfInterest property set */ + static PropertySetDescription gGetRegionOfInterestInArgPropSet(kOfxImageEffectActionGetRegionsOfInterest "in argument", + gGetRegionOfInterestInArgProps, sizeof(gGetRegionOfInterestInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetTimeDomain action's outargs properties */ + static PropertyDescription gGetTimeDomainOutArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropFrameRange, OFX::eDouble, 2, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetTimeDomain property set */ + static PropertySetDescription gGetTimeDomainOutArgPropSet(kOfxImageEffectActionGetTimeDomain " out argument", + gGetTimeDomainOutArgProps, sizeof(gGetTimeDomainOutArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetFramesNeeded action's inargs properties */ + static PropertyDescription gGetFramesNeededInArgProps[ ] = + { + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetFramesNeeded property set */ + static PropertySetDescription gGetFramesNeededInArgPropSet(kOfxImageEffectActionGetFramesNeeded " in argument", + gGetFramesNeededInArgProps, sizeof(gGetFramesNeededInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxImageEffectActionGetClipPreferences action's outargs properties */ + static PropertyDescription gGetClipPreferencesOutArgProps[ ] = + { + PropertyDescription(kOfxImageEffectPropFrameRate, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropFieldOrder, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxImageClipPropContinuousSamples, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectFrameVarying, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxImageEffectPropPreMultiplication, OFX::eString, 1, eDescFinished), + }; + + /** @brief kOfxImageEffectActionGetClipPreferences property set */ + static PropertySetDescription gGetClipPreferencesOutArgPropSet(kOfxImageEffectActionGetClipPreferences " out argument", + gGetClipPreferencesOutArgProps, sizeof(gGetClipPreferencesOutArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxActionInstanceChanged action's inargs properties */ + static PropertyDescription gInstanceChangedInArgProps[ ] = + { + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropChangeReason, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropTime, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxImageEffectPropRenderScale, OFX::eDouble, 2, eDescFinished), + }; + + /** @brief kOfxActionInstanceChanged property set */ + static PropertySetDescription gInstanceChangedInArgPropSet(kOfxActionInstanceChanged " in argument", + gInstanceChangedInArgProps, sizeof(gInstanceChangedInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + /** @brief kOfxActionBeginInstanceChanged and kOfxActionEndInstanceChanged actions' inargs properties */ + static PropertyDescription gBeginEndInstanceChangedInArgProps[ ] = + { + PropertyDescription(kOfxPropChangeReason, OFX::eString, 1, eDescFinished), + }; + + /** @brief kOfxActionBeginInstanceChanged property set */ + static PropertySetDescription gBeginInstanceChangedInArgPropSet(kOfxActionBeginInstanceChanged " in argument", + gBeginEndInstanceChangedInArgProps, sizeof(gBeginEndInstanceChangedInArgProps)/sizeof(PropertyDescription), + NULLPTR); + /** @brief kOfxActionEndInstanceChanged property set */ + static PropertySetDescription gEndInstanceChangedInArgPropSet(kOfxActionEndInstanceChanged " in argument", + gBeginEndInstanceChangedInArgProps, sizeof(gBeginEndInstanceChangedInArgProps)/sizeof(PropertyDescription), + NULLPTR); + + + //////////////////////////////////////////////////////////////////////////////// + // parameter properties + //////////////////////////////////////////////////////////////////////////////// + + /** @brief Basic parameter descriptor properties */ + static PropertyDescription gBasicParamProps[ ] = + { + PropertyDescription(kOfxPropType, OFX::eString, 1, eDescDefault, kOfxTypeParameter, eDescFinished), + PropertyDescription(kOfxPropName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropShortLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxPropLongLabel, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropType, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropSecret, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxParamPropHint, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropScriptName, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropParent, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropEnabled, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropDataPtr, OFX::ePointer,1, eDescDefault, (void *)(0), eDescFinished), + }; + + + /** @brief Props for params that can have an interact override their UI */ + static PropertyDescription gInteractOverideParamProps[ ] = + { + PropertyDescription(kOfxParamPropInteractV1, OFX::ePointer,1, eDescDefault, (void *)(0), eDescFinished), + PropertyDescription(kOfxParamPropInteractSize, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropInteractSizeAspect, OFX::eDouble, 1, eDescDefault, 1.0, eDescFinished), + PropertyDescription(kOfxParamPropInteractMinimumSize, OFX::eDouble, 2, eDescDefault, 10, 10, eDescFinished), + PropertyDescription(kOfxParamPropInteractPreferedSize, OFX::eInt, 2, eDescDefault, 10, 10, eDescFinished), + }; + + /** @brief Props for params that can hold values. */ + static PropertyDescription gValueHolderParamProps[ ] = + { + PropertyDescription(kOfxParamPropIsAnimating, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropIsAutoKeying, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropPersistant, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropEvaluateOnChange, OFX::eInt, 1, eDescDefault, 1, eDescFinished), +# ifdef kOfxParamPropPluginMayWrite + PropertyDescription(kOfxParamPropPluginMayWrite, OFX::eInt, 1, eDescDefault, 0, eDescFinished), // removed in OFX 1.4 +# endif + PropertyDescription(kOfxParamPropCacheInvalidation, OFX::eString, 1, eDescDefault, kOfxParamInvalidateValueChange, eDescFinished), + PropertyDescription(kOfxParamPropCanUndo, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + }; + + /** @brief values for a string param */ + static PropertyDescription gStringParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxParamPropStringMode, OFX::eString, 1, eDescDefault, kOfxParamStringIsSingleLine, eDescFinished), + PropertyDescription(kOfxParamPropStringFilePathExists, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + }; + + /** @brief values for a string param */ + static PropertyDescription gCustomParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxParamPropCustomInterpCallbackV1, OFX::ePointer, 1, eDescDefault, NULLPTR, eDescFinished), + }; + + /** @brief properties for an RGB colour param */ + static PropertyDescription gRGBColourParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eDouble, 3, eDescDefault, 0., 0., 0., eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eDouble, 3, eDescDefault, 1., 1., 1., eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eDouble, 3, eDescDefault, 0., 0., 0., eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eDouble, 3, eDescDefault, 1., 1., 1., eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 3, eDescDefault, "r", "g", "b", eDescFinished), + }; + + /** @brief properties for an RGBA colour param */ + static PropertyDescription gRGBAColourParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eDouble, 4, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eDouble, 4, eDescDefault, 0., 0., 0., 0., eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eDouble, 4, eDescDefault, 1., 1., 1., 1., eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eDouble, 4, eDescDefault, 0., 0., 0., 0., eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eDouble, 4, eDescDefault, 1., 1., 1., 1., eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 4, eDescDefault, "r", "g", "b", "a", eDescFinished), + }; + + /** @brief properties for a boolean param */ + static PropertyDescription gBooleanParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + }; + + + /** @brief properties for a choice param */ + static PropertyDescription gChoiceParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxParamPropChoiceOption, OFX::eString, -1, eDescFinished), + }; + + /** @brief properties for a string choice param */ + static PropertyDescription gStrChoiceParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eString, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + PropertyDescription(kOfxParamPropChoiceEnum, OFX::eString, -1, eDescFinished), + PropertyDescription(kOfxParamPropChoiceOption, OFX::eString, -1, eDescFinished), + }; + + /** @brief properties for a 1D integer param */ + static PropertyDescription gInt1DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + }; + + /** @brief properties for a 2D integer param */ + static PropertyDescription gInt2DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eInt, 2, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eInt, 2, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eInt, 2, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eInt, 2, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eInt, 2, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 2, eDescDefault, "x", "y", eDescFinished), + }; + + /** @brief properties for a 3D integer param */ + static PropertyDescription gInt3DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eInt, 3, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eInt, 3, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eInt, 3, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eInt, 3, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eInt, 3, eDescFinished), + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 3, eDescDefault, "x", "y", "z", eDescFinished), + }; + + /** @brief Properties common to all double params */ + static PropertyDescription gDoubleParamProps[ ] = + { + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropIncrement, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropDigits, OFX::eInt, 1, eDescFinished), + PropertyDescription(kOfxParamPropDoubleType, OFX::eString, 1, eDescDefault, kOfxParamDoubleTypePlain, eDescFinished), + }; + + + /** @brief properties for a 1D double param */ + static PropertyDescription gDouble1DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eDouble, 1, eDescFinished), + PropertyDescription(kOfxParamPropShowTimeMarker, OFX::eInt, 1, eDescDefault, 0, eDescFinished), + }; + + /** @brief properties for a 2D double param */ + static PropertyDescription gDouble2DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eDouble, 2, eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 2, eDescDefault, "x", "y", eDescFinished), + }; + + /** @brief properties for a 3D double param */ + static PropertyDescription gDouble3DParamProps[ ] = + { + PropertyDescription(kOfxParamPropDefault, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropMin, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropMax, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMin, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropDisplayMax, OFX::eDouble, 3, eDescFinished), + PropertyDescription(kOfxParamPropDimensionLabel, OFX::eString, 3, eDescDefault, "x", "y", "z", eDescFinished), + }; + + /** @brief properties for a group param */ + static PropertyDescription gGroupParamProps[ ] = + { + PropertyDescription(kOfxParamPropGroupOpen, OFX::eInt, 1, eDescFinished), + }; + + /** @brief properties for a page param */ + static PropertyDescription gPageParamProps[ ] = + { + PropertyDescription(kOfxParamPropPageChild, OFX::eString, -1, eDescFinished), + }; + + /** @brief properties for a parametric param */ + static PropertyDescription gParametricParamProps[ ] = + { + PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropCanUndo, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropParametricDimension, OFX::eInt, 1, eDescDefault, 1, eDescFinished), + PropertyDescription(kOfxParamPropParametricUIColour, OFX::eDouble, -1, eDescFinished), + PropertyDescription(kOfxParamPropParametricInteractBackground, OFX::ePointer, 1, eDescDefault, (void*)(0), eDescFinished), + PropertyDescription(kOfxParamPropParametricRange, OFX::eDouble, 2, eDescDefault, 0.0, 1.0, eDescFinished), + }; + + /** @brief Property set for 1D ints */ + static PropertySetDescription gInt1DParamPropSet("1D Integer parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gInt1DParamProps), + NULLPTR); + + + /** @brief Property set for 2D ints */ + static PropertySetDescription gInt2DParamPropSet("2D Integer parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gInt2DParamProps), + NULLPTR); + + /** @brief Property set for 3D ints */ + static PropertySetDescription gInt3DParamPropSet("3D Integer parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gInt3DParamProps), + NULLPTR); + + /** @brief Property set for 1D doubles */ + static PropertySetDescription gDouble1DParamPropSet("1D Double parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gDoubleParamProps), + mPropDescriptionArg(gDouble1DParamProps), + NULLPTR); + + + /** @brief Property set for 2D doubles */ + static PropertySetDescription gDouble2DParamPropSet("2D Double parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gDoubleParamProps), + mPropDescriptionArg(gDouble2DParamProps), + NULLPTR); + + /** @brief Property set for 3D doubles */ + static PropertySetDescription gDouble3DParamPropSet("3D Double parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gDoubleParamProps), + mPropDescriptionArg(gDouble3DParamProps), + NULLPTR); + + /** @brief Property set for RGB colour params */ + static PropertySetDescription gRGBParamPropSet("RGB Colour parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gRGBColourParamProps), + NULLPTR); + + /** @brief Property set for RGB colour params */ + static PropertySetDescription gRGBAParamPropSet("RGB Colour parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gRGBAColourParamProps), + NULLPTR); + + /** @brief Property set for string params */ + static PropertySetDescription gStringParamPropSet("String parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gStringParamProps), + NULLPTR); + + /** @brief Property set for string params */ + static PropertySetDescription gCustomParamPropSet("Custom parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gCustomParamProps), + NULLPTR); + + /** @brief Property set for boolean params */ + static PropertySetDescription gBooleanParamPropSet("Boolean parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gBooleanParamProps), + NULLPTR); + + /** @brief Property set for choice params */ + static PropertySetDescription gChoiceParamPropSet("Choice parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gChoiceParamProps), + NULLPTR); + + /** @brief Property set for string choice params */ + static PropertySetDescription gStrChoiceParamPropSet("String Choice parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gStrChoiceParamProps), + NULLPTR); + + /** @brief Property set for push button params */ + static PropertySetDescription gPushButtonParamPropSet("PushButton parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + NULLPTR); + + /** @brief Property set for group params */ + static PropertySetDescription gGroupParamPropSet("Group Parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gGroupParamProps), + NULLPTR); + + /** @brief Property set for page params */ + static PropertySetDescription gPageParamPropSet("Page Parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gPageParamProps), + NULLPTR); + + static PropertySetDescription gParametricParamPropSet("Parametric Parameter", + mPropDescriptionArg(gBasicParamProps), + mPropDescriptionArg(gInteractOverideParamProps), + mPropDescriptionArg(gValueHolderParamProps), + mPropDescriptionArg(gParametricParamProps), + NULLPTR); + +#endif + /** @brief Validates the host structure and property handle */ + void + validateHostProperties(OfxHost *host) + { +#ifdef kOfxsDisableValidation + (void)host; +#else + // make a description set + PropertySet props(host->host); + gHostPropSet.validate(props); +#endif + } + + /** @brief Validates the effect descriptor properties */ + void + validatePluginDescriptorProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gPluginDescriptorPropSet.validate(props); +#endif + } + + /** @brief Validates the effect instance properties */ + void + validatePluginInstanceProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gPluginInstancePropSet.validate(props); +#endif + } + + /** @brief validates a clip descriptor */ + void + validateClipDescriptorProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gClipDescriptorPropSet.validate(props); +#endif + } + + /** @brief validates a clip instance */ + void + validateClipInstanceProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gClipInstancePropSet.validate(props); +#endif + } + + /** @brief validates an image or texture instance */ + void + validateImageBaseProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gImageBaseInstancePropSet.validate(props); +#endif + } + + /** @brief validates an image instance */ + void + validateImageProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gImageInstancePropSet.validate(props); +#endif + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief validates an OpenGL texture instance */ + void + validateTextureProperties(PropertySet props) + { +#ifdef kOfxsDisableValidation + (void)props; +#else + gTextureInstancePropSet.validate(props); +#endif + } +#endif + + /** @brief Validates action in/out arguments */ + void + validateActionArgumentsProperties(const std::string &action, PropertySet inArgs, PropertySet outArgs) + { +#ifdef kOfxsDisableValidation + (void)action; + (void)inArgs; + (void)outArgs; +#else + if(action == kOfxActionInstanceChanged) { + gInstanceChangedInArgPropSet.validate(inArgs); + } + else if(action == kOfxActionBeginInstanceChanged) { + gBeginInstanceChangedInArgPropSet.validate(inArgs); + } + else if(action == kOfxActionEndInstanceChanged) { + gEndInstanceChangedInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionGetRegionOfDefinition) { + gGetRegionOfDefinitionInArgPropSet.validate(inArgs); + gGetRegionOfDefinitionOutArgPropSet.validate(outArgs); + } + else if(action == kOfxImageEffectActionGetRegionsOfInterest) { + gGetRegionOfInterestInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionGetTimeDomain) { + gGetTimeDomainOutArgPropSet.validate(outArgs); + } + else if(action == kOfxImageEffectActionGetFramesNeeded) { + gGetFramesNeededInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionGetClipPreferences) { + gGetClipPreferencesOutArgPropSet.validate(outArgs); + } + else if(action == kOfxImageEffectActionIsIdentity) { + gIsIdentityActionInArgPropSet.validate(inArgs); + gIsIdentityActionOutArgPropSet.validate(outArgs); + } + else if(action == kOfxImageEffectActionRender) { + gRenderActionInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionBeginSequenceRender) { + gBeginSequenceRenderActionInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionEndSequenceRender) { + gEndSequenceRenderActionInArgPropSet.validate(inArgs); + } + else if(action == kOfxImageEffectActionDescribeInContext) { + gDescribeInContextActionInArgPropSet.validate(inArgs); + } +#endif + } + + /** @brief Validates parameter properties */ + void + validateParameterProperties(ParamTypeEnum paramType, + OFX::PropertySet paramProps, + bool checkDefaults) + { +#ifdef kOfxsDisableValidation + (void)paramType; + (void)paramProps; + (void)checkDefaults; +#else + // should use a map here + switch(paramType) + { + case eStringParam : + gStringParamPropSet.validate(paramProps, checkDefaults); + break; + case eIntParam : + gInt1DParamPropSet.validate(paramProps, checkDefaults); + break; + case eInt2DParam : + gInt2DParamPropSet.validate(paramProps, checkDefaults); + break; + case eInt3DParam : + gInt3DParamPropSet.validate(paramProps, checkDefaults); + break; + case eDoubleParam : + gDouble1DParamPropSet.validate(paramProps, checkDefaults); + break; + case eDouble2DParam : + gDouble2DParamPropSet.validate(paramProps, checkDefaults); + break; + case eDouble3DParam : + gDouble3DParamPropSet.validate(paramProps, checkDefaults); + break; + case eRGBParam : + gRGBParamPropSet.validate(paramProps, checkDefaults); + break; + case eRGBAParam : + gRGBAParamPropSet.validate(paramProps, checkDefaults); + break; + case eBooleanParam : + gBooleanParamPropSet.validate(paramProps, checkDefaults); + break; + case eChoiceParam : + gChoiceParamPropSet.validate(paramProps, checkDefaults); + break; + case eStrChoiceParam : + gStrChoiceParamPropSet.validate(paramProps, checkDefaults); + break; + case eCustomParam : + gCustomParamPropSet.validate(paramProps, checkDefaults); + break; + case eGroupParam : + gGroupParamPropSet.validate(paramProps, checkDefaults); + break; + case ePageParam : + gPageParamPropSet.validate(paramProps, checkDefaults); + break; + case ePushButtonParam : + gPushButtonParamPropSet.validate(paramProps, checkDefaults); + break; + case eParametricParam: + gParametricParamPropSet.validate(paramProps, checkDefaults); + break; + case eDummyParam: + //default: + break; + } +#endif + } + + //////////////////////////////////////////////////////////////////////////////// + // + + /** @brief Initialises validation stuff that needs to be done once we know how the host behaves, called during the onload action */ + void + initialise(void) + { +#ifndef kOfxsDisableValidation + static bool beenInitialised = false; + if(!beenInitialised && getImageEffectHostDescription()) { + beenInitialised = true; + + // create new property descriptions depending on certain host states + PropertyDescription *desc; + + // do custom params animate ? + desc = new PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, + eDescDefault, int(getImageEffectHostDescription()->supportsCustomAnimation), + eDescFinished); + gCustomParamPropSet.addProperty(desc, true); + + // do strings animate ? + desc = new PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, + eDescDefault, int(getImageEffectHostDescription()->supportsStringAnimation), + eDescFinished); + gStringParamPropSet.addProperty(desc, true); + + // do choice params animate + desc = new PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, + eDescDefault, int(getImageEffectHostDescription()->supportsChoiceAnimation), + eDescFinished); + gChoiceParamPropSet.addProperty(desc, true); + + // do string choice params animate + desc = new PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, + eDescDefault, int(getImageEffectHostDescription()->supportsStrChoiceAnimation), + eDescFinished); + gStrChoiceParamPropSet.addProperty(desc, true); + + // do boolean params animate + desc = new PropertyDescription(kOfxParamPropAnimates, OFX::eInt, 1, + eDescDefault, int(getImageEffectHostDescription()->supportsBooleanAnimation), + eDescFinished); + gBooleanParamPropSet.addProperty(desc, true); + } +#endif + } + }; +}; diff --git a/third_party/openfx/Support/Library/ofxsSupportPrivate.h b/third_party/openfx/Support/Library/ofxsSupportPrivate.h new file mode 100644 index 000000000..55865305d --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsSupportPrivate.h @@ -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 EffectContextMap; + typedef std::map 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 _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 _descriptions; + + /** @brief The descriptions of each property */ + std::vector _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 diff --git a/third_party/openfx/Support/Library/ofxsupport.dsw b/third_party/openfx/Support/Library/ofxsupport.dsw new file mode 100755 index 000000000..d326040fd --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsupport.dsw @@ -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> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/Library/ofxsupport.vcproj b/third_party/openfx/Support/Library/ofxsupport.vcproj new file mode 100755 index 000000000..450f30441 --- /dev/null +++ b/third_party/openfx/Support/Library/ofxsupport.vcproj @@ -0,0 +1,695 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/OSXStaticLoader/pluginLoader.cpp b/third_party/openfx/Support/OSXStaticLoader/pluginLoader.cpp new file mode 100644 index 000000000..f42c2b3bc --- /dev/null +++ b/third_party/openfx/Support/OSXStaticLoader/pluginLoader.cpp @@ -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 \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 ); +} diff --git a/third_party/openfx/Support/Plugins/Basic/Info.plist b/third_party/openfx/Support/Plugins/Basic/Info.plist new file mode 100644 index 000000000..21152b3e8 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Basic/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + basic.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Basic/basic.cpp b/third_party/openfx/Support/Plugins/Basic/basic.cpp new file mode 100644 index 000000000..fc78cd927 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Basic/basic.cpp @@ -0,0 +1,727 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#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 inline T +Minimum(T a, T b) { return (a < b) ? a : b;} + +template inline T +Absolute(T a) { return (a < 0) ? -a : a;} + +template 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 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 dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // fetch main input image + std::unique_ptr 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 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 fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageScaler 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 {}; + +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); + } + } +} diff --git a/third_party/openfx/Support/Plugins/Basic/basic.dsp b/third_party/openfx/Support/Plugins/Basic/basic.dsp new file mode 100755 index 000000000..c58eafeca --- /dev/null +++ b/third_party/openfx/Support/Plugins/Basic/basic.dsp @@ -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 diff --git a/third_party/openfx/Support/Plugins/Basic/basic.dsw b/third_party/openfx/Support/Plugins/Basic/basic.dsw new file mode 100755 index 000000000..a98a697c9 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Basic/basic.dsw @@ -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> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/Plugins/Basic/basic.vcproj b/third_party/openfx/Support/Plugins/Basic/basic.vcproj new file mode 100755 index 000000000..eda736e58 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Basic/basic.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/CMakeLists.txt b/third_party/openfx/Support/Plugins/CMakeLists.txt new file mode 100644 index 000000000..731b6cdc7 --- /dev/null +++ b/third_party/openfx/Support/Plugins/CMakeLists.txt @@ -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() diff --git a/third_party/openfx/Support/Plugins/ChoiceParams/Info.plist b/third_party/openfx/Support/Plugins/ChoiceParams/Info.plist new file mode 100644 index 000000000..750eda640 --- /dev/null +++ b/third_party/openfx/Support/Plugins/ChoiceParams/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + choiceparams.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/ChoiceParams/choiceparams.cpp b/third_party/openfx/Support/Plugins/ChoiceParams/choiceparams.cpp new file mode 100644 index 000000000..c83f5d4ba --- /dev/null +++ b/third_party/openfx/Support/Plugins/ChoiceParams/choiceparams.cpp @@ -0,0 +1,681 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#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 inline T +Minimum(T a, T b) { return (a < b) ? a : b;} + +template inline T +Absolute(T a) { return (a < 0) ? -a : a;} + +template 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 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 dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // fetch main input image + std::unique_ptr 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 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 fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageScaler fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageScaler 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 {}; + +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); + } + } +} diff --git a/third_party/openfx/Support/Plugins/ExamplePlugs.sln b/third_party/openfx/Support/Plugins/ExamplePlugs.sln new file mode 100755 index 000000000..f76427b95 --- /dev/null +++ b/third_party/openfx/Support/Plugins/ExamplePlugs.sln @@ -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 diff --git a/third_party/openfx/Support/Plugins/Field/Info.plist b/third_party/openfx/Support/Plugins/Field/Info.plist new file mode 100644 index 000000000..f98fcd72a --- /dev/null +++ b/third_party/openfx/Support/Plugins/Field/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + field.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Field/field.cpp b/third_party/openfx/Support/Plugins/Field/field.cpp new file mode 100644 index 000000000..b844b58cd --- /dev/null +++ b/third_party/openfx/Support/Plugins/Field/field.cpp @@ -0,0 +1,286 @@ + + +#ifdef _WINDOWS +#include +#endif + +#include +#include +#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 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 dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // fetch main input image + std::unique_ptr 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 fred(*this, field); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + ImageFielder fred(*this, field); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + ImageFielder fred(*this, field); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + ImageFielder fred(*this, field); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + ImageFielder fred(*this, field); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + ImageFielder 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); + } + } +} diff --git a/third_party/openfx/Support/Plugins/Field/field.vcproj b/third_party/openfx/Support/Plugins/Field/field.vcproj new file mode 100755 index 000000000..d4e50e768 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Field/field.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/GPUGain/CudaKernel.cu b/third_party/openfx/Support/Plugins/GPUGain/CudaKernel.cu new file mode 100644 index 000000000..46d0ca03e --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/CudaKernel.cu @@ -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(p_Stream); + + GainAdjustKernel<<>>(p_Width, p_Height, p_Gain[0], p_Gain[1], p_Gain[2], p_Gain[3], p_Input, p_Output); +} diff --git a/third_party/openfx/Support/Plugins/GPUGain/GPUGain.cpp b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.cpp new file mode 100644 index 000000000..3c43378e8 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.cpp @@ -0,0 +1,462 @@ + + +#include "GPUGain.h" + +#include + +#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(_srcImg->getPixelData()); + float* output = static_cast(_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(_srcImg->getPixelData()); + float* output = static_cast(_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(_srcImg->getOpenCLImage()); + float* output = static_cast(_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(_srcImg->getPixelData()); + output = static_cast(_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(_dstImg->getPixelAddress(p_ProcWindow.x1, y)); + + for (int x = p_ProcWindow.x1; x < p_ProcWindow.x2; ++x) + { + float* srcPix = static_cast(_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 dst(m_DstClip->fetchImage(p_Args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // Get the src image + std::unique_ptr 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(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); +} diff --git a/third_party/openfx/Support/Plugins/GPUGain/GPUGain.h b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.h new file mode 100644 index 000000000..528aa3a30 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.h @@ -0,0 +1,16 @@ + + +#pragma once + +#include "ofxsImageEffect.h" + +class GPUGainFactory : public OFX::PluginFactoryHelper +{ +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); +}; diff --git a/third_party/openfx/Support/Plugins/GPUGain/GPUGain.sln b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.sln new file mode 100644 index 000000000..e6335a2ca --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.sln @@ -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 diff --git a/third_party/openfx/Support/Plugins/GPUGain/GPUGain.vcxproj b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.vcxproj new file mode 100644 index 000000000..fc45ab913 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {88405F0E-918E-4523-8627-1380BC83A605} + GPUGain + Win32Proj + + + + DynamicLibrary + v120 + Unicode + true + + + DynamicLibrary + v120 + Unicode + + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(CUDA_INC_PATH);$(AMDAPPSDKROOT)/include;../OpenFX-1.4/include;../Support/include + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(CUDA_LIB_PATH);$(AMDAPPSDKROOT)/lib/x86_64 + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(CUDA_INC_PATH);$(AMDAPPSDKROOT)/include;../OpenFX-1.4/include;../Support/include + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(CUDA_LIB_PATH);$(AMDAPPSDKROOT)/lib/x86_64 + + + + + + + X64 + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + ProgramDatabase + + + true + Windows + MachineX64 + 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) + + + Creating bundle... + 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 + + + + 64 + + + + + X64 + + + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level3 + ProgramDatabase + + + true + Windows + true + true + MachineX64 + 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) + + + Creating bundle... + 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 + + + + 64 + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/GPUGain/GPUGain.xcodeproj/project.pbxproj b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.xcodeproj/project.pbxproj new file mode 100644 index 000000000..1a66eb8b2 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/GPUGain.xcodeproj/project.pbxproj @@ -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 = ""; }; + 3DF51C6D1CB741110070CA48 /* GPUGain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GPUGain.cpp; sourceTree = ""; }; + 3DF51C6E1CB741110070CA48 /* GPUGain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPUGain.h; sourceTree = ""; }; + 3DF51C701CB741110070CA48 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 3DF51C711CB741110070CA48 /* OpenCLKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenCLKernel.cpp; sourceTree = ""; }; + 3DF51C721CB7413B0070CA48 /* ofxsCore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsCore.cpp; path = ../../Support/Library/ofxsCore.cpp; sourceTree = ""; }; + 3DF51C731CB7413B0070CA48 /* ofxsImageEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsImageEffect.cpp; path = ../../Support/Library/ofxsImageEffect.cpp; sourceTree = ""; }; + 3DF51C741CB7413B0070CA48 /* ofxsInteract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsInteract.cpp; path = ../../Support/Library/ofxsInteract.cpp; sourceTree = ""; }; + 3DF51C751CB7413B0070CA48 /* ofxsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsLog.cpp; path = ../../Support/Library/ofxsLog.cpp; sourceTree = ""; }; + 3DF51C761CB7413B0070CA48 /* ofxsMultiThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsMultiThread.cpp; path = ../../Support/Library/ofxsMultiThread.cpp; sourceTree = ""; }; + 3DF51C771CB7413B0070CA48 /* ofxsParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsParams.cpp; path = ../../Support/Library/ofxsParams.cpp; sourceTree = ""; }; + 3DF51C781CB7413B0070CA48 /* ofxsProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsProperty.cpp; path = ../../Support/Library/ofxsProperty.cpp; sourceTree = ""; }; + 3DF51C791CB7413B0070CA48 /* ofxsPropertyValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsPropertyValidation.cpp; path = ../../Support/Library/ofxsPropertyValidation.cpp; sourceTree = ""; }; + 4F799E1E1EC4662F00E46226 /* MetalKernel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalKernel.mm; sourceTree = ""; }; +/* 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 = ""; + }; + 3DF51C611CB740BF0070CA48 = { + isa = PBXGroup; + children = ( + 3D2F26961CBB8F6B00FC8803 /* Support */, + 3DF51C6C1CB741110070CA48 /* CudaKernel.cu */, + 3DF51C6D1CB741110070CA48 /* GPUGain.cpp */, + 3DF51C6E1CB741110070CA48 /* GPUGain.h */, + 3DF51C701CB741110070CA48 /* Makefile */, + 3DF51C711CB741110070CA48 /* OpenCLKernel.cpp */, + 4F799E1E1EC4662F00E46226 /* MetalKernel.mm */, + ); + sourceTree = ""; + }; +/* 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 */; +} diff --git a/third_party/openfx/Support/Plugins/GPUGain/Info.plist b/third_party/openfx/Support/Plugins/GPUGain/Info.plist new file mode 100644 index 000000000..2c98dddd9 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + GPUGain.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/GPUGain/MetalKernel.mm b/third_party/openfx/Support/Plugins/GPUGain/MetalKernel.mm new file mode 100644 index 000000000..70af47a49 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/MetalKernel.mm @@ -0,0 +1,108 @@ + + +#import + +#include +#include + +const char* kernelSource = \ +"#include \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> 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 queue = static_cast >(p_CmdQ); + id device = queue.device; + id metalLibrary; // Metal library + id kernelFunction; // Compute kernel + id pipelineState; // Metal pipeline + NSError* err; + + std::unique_lock lock(s_PipelineQueueMutex); + + const auto it = s_PipelineQueueMap.find(queue); + if (it == s_PipelineQueueMap.end()) + { + id metalLibrary; // Metal library + id 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 srcDeviceBuf = reinterpret_cast >(const_cast(p_Input)); + id dstDeviceBuf = reinterpret_cast >(p_Output); + + id commandBuffer = [queue commandBuffer]; + commandBuffer.label = [NSString stringWithFormat:@"GainAdjustKernel"]; + + id 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]; +} diff --git a/third_party/openfx/Support/Plugins/GPUGain/OpenCLKernel.cpp b/third_party/openfx/Support/Plugins/GPUGain/OpenCLKernel.cpp new file mode 100644 index 000000000..2b237bdf1 --- /dev/null +++ b/third_party/openfx/Support/Plugins/GPUGain/OpenCLKernel.cpp @@ -0,0 +1,270 @@ + + +#ifdef _WIN64 +#include +#else +#include +#endif +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +const char *KernelSourceBuffers = "\n" \ +"__kernel void GainAdjustKernelBuffers( \n" \ +" int p_Width, \n" \ +" int p_Height, \n" \ +" float p_GainR, \n" \ +" float p_GainG, \n" \ +" float p_GainB, \n" \ +" float p_GainA, \n" \ +" __global const float* p_Input, \n" \ +" __global float* p_Output) \n" \ +"{ \n" \ +" const int x = get_global_id(0); \n" \ +" const int y = get_global_id(1); \n" \ +" \n" \ +" if ((x < p_Width) && (y < p_Height)) \n" \ +" { \n" \ +" const int index = ((y * p_Width) + x) * 4; \n" \ +" \n" \ +" p_Output[index + 0] = p_Input[index + 0] * p_GainR; \n" \ +" p_Output[index + 1] = p_Input[index + 1] * p_GainG; \n" \ +" p_Output[index + 2] = p_Input[index + 2] * p_GainB; \n" \ +" p_Output[index + 3] = p_Input[index + 3] * p_GainA; \n" \ +" } \n" \ +"} \n" \ +"\n"; + +const char *KernelSourceImages = "\n" \ +"__constant sampler_t imageSampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; \n" \ +" \n" \ +"__kernel void GainAdjustKernelImages( \n" \ +" int p_Width, \n" \ +" int p_Height, \n" \ +" float p_GainR, \n" \ +" float p_GainG, \n" \ +" float p_GainB, \n" \ +" float p_GainA, \n" \ +" __read_only image2d_t p_Input, \n" \ +" __write_only image2d_t p_Output) \n" \ +"{ \n" \ +" const int x = get_global_id(0); \n" \ +" const int y = get_global_id(1); \n" \ +" \n" \ +" if ((x < p_Width) && (y < p_Height)) \n" \ +" { \n" \ +" int2 coord = (int2)(x, y); \n" \ +" float4 out = read_imagef(p_Input, imageSampler, coord); \n" \ +" out *= (float4)(p_GainR, p_GainG, p_GainB, p_GainA); \n" \ +" write_imagef(p_Output, coord, out); \n" \ +" } \n" \ +"} \n" \ +"\n"; + +void CheckError(cl_int p_Error, const char* p_Msg) +{ + if (p_Error != CL_SUCCESS) + { + fprintf(stderr, "%s [%d]\n", p_Msg, p_Error); + } +} + +class Locker +{ +public: + Locker() + { +#ifdef _WIN64 + InitializeCriticalSection(&mutex); +#else + pthread_mutex_init(&mutex, NULL); +#endif + } + + ~Locker() + { +#ifdef _WIN64 + DeleteCriticalSection(&mutex); +#else + pthread_mutex_destroy(&mutex); +#endif + } + + void Lock() + { +#ifdef _WIN64 + EnterCriticalSection(&mutex); +#else + pthread_mutex_lock(&mutex); +#endif + } + + void Unlock() + { +#ifdef _WIN64 + LeaveCriticalSection(&mutex); +#else + pthread_mutex_unlock(&mutex); +#endif + } + +private: +#ifdef _WIN64 + CRITICAL_SECTION mutex; +#else + pthread_mutex_t mutex; +#endif +}; + +void RunOpenCLKernelBuffers(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output) +{ + cl_int error; + + cl_command_queue cmdQ = static_cast(p_CmdQ); + + // store device id and kernel per command queue (required for multi-GPU systems) + static std::map deviceIdMap; + static std::map kernelMap; + + static Locker locker; // simple lock to control access to the above maps from multiple threads + + locker.Lock(); + + // find the device id corresponding to the command queue + cl_device_id deviceId = NULL; + if (deviceIdMap.find(cmdQ) == deviceIdMap.end()) + { + error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_DEVICE, sizeof(cl_device_id), &deviceId, NULL); + CheckError(error, "Unable to get the device"); + + deviceIdMap[cmdQ] = deviceId; + } + else + { + deviceId = deviceIdMap[cmdQ]; + } + + // find the program kernel corresponding to the command queue + cl_kernel kernel = NULL; + if (kernelMap.find(cmdQ) == kernelMap.end()) + { + cl_context clContext = NULL; + error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_CONTEXT, sizeof(cl_context), &clContext, NULL); + CheckError(error, "Unable to get the context"); + + cl_program program = clCreateProgramWithSource(clContext, 1, (const char **)&KernelSourceBuffers, NULL, &error); + CheckError(error, "Unable to create program"); + + error = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); + CheckError(error, "Unable to build program"); + + kernel = clCreateKernel(program, "GainAdjustKernelBuffers", &error); + CheckError(error, "Unable to create kernel"); + + kernelMap[cmdQ] = kernel; + } + else + { + kernel = kernelMap[cmdQ]; + } + + locker.Unlock(); + + int count = 0; + error = clSetKernelArg(kernel, count++, sizeof(int), &p_Width); + error |= clSetKernelArg(kernel, count++, sizeof(int), &p_Height); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[0]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[1]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[2]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[3]); + error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Input); + error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Output); + CheckError(error, "Unable to set kernel arguments"); + + size_t localWorkSize[2], globalWorkSize[2]; + clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), localWorkSize, NULL); + localWorkSize[1] = 1; + globalWorkSize[0] = ((p_Width + localWorkSize[0] - 1) / localWorkSize[0]) * localWorkSize[0]; + globalWorkSize[1] = p_Height; + + clEnqueueNDRangeKernel(cmdQ, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); +} + +void RunOpenCLKernelImages(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output) +{ + cl_int error; + + cl_command_queue cmdQ = static_cast(p_CmdQ); + + // store device id and kernel per command queue (required for multi-GPU systems) + static std::map deviceIdMap; + static std::map kernelMap; + + static Locker locker; // simple lock to control access to the above maps from multiple threads + + locker.Lock(); + + // find the device id corresponding to the command queue + cl_device_id deviceId = NULL; + if (deviceIdMap.find(cmdQ) == deviceIdMap.end()) + { + error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_DEVICE, sizeof(cl_device_id), &deviceId, NULL); + CheckError(error, "Unable to get the device"); + + deviceIdMap[cmdQ] = deviceId; + } + else + { + deviceId = deviceIdMap[cmdQ]; + } + + // find the program kernel corresponding to the command queue + cl_kernel kernel = NULL; + if (kernelMap.find(cmdQ) == kernelMap.end()) + { + cl_context clContext = NULL; + error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_CONTEXT, sizeof(cl_context), &clContext, NULL); + CheckError(error, "Unable to get the context"); + + cl_program program = clCreateProgramWithSource(clContext, 1, (const char **)&KernelSourceImages, NULL, &error); + CheckError(error, "Unable to create program"); + + error = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); + CheckError(error, "Unable to build program"); + + kernel = clCreateKernel(program, "GainAdjustKernelImages", &error); + CheckError(error, "Unable to create kernel"); + + kernelMap[cmdQ] = kernel; + } + else + { + kernel = kernelMap[cmdQ]; + } + + locker.Unlock(); + + int count = 0; + error = clSetKernelArg(kernel, count++, sizeof(int), &p_Width); + error |= clSetKernelArg(kernel, count++, sizeof(int), &p_Height); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[0]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[1]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[2]); + error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[3]); + error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Input); + error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Output); + CheckError(error, "Unable to set kernel arguments"); + + size_t localWorkSize[2], globalWorkSize[2]; + clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), localWorkSize, NULL); + localWorkSize[1] = 1; + globalWorkSize[0] = ((p_Width + localWorkSize[0] - 1) / localWorkSize[0]) * localWorkSize[0]; + globalWorkSize[1] = p_Height; + + clEnqueueNDRangeKernel(cmdQ, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); +} diff --git a/third_party/openfx/Support/Plugins/Generator/Info.plist b/third_party/openfx/Support/Plugins/Generator/Info.plist new file mode 100644 index 000000000..fa60366ec --- /dev/null +++ b/third_party/openfx/Support/Plugins/Generator/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + noise.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Generator/noise.cpp b/third_party/openfx/Support/Plugins/Generator/noise.cpp new file mode 100644 index 000000000..b8496f3a7 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Generator/noise.cpp @@ -0,0 +1,293 @@ + + +#include +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" + +#include "../include/ofxsProcessing.H" + +#include + +//////////////////////////////////////////////////////////////////////////////// +// base class for the noise + +/** @brief Base class used to blend two images together */ +class NoiseGeneratorBase : public OFX::ImageProcessor { +protected : + float _noiseLevel; // how much to blend + uint32_t _seed; // base seed +public : + /** @brief no arg ctor */ + NoiseGeneratorBase(OFX::ImageEffect &instance) + : OFX::ImageProcessor(instance) + , _noiseLevel(0.5f) + , _seed(0) + { + } + + /** @brief set the scale */ + void setNoiseLevel(float v) {_noiseLevel = v;} + + /** @brief the seed to use */ + void setSeed(uint32_t v) {_seed = v;} +}; + +/** @brief templated class to blend between two images */ +template +class NoiseGenerator : public NoiseGeneratorBase { +public : + // ctor + NoiseGenerator(OFX::ImageEffect &instance) + : NoiseGeneratorBase(instance) + {} + + // and do some processing + void multiThreadProcessImages(OfxRectI procWindow) + { + float noiseLevel = _noiseLevel; + + // set up a random number generator + // Distribution is from 0 to pixel max level times noise level + std::random_device rd; + std::mt19937_64 mt(rd()); + mt.seed(_seed + procWindow.y1); + std::uniform_real_distribution dist(0.0, max * noiseLevel); + + // push pixels + for(int y = procWindow.y1; y < procWindow.y2; y++) { + if(_effect.abort()) break; + + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + + for(int x = procWindow.x1; x < procWindow.x2; x++) { + for(int c = 0; c < nComponents; c++) { + double randValue = dist(mt); + + if(max == 1) // implies floating point, so don't clamp + dstPix[c] = PIX(randValue); + else { // integer base one, clamp it + dstPix[c] = randValue < 0 ? 0 : (randValue > max ? max : PIX(randValue)); + } + } + dstPix += nComponents; + } + } + } + +}; + +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class NoisePlugin : public OFX::ImageEffect { +protected : + // do not need to delete these, the ImageEffect is managing them for us + OFX::Clip *dstClip_; + + OFX::DoubleParam *noise_; + +public : + /** @brief ctor */ + NoisePlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , dstClip_(0) + , noise_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + noise_ = fetchDoubleParam("Noise"); + } + + /* Override the render */ + virtual void render(const OFX::RenderArguments &args); + + /* Override the clip preferences, we need to say we are setting the frame varying flag */ + virtual void getClipPreferences(OFX::ClipPreferencesSetter &clipPreferences); + + /* set up and run a processor */ + void setupAndProcess(NoiseGeneratorBase &, const OFX::RenderArguments &args); + + /** @brief The get RoD action. We flag an infinite rod */ + bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod); +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the filter */ + +//////////////////////////////////////////////////////////////////////////////// +// basic plugin render function, just a skelington to instantiate templates from + + +/* set up and run a processor */ +void +NoisePlugin::setupAndProcess(NoiseGeneratorBase &processor, const OFX::RenderArguments &args) +{ + // get a dst image + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + //OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + //OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // set the images + processor.setDstImg(dst.get()); + + // set the render window + processor.setRenderWindow(args.renderWindow); + + // set the scales + processor.setNoiseLevel((float)noise_->getValueAtTime(args.time)); + + // set the seed based on the current time, and double it we get difference seeds on different fields + processor.setSeed(uint32_t(args.time * 2.0f + 2000.0f)); + + // Call the base class process member, this will call the derived templated process code + processor.process(); +} + +/* Override the clip preferences, we need to say we are setting the frame varying flag */ +void +NoisePlugin::getClipPreferences(OFX::ClipPreferencesSetter &clipPreferences) +{ + clipPreferences.setOutputFrameVarying(true); +} + +/** @brief The get RoD action. We flag an infinite rod */ +bool +NoisePlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &/*args*/, OfxRectD &rod) +{ + // we can generate noise anywhere on the image plan, so set our RoD to be infinite + rod.x1 = rod.y1 = kOfxFlagInfiniteMin; + rod.x2 = rod.y2 = kOfxFlagInfiniteMax; + return true; +} + +// the overridden render function +void +NoisePlugin::render(const OFX::RenderArguments &args) +{ + // instantiate the render code based on the pixel depth of the dst clip + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + + // do the rendering + if(dstComponents == OFX::ePixelComponentRGBA) { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + NoiseGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } +} + +mDeclarePluginFactory(NoiseExamplePluginFactory, {}, {}); + +using namespace OFX; + +void NoiseExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + desc.setLabels("Noise", "Noise", "Noise"); + desc.setPluginGrouping("OFX Example (Support)"); + desc.addSupportedContext(eContextGenerator); + desc.addSupportedContext(eContextGeneral); + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + desc.setRenderTwiceAlways(false); +} + +void NoiseExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum /*context*/) +{ + // there has to be an input clip, even for generators + ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); + srcClip->addSupportedComponent( OFX::ePixelComponentRGBA ); + srcClip->addSupportedComponent( OFX::ePixelComponentAlpha ); + srcClip->setSupportsTiles(true); + srcClip->setOptional(true); + + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + dstClip->setFieldExtraction(eFieldExtractSingle); + DoubleParamDescriptor *param = desc.defineDoubleParam("Noise"); + param->setLabels("noise", "noise", "noise"); + param->setScriptName("noise"); + param->setHint("How much noise to make."); + param->setDefault(0.2); + param->setRange(0, 10); + param->setIncrement(0.1); + param->setDisplayRange(0, 1); + param->setAnimates(true); // can animate + param->setDoubleType(eDoubleTypeScale); + PageParamDescriptor *page = desc.definePageParam("Controls"); + page->addChild(*param); +} + +ImageEffect* NoiseExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/) +{ + return new NoisePlugin(handle); +} + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static NoiseExamplePluginFactory p("net.sf.openfx.noisePlugin", 1, 0); + ids.push_back(&p); + } + }; +}; diff --git a/third_party/openfx/Support/Plugins/Generator/noise.dsp b/third_party/openfx/Support/Plugins/Generator/noise.dsp new file mode 100755 index 000000000..d09c95c41 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Generator/noise.dsp @@ -0,0 +1,111 @@ +# Microsoft Developer Studio Project File - Name="noise" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=noise - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "noise.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "noise.mak" CFG="noise - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "noise - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "noise - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "noise - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/noise.ofx" + +!ELSEIF "$(CFG)" == "noise - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\Noise.ofx.bundle\Contents\Win32\noise.ofx" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "noise - Win32 Release" +# Name "noise - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\noise.cpp +# End Source File +# Begin Source File + +SOURCE=.\randomGenerator.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/third_party/openfx/Support/Plugins/Generator/noise.dsw b/third_party/openfx/Support/Plugins/Generator/noise.dsw new file mode 100755 index 000000000..d8cd6285f --- /dev/null +++ b/third_party/openfx/Support/Plugins/Generator/noise.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "noise"=.\noise.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name ofxsupport + End Project Dependency +}}} + +############################################################################### + +Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/Plugins/Generator/noise.vcproj b/third_party/openfx/Support/Plugins/Generator/noise.vcproj new file mode 100755 index 000000000..49531691f --- /dev/null +++ b/third_party/openfx/Support/Plugins/Generator/noise.vcproj @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/Invert/Info.plist b/third_party/openfx/Support/Plugins/Invert/Info.plist new file mode 100644 index 000000000..76f334ab6 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Invert/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + invert.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Invert/invert.cpp b/third_party/openfx/Support/Plugins/Invert/invert.cpp new file mode 100644 index 000000000..36533022b --- /dev/null +++ b/third_party/openfx/Support/Plugins/Invert/invert.cpp @@ -0,0 +1,257 @@ + + +#ifdef _WINDOWS +#include +#endif + +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" + +#include "../include/ofxsProcessing.H" + + +// Base class for the RGBA and the Alpha processor +class InvertBase : public OFX::ImageProcessor { +protected : + OFX::Image *_srcImg; +public : + /** @brief no arg ctor */ + InvertBase(OFX::ImageEffect &instance) + : OFX::ImageProcessor(instance) + , _srcImg(0) + { + } + + /** @brief set the src image */ + void setSrcImg(OFX::Image *v) {_srcImg = v;} +}; + +// template to do the RGBA processing +template +class ImageInverter : public InvertBase { +public : + // ctor + ImageInverter(OFX::ImageEffect &instance) + : InvertBase(instance) + {} + + // and do some processing + void multiThreadProcessImages(OfxRectI procWindow) + { + for(int y = procWindow.y1; y < procWindow.y2; y++) { + if(_effect.abort()) break; + + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + + for(int x = procWindow.x1; x < procWindow.x2; x++) { + + PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0); + + // do we have a source image to scale up + if(srcPix) { + for(int c = 0; c < nComponents; c++) { + dstPix[c] = max - srcPix[c]; + } + } + else { + // no src pixel here, be black and transparent + for(int c = 0; c < nComponents; c++) { + dstPix[c] = 0; + } + } + + // increment the dst pixel + dstPix += nComponents; + } + } + } +}; + +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class InvertPlugin : public OFX::ImageEffect { +protected : + // do not need to delete these, the ImageEffect is managing them for us + OFX::Clip *dstClip_; + OFX::Clip *srcClip_; + +public : + /** @brief ctor */ + InvertPlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , dstClip_(0) + , srcClip_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName); + } + + /* Override the render */ + virtual void render(const OFX::RenderArguments &args); + + /* set up and run a processor */ + void setupAndProcess(InvertBase &, const OFX::RenderArguments &args); +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the filter */ + +//////////////////////////////////////////////////////////////////////////////// +// basic plugin render function, just a skelington to instantiate templates from + + +/* set up and run a processor */ +void +InvertPlugin::setupAndProcess(InvertBase &processor, const OFX::RenderArguments &args) +{ + // get a dst image + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // fetch main input image + std::unique_ptr src(srcClip_->fetchImage(args.time)); + + // make sure bit depths are sane + if(src.get()) { + OFX::BitDepthEnum srcBitDepth = src->getPixelDepth(); + OFX::PixelComponentEnum srcComponents = src->getPixelComponents(); + + // see if they have the same depths and bytes and all + if(srcBitDepth != dstBitDepth || srcComponents != dstComponents) + throw int(1); // HACK!! need to throw an sensible exception here! + } + + // set the images + processor.setDstImg(dst.get()); + processor.setSrcImg(src.get()); + + // set the render window + processor.setRenderWindow(args.renderWindow); + + // Call the base class process member, this will call the derived templated process code + processor.process(); +} + +// the overridden render function +void +InvertPlugin::render(const OFX::RenderArguments &args) +{ + // instantiate the render code based on the pixel depth of the dst clip + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + + // do the rendering + if(dstComponents == OFX::ePixelComponentRGBA) { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + ImageInverter fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } +} + +mDeclarePluginFactory(InvertExamplePluginFactory, {}, {}); + +using namespace OFX; +void InvertExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + // basic labels + desc.setLabels("Invert", "Invert", "Invert"); + desc.setPluginGrouping("OFX Example (Support)"); + + // add the supported contexts, only filter at the moment + desc.addSupportedContext(eContextFilter); + + // add supported pixel depths + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + + // set a few flags + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + +} + +void InvertExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/) +{ + // Source clip only in the filter context + // create the mandated source clip + ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->addSupportedComponent(ePixelComponentAlpha); + srcClip->setTemporalClipAccess(false); + srcClip->setSupportsTiles(true); + srcClip->setIsMask(false); + + // create the mandated output clip + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + +} + +OFX::ImageEffect* InvertExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/) +{ + return new InvertPlugin(handle); +} + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static InvertExamplePluginFactory p("net.sf.openfx.invertPlugin", 1, 0); + ids.push_back(&p); + } + } +} diff --git a/third_party/openfx/Support/Plugins/Invert/invert.vcproj b/third_party/openfx/Support/Plugins/Invert/invert.vcproj new file mode 100755 index 000000000..9b06942c0 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Invert/invert.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/Info.plist b/third_party/openfx/Support/Plugins/MultiBundle/Info.plist new file mode 100644 index 000000000..c960b6bc1 --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + multibundle.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/PluginRegistration.cpp b/third_party/openfx/Support/Plugins/MultiBundle/PluginRegistration.cpp new file mode 100755 index 000000000..4444824bf --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/PluginRegistration.cpp @@ -0,0 +1,20 @@ + + +#include +#include "ofxsImageEffect.h" +#include "multibundle1.h" +#include "multibundle2.h" + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static DotExamplePluginFactory p1; + ids.push_back(&p1); + static GammaExamplePluginFactory p2; + ids.push_back(&p2); + } + } +} diff --git a/third_party/openfx/Support/Plugins/MultiBundle/multibundle.vcproj b/third_party/openfx/Support/Plugins/MultiBundle/multibundle.vcproj new file mode 100755 index 000000000..dfd8eed3e --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/multibundle.vcproj @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.cpp b/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.cpp new file mode 100755 index 000000000..385969a67 --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.cpp @@ -0,0 +1,529 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" +#include "../include/ofxsProcessing.H" + +#include "multibundle1.h" + +static const OfxPointD kBoxSize = {20, 20}; +class GammaInteract : public OFX::OverlayInteract +{ +protected : + enum StateEnum { + eInActive, + ePoised, + ePicked + }; + OfxPointD _position; + StateEnum _state; +public : + GammaInteract(OfxInteractHandle handle, OFX::ImageEffect* /*effect*/) : OFX::OverlayInteract(handle), _state(eInActive) + { + _position.x = 0; + _position.y = 0; + } + virtual bool draw(const OFX::DrawArgs &args); + virtual bool penMotion(const OFX::PenArgs &args); + virtual bool penDown(const OFX::PenArgs &args); + virtual bool penUp(const OFX::PenArgs &args); +}; + +template +inline T Absolute(T a) +{ + return (a < 0) ? -a : a; +} + +template +inline T Clamp(T v, int min, int max) +{ + if(v < T(min)) + return T(min); + if(v > T(max)) + return T(max); + return v; +} + +class ImageScalerBase : public OFX::ImageProcessor +{ +protected : + OFX::Image *_srcImg; + OFX::Image *_maskImg; + double _rScale, _gScale, _bScale, _aScale; + bool _doMasking; + +public : + ImageScalerBase(OFX::ImageEffect &instance): OFX::ImageProcessor(instance), _srcImg(0), _maskImg(0), + _rScale(1), _gScale(1), _bScale(1), _aScale(1), _doMasking(false) + { + } + void setSrcImg(OFX::Image *v) {_srcImg = v;} + void setMaskImg(OFX::Image *v) {_maskImg = v;} + void doMasking(bool v) {_doMasking = v;} + void setScales(float r, float g, float b, float a) + { + _rScale = r; + _gScale = g; + _bScale = b; + _aScale = a; + } +}; + +template +class ImageScaler : public ImageScalerBase +{ +public : + ImageScaler(OFX::ImageEffect &instance): ImageScalerBase(instance) + {} + void multiThreadProcessImages(OfxRectI procWindow) + { + float scales[4]; + scales[0] = nComponents == 1 ? (float)_aScale : (float)_rScale; + scales[1] = (float)_gScale; + scales[2] = (float)_bScale; + scales[3] = (float)_aScale; + float maskScale = 1.0f; + for(int y = procWindow.y1; y < procWindow.y2; y++) + { + if(_effect.abort()) + break; + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + for(int x = procWindow.x1; x < procWindow.x2; x++) + { + PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0); + if(_doMasking) + { + if(!_maskImg) + maskScale = 1.0f; + else + { + PIX *maskPix = (PIX *) (_maskImg ? _maskImg->getPixelAddress(x, y) : 0); + maskScale = maskPix != 0 ? float(*maskPix)/float(max) : 0.0f; + } + } + if(srcPix) + { + for(int c = 0; c < nComponents; c++) + { + float v = (float)(pow((double)srcPix[c], (double)scales[c])) * maskScale + (1.0f - maskScale) * srcPix[c]; + if(max == 1) + dstPix[c] = PIX(v); + else + dstPix[c] = PIX(Clamp(v, 0, max)); + } + } + else + { + for(int c = 0; c < nComponents; c++) + dstPix[c] = 0; + } + dstPix += nComponents; + } + } + } +}; + + +class GammaPlugin : public OFX::ImageEffect +{ +protected : + OFX::Clip *dstClip_; + OFX::Clip *srcClip_; + OFX::Clip *maskClip_; + OFX::DoubleParam *scale_; + OFX::DoubleParam *rScale_; + OFX::DoubleParam *gScale_; + OFX::DoubleParam *bScale_; + OFX::DoubleParam *aScale_; + OFX::BooleanParam *componentScalesEnabled_; +public : + GammaPlugin(OfxImageEffectHandle handle): ImageEffect(handle), dstClip_(0), srcClip_(0), scale_(0) + , rScale_(0), gScale_(0), bScale_(0), aScale_(0), componentScalesEnabled_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName); + maskClip_ = getContext() == OFX::eContextFilter ? NULL : fetchClip(getContext() == OFX::eContextPaint ? "Brush" : "Mask"); + scale_ = fetchDoubleParam("scale"); + rScale_ = fetchDoubleParam("scaleR"); + gScale_ = fetchDoubleParam("scaleG"); + bScale_ = fetchDoubleParam("scaleB"); + aScale_ = fetchDoubleParam("scaleA"); + componentScalesEnabled_ = fetchBooleanParam("scaleComponents"); + setEnabledness(); + } + void setEnabledness(); + virtual void render(const OFX::RenderArguments &args); + virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime); + virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName); + virtual void changedClip(const OFX::InstanceChangedArgs &args, const std::string &clipName); + virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod); + virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois); + void setupAndProcess(ImageScalerBase &, const OFX::RenderArguments &args); +}; + +void GammaPlugin::setupAndProcess(ImageScalerBase &processor, const OFX::RenderArguments &args) +{ + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + std::unique_ptr src(srcClip_->fetchImage(args.time)); + if(src.get()) + { + OFX::BitDepthEnum srcBitDepth = src->getPixelDepth(); + OFX::PixelComponentEnum srcComponents = src->getPixelComponents(); + if(srcBitDepth != dstBitDepth || srcComponents != dstComponents) + throw int(1); + } + std::unique_ptr mask; + if(getContext() != OFX::eContextFilter) + { + mask.reset(maskClip_->fetchImage(args.time)); + processor.doMasking(true); + processor.setMaskImg(mask.get()); + } + double r, g, b, a = aScale_->getValueAtTime(args.time); + r = g = b = scale_->getValueAtTime(args.time); + if(componentScalesEnabled_->getValueAtTime(args.time)) + { + r += rScale_->getValueAtTime(args.time); + g += gScale_->getValueAtTime(args.time); + b += bScale_->getValueAtTime(args.time); + } + processor.setDstImg(dst.get()); + processor.setSrcImg(src.get()); + processor.setRenderWindow(args.renderWindow); + processor.setScales((float)r, (float)g, (float)b, (float)a); + processor.process(); +} + +bool GammaPlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod) +{ + rod = srcClip_->getRegionOfDefinition(args.time); + return true; +} + +void GammaPlugin::getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois) +{ + rois.setRegionOfInterest(*srcClip_, args.regionOfInterest); + if(getContext() != OFX::eContextFilter) + rois.setRegionOfInterest(*maskClip_, args.regionOfInterest); +} + +void GammaPlugin::render(const OFX::RenderArguments &args) +{ + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + if(dstComponents == OFX::ePixelComponentRGBA) + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + case OFX::eBitDepthUShort : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + case OFX::eBitDepthFloat : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + case OFX::eBitDepthUShort : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + case OFX::eBitDepthFloat : + { + ImageScaler fred(*this); + setupAndProcess(fred, args); + break; + } + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } +} + +bool GammaPlugin:: isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime) +{ + double scale = scale_->getValueAtTime(args.time); + double rScale = 1, gScale = 1, bScale = 1, aScale = 1; + if(componentScalesEnabled_->getValueAtTime(args.time)) { + rScale = rScale_->getValueAtTime(args.time); + gScale = gScale_->getValueAtTime(args.time); + bScale = bScale_->getValueAtTime(args.time); + aScale = aScale_->getValueAtTime(args.time); + } + rScale += scale; + gScale += scale; + bScale += scale; + if(rScale == 1 && gScale == 1 && bScale == 1 && aScale == 1) { + identityClip = srcClip_; + identityTime = args.time; + return true; + } + return false; +} + +void GammaPlugin::setEnabledness(void) +{ + bool v = componentScalesEnabled_->getValue() && srcClip_->getPixelComponents() == OFX::ePixelComponentRGBA; + rScale_->setEnabled(v); + gScale_->setEnabled(v); + bScale_->setEnabled(v); + aScale_->setEnabled(v); +} + +void GammaPlugin::changedParam(const OFX::InstanceChangedArgs &/*args*/, const std::string ¶mName) +{ + if(paramName == "scaleComponents") + setEnabledness(); +} + +void GammaPlugin::changedClip(const OFX::InstanceChangedArgs &/*args*/, const std::string &clipName) +{ + if(clipName == kOfxImageEffectSimpleSourceClipName) + setEnabledness(); +} + +bool GammaInteract::draw(const OFX::DrawArgs &args) +{ + OfxRGBColourF col; + switch(_state) { +case eInActive : + col.r = col.g = col.b = 0.0f; + break; +case ePoised : + col.r = col.g = col.b = 0.5f; + break; +case ePicked : + col.r = col.g = col.b = 1.0f; + break; + } + + float dx = (float)(kBoxSize.x * args.pixelScale.x); + float dy = (float)(kBoxSize.y * args.pixelScale.y); + glPushMatrix(); + glColor3f(col.r, col.g, col.b); + glTranslated(_position.x, _position.y, 0); + glBegin(GL_POLYGON); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b); + glTranslated(_position.x, _position.y, 0); + glBegin(GL_LINE_LOOP); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + return true; +} + +bool GammaInteract::penMotion(const OFX::PenArgs &args) +{ + float dx = (float)(kBoxSize.x * args.pixelScale.x); + float dy = (float)(kBoxSize.y * args.pixelScale.y); + OfxPointD penPos = args.penPosition; + switch(_state) + { + case eInActive : + case ePoised : + { + StateEnum newState; + penPos.x -= _position.x; + penPos.y -= _position.y; + if(Absolute(penPos.x) < dx && Absolute(penPos.y) < dy) + { + newState = ePoised; + } + else + { + newState = eInActive; + } + + if(_state != newState) + { + _state = newState; + _effect->redrawOverlays(); + } + } + break; + case ePicked : + { + _position = penPos; + _effect->redrawOverlays(); + } + break; + } + return _state != eInActive; +} + +bool GammaInteract::penDown(const OFX::PenArgs &args) +{ + penMotion(args); + if(_state == ePoised) + { + _state = ePicked; + _position = args.penPosition; + _effect->redrawOverlays(); + } + return _state == ePicked; +} + +bool GammaInteract::penUp(const OFX::PenArgs &args) +{ + if(_state == ePicked) + { + _state = ePoised; + penMotion(args); + _effect->redrawOverlays(); + return true; + } + return false; +} + +using namespace OFX; + +class GammaOverlayDescriptor : public DefaultEffectOverlayDescriptor {}; + +void GammaExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + desc.setLabels("Gamma", "Gamma", "Gamma"); + desc.setPluginGrouping("OFX Example (Support)"); + desc.addSupportedContext(eContextFilter); + desc.addSupportedContext(eContextGeneral); + desc.addSupportedContext(eContextPaint); + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + desc.setOverlayInteractDescriptor( new GammaOverlayDescriptor ); +} + +static +DoubleParamDescriptor *defineScaleParam(OFX::ImageEffectDescriptor &desc, + const std::string &name, const std::string &label, const std::string &hint, + GroupParamDescriptor *parent, double def = 1.0) +{ + DoubleParamDescriptor *param = desc.defineDoubleParam(name); + param->setLabels(label, label, label); + param->setScriptName(name); + param->setHint(hint); + param->setDefault(def); + param->setRange(0, 10); + param->setIncrement(0.1); + param->setDisplayRange(0, 10); + param->setDoubleType(eDoubleTypeScale); + if(parent) + param->setParent(*parent); + return param; +} + +void GammaExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context) +{ + ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->addSupportedComponent(ePixelComponentAlpha); + srcClip->setTemporalClipAccess(false); + srcClip->setSupportsTiles(true); + srcClip->setIsMask(false); + + if(context == eContextGeneral || context == eContextPaint) + { + ClipDescriptor *maskClip = context == eContextGeneral ? desc.defineClip("Mask") : desc.defineClip("Brush"); + maskClip->addSupportedComponent(ePixelComponentAlpha); + maskClip->setTemporalClipAccess(false); + if(context == eContextGeneral) + maskClip->setOptional(true); + maskClip->setSupportsTiles(true); + maskClip->setIsMask(true); + } + + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + + PageParamDescriptor *page = desc.definePageParam("Controls"); + + GroupParamDescriptor *componentScalesGroup = desc.defineGroupParam("componentScales"); + componentScalesGroup->setHint("Scales on the individual component"); + componentScalesGroup->setLabels("Components", "Components", "Components"); + + DoubleParamDescriptor *param = defineScaleParam(desc, "scale", "scale", "Scales all component in the image", 0, 1.0); + page->addChild(*param); + + BooleanParamDescriptor *boolP = desc.defineBooleanParam("scaleComponents"); + boolP->setDefault(true); + boolP->setHint("Enables gamma correction on individual components"); + boolP->setLabels("Gamma Components", "Gamma Components", "Gamma Components"); + boolP->setParent(*componentScalesGroup); + page->addChild(*boolP); + + param = defineScaleParam(desc, "scaleR", "red", "Gamma corrects the red component of the image", componentScalesGroup, 0.0); + page->addChild(*param); + + param = defineScaleParam(desc, "scaleG", "green", "Gamma corrects the green component of the image", componentScalesGroup, 0.0); + page->addChild(*param); + + param = defineScaleParam(desc, "scaleB", "blue", "Gamma corrects the blue component of the image", componentScalesGroup, 0.0); + page->addChild(*param); + + param = defineScaleParam(desc, "scaleA", "alpha", "Gamma corrects the alpha component of the image", componentScalesGroup, 0.0); + page->addChild(*param); + +} + +ImageEffect* GammaExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/) +{ + return new GammaPlugin(handle); +} + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.h b/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.h new file mode 100755 index 000000000..7e6d6553f --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/multibundle1.h @@ -0,0 +1,13 @@ + + +#include "ofxsCore.h" + +class GammaExamplePluginFactory : public OFX::PluginFactoryHelper +{ +public: + GammaExamplePluginFactory():OFX::PluginFactoryHelper("net.sf.openfx.gammaexample", 1, 0){} + virtual void describe(OFX::ImageEffectDescriptor &desc); + virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context); + virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context); +}; + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.cpp b/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.cpp new file mode 100644 index 000000000..699ad871d --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.cpp @@ -0,0 +1,431 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" +#include "../include/ofxsProcessing.H" + +#include "multibundle2.h" + +static const OfxPointD kBoxSize = {20, 20}; + +class DotExampleInteract : public OFX::OverlayInteract +{ +protected : + enum StateEnum { + eInActive, + ePoised, + ePicked + }; + StateEnum _state; + OFX::Double2DParam* position_; +public : + DotExampleInteract(OfxInteractHandle handle, OFX::ImageEffect* effect) : OFX::OverlayInteract(handle), _state(eInActive) + { + position_ = effect->fetchDouble2DParam("position"); + } + virtual bool draw(const OFX::DrawArgs &args); + virtual bool penMotion(const OFX::PenArgs &args); + virtual bool penDown(const OFX::PenArgs &args); + virtual bool penUp(const OFX::PenArgs &args); +}; + +template +inline T Absolute(T a) +{ + return (a < 0) ? -a : a; +} + +class DotGeneratorBase : public OFX::ImageProcessor +{ +public : + DotGeneratorBase(OFX::ImageEffect &instance) : OFX::ImageProcessor(instance), _radius(0.0f), _positionx(0.0f), _positiony(0.0f) + { + _colour[0] = _colour[1] = _colour[2] = _colour[3] = 0; + } + void setRadius(float v) { _radius = v; } + void setR(float v) { _colour[0] = v;} + void setG(float v) { _colour[1] = v;} + void setB(float v) { _colour[2] = v;} + void setA(float v) { _colour[3] = v;} + void setColour(double r, double g, double b, double a) + { + setR((float)r); + setG((float)g); + setB((float)b); + setA((float)a); + } + void setPosition(float x, float y) + { + _positionx = x; + _positiony = y; + } +protected: + float _radius; + float _colour[4]; + float _positionx; + float _positiony; +}; + +template +class DotGenerator : public DotGeneratorBase { +public : + DotGenerator(OFX::ImageEffect &instance): DotGeneratorBase(instance){} + void multiThreadProcessImages(OfxRectI procWindow) + { + float radiusSq = _radius * _radius; + for(int y = procWindow.y1; y < procWindow.y2; y++) + { + if(_effect.abort()) + break; + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + for(int x = procWindow.x1; x < procWindow.x2; x++) + { + float radsq = (x - _positionx)*(x - _positionx) + (y - _positiony)*(y - _positiony); + float val = radsq/radiusSq; + for(int c = 0; c < nComponents; c++) + { + dstPix[c] = val < 1.0f ? PIX((1.0f-val)*max) : PIX(0); + dstPix[c] = (PIX)(dstPix[c] * _colour[c]); + } + dstPix += nComponents; + } + } + } +}; + +class DotExamplePlugin : public OFX::ImageEffect +{ +protected: + OFX::Clip *dstClip_; + OFX::DoubleParam *radius_; + OFX::RGBAParam *colour_; + OFX::Double2DParam* position_; +public: + DotExamplePlugin(OfxImageEffectHandle handle): ImageEffect(handle), dstClip_(0), radius_(0) , colour_(0), position_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + radius_ = fetchDoubleParam("radius"); + colour_ = fetchRGBAParam("colour"); + position_ = fetchDouble2DParam("position"); + } + virtual void render(const OFX::RenderArguments &args); + void setupAndProcess(DotGeneratorBase &, const OFX::RenderArguments &args); + bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod); + template + void getPositionInPixels(double& x, double& y, const ARGS& args); + template + void getPositionInCanonical(double& x, double& y, const ARGS& args); +}; + +template +void DotExamplePlugin::getPositionInCanonical(double& x, double& y, const ARGS& args) +{ + position_->getValueAtTime(args.time, x, y); +} + +template +void DotExamplePlugin::getPositionInPixels(double& x, double& y, const ARGS& args) +{ + double xpos, ypos; + getPositionInCanonical(xpos, ypos, args); + x = (xpos * args.renderScale.x) /getProjectPixelAspectRatio(); + y = ypos * args.renderScale.y; +} + +void DotExamplePlugin::setupAndProcess(DotGeneratorBase &processor, const OFX::RenderArguments &args) +{ + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + //OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + //OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + double rad = radius_->getValueAtTime(args.time); + processor.setRadius((float)(rad)); + double r, g, b, a; + colour_->getValueAtTime(args.time, r, g, b, a); + processor.setColour(r,g,b,a); + processor.setDstImg(dst.get()); + processor.setRenderWindow(args.renderWindow); + double xpospixel, ypospixel; + getPositionInPixels(xpospixel, ypospixel, args); + float fieldScaler = (args.fieldToRender == OFX::eFieldLower || args.fieldToRender == OFX::eFieldUpper)? 0.5f: 1.0f; + ypospixel *= fieldScaler; + processor.setPosition((float)xpospixel, (float)ypospixel); + processor.process(); +} + + +bool DotExamplePlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod) +{ + double r = radius_->getValueAtTime(args.time); + double x, y; + position_->getValueAtTime(args.time, x, y); + rod.x1 = x - r; + rod.y1 = y - r; + rod.x2 = x + r; + rod.y2 = y + r; + return true; +} + +void DotExamplePlugin::render(const OFX::RenderArguments &args) +{ + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + if(dstComponents == OFX::ePixelComponentRGBA) + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + case OFX::eBitDepthUShort : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + case OFX::eBitDepthFloat : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + case OFX::eBitDepthUShort : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + case OFX::eBitDepthFloat : + { + DotGenerator fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } +} + + +bool DotExampleInteract::draw(const OFX::DrawArgs &args) +{ + OfxRGBColourF col; + col.r = 0.5f; + col.g = 0.0f; + + switch(_state) + { + case eInActive : + col.b = 0.0f; + break; + case ePoised : + col.b = 0.5f; + break; + case ePicked : + col.b = 1.0f; + break; + } + + float dx = (float)(kBoxSize.x * args.pixelScale.x); + float dy = (float)(kBoxSize.y * args.pixelScale.y); + double xpos = 0., ypos = 0.; + DotExamplePlugin* plug = dynamic_cast(_effect); + assert(plug); + if (plug) { + plug->getPositionInCanonical(xpos, ypos, args); + } + glPushMatrix(); + glColor3f(col.r, col.g, col.b); + glTranslated(xpos, ypos, 0); + glBegin(GL_POLYGON); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b); + glTranslated(xpos, ypos, 0); + glBegin(GL_LINE_LOOP); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + return true; +} + +bool DotExampleInteract::penMotion(const OFX::PenArgs &args) +{ + float dx = (float)(kBoxSize.x * args.pixelScale.x); + float dy = (float)(kBoxSize.y * args.pixelScale.y); + OfxPointD penPos = args.penPosition; + switch(_state) + { + case eInActive : + case ePoised : + { + StateEnum newState; + double xpos = 0., ypos = 0.; + DotExamplePlugin* plug = dynamic_cast(_effect); + if (plug) { + plug->getPositionInCanonical(xpos, ypos, args); + } + penPos.x -= xpos; + penPos.y -= ypos; + if(Absolute(penPos.x) < dx && Absolute(penPos.y) < dy) + { + newState = ePoised; + } + else + { + newState = eInActive; + } + + if(_state != newState) + { + _state = newState; + _effect->redrawOverlays(); + } + } + break; + case ePicked : + { + + position_->setValueAtTime(args.time, args.penPosition.x, args.penPosition.y); + _effect->redrawOverlays(); + } + break; + } + return _state != eInActive; +} + +bool DotExampleInteract::penDown(const OFX::PenArgs &args) +{ + penMotion(args); + if(_state == ePoised) + { + _state = ePicked; + _effect->redrawOverlays(); + } + return _state == ePicked; +} + +bool DotExampleInteract::penUp(const OFX::PenArgs &args) +{ + if(_state == ePicked) + { + _state = ePoised; + penMotion(args); + _effect->redrawOverlays(); + return true; + } + return false; +} + +using namespace OFX; + +class DotExampleOverlayDescriptor : public DefaultEffectOverlayDescriptor {}; + +void DotExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + desc.setLabels("Dot Generator", "Dot Generator", "Dot Generator"); + desc.setPluginGrouping("OFX Example (Support)"); + desc.addSupportedContext(eContextGenerator); + desc.addSupportedContext(eContextGeneral); + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + desc.setRenderTwiceAlways(false); + desc.setOverlayInteractDescriptor( new DotExampleOverlayDescriptor ); +} + +void DotExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/) +{ + // there has to be an input clip, even for generators + ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); + srcClip->addSupportedComponent( OFX::ePixelComponentRGBA ); + srcClip->addSupportedComponent( OFX::ePixelComponentAlpha ); + srcClip->setSupportsTiles(true); + srcClip->setOptional(true); + + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + dstClip->setFieldExtraction(eFieldExtractSingle); + + DoubleParamDescriptor *param = desc.defineDoubleParam("radius"); + param->setLabels("Radius", "Radius", "Radius"); + param->setScriptName("radius"); + param->setHint("The radius of the dot produced."); + param->setDoubleType(eDoubleTypeX); + param->setDefaultCoordinateSystem(eCoordinatesNormalised); + param->setDefault(0.02); + //param->setRange(0, 1); + param->setIncrement(1); + param->setDisplayRange(0, 1); + param->setAnimates(true); + + RGBAParamDescriptor *param2 = desc.defineRGBAParam("colour"); + param2->setAnimates(true); + param2->setLabels("Colour", "Colour", "Colour"); + param2->setHint("The colour of the dot produced."); + param2->setScriptName("colour"); + param2->setDefault(1.0, 1.0, 1.0, 1.0); + + Double2DParamDescriptor* param3 = desc.defineDouble2DParam("position"); + param3->setLabels("Dot Position", "Dot Position", "Dot Position"); + param3->setDoubleType(eDoubleTypeXY); + param3->setDefaultCoordinateSystem(eCoordinatesNormalised); + param3->setAnimates(true); + param3->setDimensionLabels("X", "Y"); + param3->setDefault(0.5, 0.5); + + PageParamDescriptor *page = desc.definePageParam("Controls"); + page->addChild(*param); + page->addChild(*param2); + page->addChild(*param3); +} + +ImageEffect* DotExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/) +{ + return new DotExamplePlugin(handle); +} + diff --git a/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.h b/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.h new file mode 100755 index 000000000..47ea7104b --- /dev/null +++ b/third_party/openfx/Support/Plugins/MultiBundle/multibundle2.h @@ -0,0 +1,13 @@ + + +#include "ofxsImageEffect.h" + +class DotExamplePluginFactory : public OFX::PluginFactoryHelper +{ +public: + DotExamplePluginFactory():OFX::PluginFactoryHelper("net.sf.openfx.dotexample", 1, 0){} + virtual void describe(OFX::ImageEffectDescriptor &desc); + virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context); + virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context); +}; + diff --git a/third_party/openfx/Support/Plugins/Retimer/Info.plist b/third_party/openfx/Support/Plugins/Retimer/Info.plist new file mode 100644 index 000000000..2156abb22 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Retimer/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + retimer.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Retimer/retimer.cpp b/third_party/openfx/Support/Plugins/Retimer/retimer.cpp new file mode 100644 index 000000000..d7361adb7 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Retimer/retimer.cpp @@ -0,0 +1,386 @@ + + +#include // for floor +#include // for FLT_MAX + +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" + +#include "../include/ofxsProcessing.H" +#include "../include/ofxsImageBlender.H" + + namespace OFX { + extern ImageEffectHostDescription gHostDescription; + } +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class RetimerPlugin : public OFX::ImageEffect { +protected : + // do not need to delete these, the ImageEffect is managing them for us + OFX::Clip *dstClip_; /**< @brief Mandated output clips */ + OFX::Clip *srcClip_; /**< @brief Mandated input clips */ + + OFX::DoubleParam *sourceTime_; /**< @brief mandated parameter, only used in the retimer context. */ + OFX::DoubleParam *speed_; /**< @brief only used in the filter context. */ + OFX::DoubleParam *duration_; /**< @brief how long the output should be as a proportion of input. General context only */ + +public : + /** @brief ctor */ + RetimerPlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , dstClip_(0) + , srcClip_(0) + , sourceTime_(0) + , speed_(0) + , duration_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName); + + // What parameters we instantiate depend on the context + if(getContext() == OFX::eContextRetimer) + // fetch the mandated parameter which the host uses to pass us the frame to retime to + sourceTime_ = fetchDoubleParam(kOfxImageEffectRetimerParamName); + else // context == OFX::eContextFilter || context == OFX::eContextGeneral + // filter context means we are in charge of how to retime, and our example is using a speed curve to do that + speed_ = fetchDoubleParam("Speed"); + + // fetch duration param for general context + if(getContext() == OFX::eContextGeneral) + duration_ = fetchDoubleParam("Duration"); + } + + /* Override the render */ + virtual void render(const OFX::RenderArguments &args); + + /** Override the get frames needed action */ + virtual void getFramesNeeded(const OFX::FramesNeededArguments &args, OFX::FramesNeededSetter &frames); + + /* override the time domain action, only for the general context */ + virtual bool getTimeDomain(OfxRangeD &range); + + /* set up and run a processor */ + void + setupAndProcess(OFX::ImageBlenderBase &, const OFX::RenderArguments &args); +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the filter */ + +//////////////////////////////////////////////////////////////////////////////// +// basic plugin render function, just a skelington to instantiate templates from + +// make sure components are sane +static void +checkComponents(const OFX::Image &src, + OFX::BitDepthEnum dstBitDepth, + OFX::PixelComponentEnum dstComponents) +{ + OFX::BitDepthEnum srcBitDepth = src.getPixelDepth(); + OFX::PixelComponentEnum srcComponents = src.getPixelComponents(); + + // see if they have the same depths and bytes and all + if(srcBitDepth != dstBitDepth || srcComponents != dstComponents) + throw int(1); // HACK!! need to throw an sensible exception here! +} + +static void framesNeeded(double sourceTime, OFX::FieldEnum fieldToRender, double *fromTimep, double *toTimep, double *blendp) +{ + // figure the two images we are blending between + double fromTime, toTime; + double blend; + + if (fieldToRender == OFX::eFieldNone) { + // unfielded, easy peasy + fromTime = floor(sourceTime); + toTime = fromTime + 1; + blend = sourceTime - fromTime; + } + else { + // Fielded clips, pook. We are rendering field doubled images, + // and so need to blend between fields, not frames. + double frac = sourceTime - floor(sourceTime); + if(frac < 0.5) { + // need to go between the first and second fields of this frame + fromTime = floor(sourceTime); // this will get the first field + toTime = fromTime + 0.5; // this will get the second field of the same frame + blend = frac * 2.0; // and the blend is between those two + } + else { // frac > 0.5 + fromTime = floor(sourceTime) + 0.5; // this will get the second field of this frame + toTime = floor(sourceTime) + 1.0; // this will get the first field of the next frame + blend = (frac - 0.5) * 2.0; + } + } + *fromTimep = fromTime; + *toTimep = toTime; + *blendp = blend; +} + +/* set up and run a processor */ +void +RetimerPlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::RenderArguments &args) +{ + // get a dst image + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // figure the frame we should be retiming from + double sourceTime; + + if(getContext() == OFX::eContextRetimer) { + // the host is specifying it, so fetch it from the kOfxImageEffectRetimerParamName pseudo-param + sourceTime = sourceTime_->getValueAtTime(args.time); + } + else { + // we have our own param, which is a speed, so we integrate it to get the time we want + sourceTime = speed_->integrate(0, args.time); + } + + // figure the two images we are blending between + double fromTime, toTime; + double blend; + framesNeeded(sourceTime, args.fieldToRender, &fromTime, &toTime, &blend); + + // fetch the two source images + std::unique_ptr fromImg(srcClip_->fetchImage(fromTime)); + std::unique_ptr toImg(srcClip_->fetchImage(toTime)); + + // make sure bit depths are sane + if(fromImg.get()) checkComponents(*fromImg, dstBitDepth, dstComponents); + if(toImg.get()) checkComponents(*toImg, dstBitDepth, dstComponents); + + // set the images + processor.setDstImg(dst.get()); + processor.setFromImg(fromImg.get()); + processor.setToImg(toImg.get()); + + // set the render window + processor.setRenderWindow(args.renderWindow); + + // set the blend between + processor.setBlend((float)blend); + + // Call the base class process member, this will call the derived templated process code + processor.process(); +} + +void +RetimerPlugin::getFramesNeeded(const OFX::FramesNeededArguments &args, + OFX::FramesNeededSetter &frames) +{ + // figure the two images we are blending between + double fromTime, toTime; + double blend; + // whatever the rendered field is, the frames are the same + framesNeeded(args.time, OFX::eFieldNone, &fromTime, &toTime, &blend); + OfxRangeD range; + range.min = fromTime; + range.max = toTime; + frames.setFramesNeeded(*srcClip_, range); +} + +/* override the time domain action, only for the general context */ +bool +RetimerPlugin::getTimeDomain(OfxRangeD &range) +{ + // this should only be called in the general context, ever! + if(getContext() == OFX::eContextGeneral) { + // If we are a general context, we can changed the duration of the effect, so have a param to do that + // We need a separate param as it is impossible to derive this from a speed param and the input clip + // duration (the speed may be animating or wired to an expression). + double duration = duration_->getValue(); //don't animate + + // how many frames on the input clip + OfxRangeD srcRange = srcClip_->getFrameRange(); + + range.min = 0; + range.max = srcRange.max * duration; + return true; + } + + return false; +} + +// the overridden render function +void +RetimerPlugin::render(const OFX::RenderArguments &args) +{ + // instantiate the render code based on the pixel depth of the dst clip + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + + // do the rendering + if(dstComponents == OFX::ePixelComponentRGBA) { + switch(dstBitDepth) { + case OFX::eBitDepthUByte : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) { + case OFX::eBitDepthUByte : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } // switch +} + +using namespace OFX; +mDeclarePluginFactory(RetimerExamplePluginFactory, ;, {}); + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static RetimerExamplePluginFactory p("net.sf.openfx.retimer", 1, 0); + ids.push_back(&p); + } + }; +}; + +void RetimerExamplePluginFactory::load() +{ + // we can't be used on hosts that don't perfrom temporal clip access + if(!gHostDescription.temporalClipAccess) { + throw OFX::Exception::HostInadequate("Need random temporal image access to work"); + } +} + +/** @brief The basic describe function, passed a plugin descriptor */ +void RetimerExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + // basic labels + desc.setLabels("Retimer", "Retimer", "Retimer"); + desc.setPluginGrouping("OFX Example (Support)"); + + // Say we are a transition context + desc.addSupportedContext(OFX::eContextRetimer); + desc.addSupportedContext(OFX::eContextFilter); + desc.addSupportedContext(OFX::eContextGeneral); + + // Add supported pixel depths + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + + // set a few flags + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(true); // say we will be doing random time access on clips + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); +} + +/** @brief The describe in context function, passed a plugin descriptor and a context */ +void RetimerExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context) +{ + // we are a transition, so define the sourceTo input clip + ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->addSupportedComponent(ePixelComponentAlpha); + srcClip->setTemporalClipAccess(true); // say we will be doing random time access on this clip + srcClip->setSupportsTiles(true); + srcClip->setFieldExtraction(eFieldExtractDoubled); // which is the default anyway + + // create the mandated output clip + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setFieldExtraction(eFieldExtractDoubled); // which is the default anyway + dstClip->setSupportsTiles(true); + + // what param we have is dependant on the host + if(context == OFX::eContextRetimer) { + // Define the mandated kOfxImageEffectRetimerParamName param, note that we don't do anything with this other than. + // describe it. It is not a true param but how the host indicates to the plug-in which frame + // it wants you to retime to. It appears on no plug-in side UI, it is purely the host's to manage. + DoubleParamDescriptor *param = desc.defineDoubleParam(kOfxImageEffectRetimerParamName); + (void)param; + } + else { + // We are a general or filter context, define a speed param and a page of controls to put that in + DoubleParamDescriptor *param = desc.defineDoubleParam("Speed"); + param->setLabels("speed", "speed", "speed"); + param->setScriptName("speed"); + param->setHint("How much to changed the speed of the input clip"); + param->setDefault(1); + param->setRange(-FLT_MAX, FLT_MAX); + param->setIncrement(0.05); + param->setDisplayRange(0, 1); + param->setAnimates(true); // can animate + param->setDoubleType(eDoubleTypeScale); + + // make a page to put it in + PageParamDescriptor *page = desc.definePageParam("Controls"); + + // add our speed param into it + page->addChild(*param); + + // If we are a general context, we can change the duration of the effect, so have a param to do that + // We need a separate param as it is impossible to derive this from a speed param and the input clip + // duration (the speed may be animating or wired to an expression). + if(context == OFX::eContextGeneral) { + // We are a general or filter context, define a speed param and a page of controls to put that in + DoubleParamDescriptor *param = desc.defineDoubleParam("Duration"); + param->setLabels("duration", "duraction", "duration"); + param->setScriptName("duration"); + param->setHint("How long the output clip should be, as a proportion of the input clip's length."); + param->setDefault(1); + param->setRange(0, 10); + param->setIncrement(0.1); + param->setDisplayRange(0, 10); + param->setAnimates(false); // no animation here! + param->setDoubleType(eDoubleTypeScale); + + // add param to page + page->addChild(*param); + } + } +} + +/** @brief The create instance function, the plugin must return an object derived from the \ref OFX::ImageEffect class */ +ImageEffect* RetimerExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/) +{ + return new RetimerPlugin(handle); +} diff --git a/third_party/openfx/Support/Plugins/Retimer/retimer.dsp b/third_party/openfx/Support/Plugins/Retimer/retimer.dsp new file mode 100755 index 000000000..bff7dd3cc --- /dev/null +++ b/third_party/openfx/Support/Plugins/Retimer/retimer.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="retimer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=retimer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "retimer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "retimer.mak" CFG="retimer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "retimer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "retimer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "retimer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/retimer.ofx" + +!ELSEIF "$(CFG)" == "retimer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\Retimer.ofx.bundle\Contents\Win32\retimer.ofx" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "retimer - Win32 Release" +# Name "retimer - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\retimer.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/third_party/openfx/Support/Plugins/Retimer/retimer.dsw b/third_party/openfx/Support/Plugins/Retimer/retimer.dsw new file mode 100755 index 000000000..614ef8642 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Retimer/retimer.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "retimer"=.\retimer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name ofxsupport + End Project Dependency +}}} + +############################################################################### + +Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/Plugins/Retimer/retimer.vcproj b/third_party/openfx/Support/Plugins/Retimer/retimer.vcproj new file mode 100755 index 000000000..ed934eb5e --- /dev/null +++ b/third_party/openfx/Support/Plugins/Retimer/retimer.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/Tester/Info.plist b/third_party/openfx/Support/Plugins/Tester/Info.plist new file mode 100644 index 000000000..01a1c0f1c --- /dev/null +++ b/third_party/openfx/Support/Plugins/Tester/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + tester.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Tester/Tester.cpp b/third_party/openfx/Support/Plugins/Tester/Tester.cpp new file mode 100644 index 000000000..2b2506544 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Tester/Tester.cpp @@ -0,0 +1,528 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" +#include "ofxsInteract.h" + +#include "../include/ofxsProcessing.H" + +static const OfxPointD kBoxSize = {5, 5}; + +template +inline T Minimum(T a, T b) { return (a < b) ? a : b;} + +template +inline T Absolute(T a) { return (a < 0) ? -a : a;} + +class PositionInteract : public OFX::OverlayInteract +{ +protected : + enum StateEnum { + eInActive, + ePoised, + ePicked + }; + + StateEnum _state; + OFX::Double2DParam* _position; +public : + PositionInteract(OfxInteractHandle handle, OFX::ImageEffect* effect) + : OFX::OverlayInteract(handle) + , _state(eInActive) + { + _position = effect->fetchDouble2DParam("widgetPos"); + } + + // overridden functions from OFX::Interact to do things + virtual bool draw(const OFX::DrawArgs &args); + virtual bool penMotion(const OFX::PenArgs &args); + virtual bool penDown(const OFX::PenArgs &args); + virtual bool penUp(const OFX::PenArgs &args); + OfxPointD getCanonicalPosition(double time) const + { + OfxPointD retVal; + _position->getValueAtTime(time, retVal.x, retVal.y); + return retVal; + } + void setCanonicalPosition(double x, double y, double time) + { + _position->setValueAtTime(time, x, y); + } +}; + +bool PositionInteract::draw(const OFX::DrawArgs &args) +{ + OfxRGBColourF col; + switch(_state) + { + case eInActive : col.r = col.g = col.b = 0.0f; break; + case ePoised : col.r = col.g = col.b = 0.5f; break; + case ePicked : col.r = col.g = col.b = 1.0f; break; + } + + // make the box a constant size on screen by scaling by the pixel scale + float dx = (float)(kBoxSize.x / args.pixelScale.x); + float dy = (float)(kBoxSize.y / args.pixelScale.y); + + // Draw a cross hair, the current coordinate system aligns with the image plane. + glPushMatrix(); + + // draw the bo + OfxPointD pos = getCanonicalPosition(args.time); + glColor3f(col.r, col.g, col.b); + glTranslated(pos.x, pos.y, 0); + glBegin(GL_POLYGON); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + + glPushMatrix(); + // draw a complementary outline + glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b); + glTranslated(pos.x, pos.y, 0); + glBegin(GL_LINE_LOOP); + glVertex2f(-dx, -dy); + glVertex2f(-dx, dy); + glVertex2f( dx, dy); + glVertex2f( dx, -dy); + glEnd(); + glPopMatrix(); + + return true; +} + +// overridden functions from OFX::Interact to do things +bool PositionInteract::penMotion(const OFX::PenArgs &args) +{ + // figure the size of the box in cannonical coords + float dx = (float)(kBoxSize.x / args.pixelScale.x); + float dy = (float)(kBoxSize.y / args.pixelScale.y); + + OfxPointD pos = getCanonicalPosition(args.time); + + // pen position is in cannonical coords + OfxPointD penPos = args.penPosition; + + switch(_state) + { + case eInActive : + case ePoised : + { + // are we in the box, become 'poised' + StateEnum newState; + penPos.x -= pos.x; + penPos.y -= pos.y; + if(Absolute(penPos.x) < dx && + Absolute(penPos.y) < dy) { + newState = ePoised; + } + else { + newState = eInActive; + } + + if(_state != newState) { + _state = newState; + _effect->redrawOverlays(); + } + } + break; + + case ePicked : + { + setCanonicalPosition(penPos.x, penPos.y, args.time); + _effect->redrawOverlays(); + } + break; + } + return _state != eInActive; +} + +bool PositionInteract::penDown(const OFX::PenArgs &args) +{ + penMotion(args); + if(_state == ePoised) { + _state = ePicked; + setCanonicalPosition(args.penPosition.x, args.penPosition.y, args.time); + _effect->redrawOverlays(); + } + + return _state == ePicked; +} + +bool PositionInteract::penUp(const OFX::PenArgs &args) +{ + if(_state == ePicked) + { + _state = ePoised; + penMotion(args); + _effect->redrawOverlays(); + return true; + } + return false; +} + +class GenericTestBase : public OFX::ImageProcessor { +protected : + OFX::Image *_srcImg; +public : + GenericTestBase(OFX::ImageEffect &instance): OFX::ImageProcessor(instance), _srcImg(0) + { + } + void setSrcImg(OFX::Image *v) {_srcImg = v;} +}; + +template +class ImageGenericTester : public GenericTestBase +{ +public : + ImageGenericTester(OFX::ImageEffect &instance) : GenericTestBase(instance){} + void multiThreadProcessImages(OfxRectI procWindow) + { + for(int y = procWindow.y1; y < procWindow.y2; y++) + { + if(_effect.abort()) + break; + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + for(int x = procWindow.x1; x < procWindow.x2; x++) + { + PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0); + if(srcPix) + { + for(int c = 0; c < nComponents; c++) + dstPix[c] = max - srcPix[c]; + } + else + { + for(int c = 0; c < nComponents; c++) + dstPix[c] = 0; + } + dstPix += nComponents; + } + } + } +}; + + + +template +class Analyser +{ +public: + Analyser(OFX::Clip* srcClip, OFX::DoubleParam* dbl) + { + OfxRangeD range = srcClip->getFrameRange(); + for(double d = range.min; d< range.max; ++d) + { + std::unique_ptr src(srcClip->fetchImage(d)); + dbl->setValueAtTime(d, d); + } + } +}; + +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class GenericTestPlugin : public OFX::ImageEffect +{ +protected : + OFX::Clip *dstClip_; + OFX::Clip *srcClip_; + +public : + GenericTestPlugin(OfxImageEffectHandle handle) : ImageEffect(handle), dstClip_(0), srcClip_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName); + } + + virtual void render(const OFX::RenderArguments &args); + void setupAndProcess(GenericTestBase &, const OFX::RenderArguments &args); + void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName) + { + if(paramName=="enableTest") + { + OFX::ChoiceParam* choice = fetchChoiceParam("enableTest"); + OFX::DoubleParam* dbl = fetchDoubleParam("enableDbl"); + int value = 0; + choice->getValueAtTime(args.time, value); + dbl->setEnabled(value ==0 ); + } + else if(paramName=="pbButton") + { + sendMessage(OFX::Message::eMessageMessage, "", "Push Button Pressed - TestPassed!"); + } + else if(paramName=="widgetPos") + { + redrawOverlays(); + } + else if(paramName == "analyseButton") + { + OFX::BitDepthEnum dstBitDepth = srcClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = srcClip_->getPixelComponents(); + OFX::DoubleParam* dbl = fetchDoubleParam("analysisParam"); + + if(dstComponents == OFX::ePixelComponentRGBA) + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + Analyser analyse(srcClip_, dbl); + break; + } + case OFX::eBitDepthUShort : + { + Analyser analyse(srcClip_, dbl); + break; + } + case OFX::eBitDepthFloat : + { + Analyser analyse(srcClip_, dbl); + break; + } + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + Analyser analyse(srcClip_, dbl); + break; + } + case OFX::eBitDepthUShort : + { + Analyser analyse(srcClip_, dbl); + break; + } + case OFX::eBitDepthFloat : + { + Analyser analyse(srcClip_, dbl); + break; + } + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + } + } +}; + + +void GenericTestPlugin::setupAndProcess(GenericTestBase &processor, const OFX::RenderArguments &args) +{ + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + std::unique_ptr src(srcClip_->fetchImage(args.time)); + + if(src.get()) + { + OFX::BitDepthEnum srcBitDepth = src->getPixelDepth(); + OFX::PixelComponentEnum srcComponents = src->getPixelComponents(); + + // see if they have the same depths and bytes and all + if(srcBitDepth != dstBitDepth || srcComponents != dstComponents) + throw int(1); // HACK!! need to throw an sensible exception here! + } + + processor.setDstImg(dst.get()); + processor.setSrcImg(src.get()); + processor.setRenderWindow(args.renderWindow); + processor.process(); +} + + +void GenericTestPlugin::render(const OFX::RenderArguments &args) +{ + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + + if(dstComponents == OFX::ePixelComponentRGBA) + { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) + { + case OFX::eBitDepthUByte : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthUShort : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + + case OFX::eBitDepthFloat : + { + ImageGenericTester fred(*this); + setupAndProcess(fred, args); + } + break; + default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } +} + +class PositionOverlayDescriptor : public OFX::DefaultEffectOverlayDescriptor {}; + +mDeclarePluginFactory(GenericTestExamplePluginFactory, {}, {}); + +using namespace OFX; +void GenericTestExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + desc.setLabels("GenericTest", "GenericTest", "GenericTest"); + desc.setPluginGrouping("OFX Example (Support)"); + desc.addSupportedContext(eContextFilter); + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + + desc.setOverlayInteractDescriptor( new PositionOverlayDescriptor); +} + +void GenericTestExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/) +{ + ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->addSupportedComponent(ePixelComponentAlpha); + srcClip->setTemporalClipAccess(false); + srcClip->setSupportsTiles(true); + srcClip->setIsMask(false); + + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + + DoubleParamDescriptor *param1 = desc.defineDoubleParam("MinMaxTest"); + param1->setLabels("Min/Max Test", "Min/Max Test", "Min/Max Test"); + param1->setScriptName("minMaxTest"); + param1->setHint("A double parameter to illustrate visual min/max."); + param1->setDefault(50.0); + param1->setRange(-1000, 1000); + param1->setDisplayRange(-1000, 1000); + param1->setDoubleType(eDoubleTypePlain); + + ChoiceParamDescriptor* param2 = desc.defineChoiceParam("enableTest"); + param2->setLabels("Enabler", "Enabler", "Enabler"); + param2->appendOption("Enable parameter", "Enable parameter"); + param2->appendOption("Disable parameter", "Disable parameter"); + + DoubleParamDescriptor *param3 = desc.defineDoubleParam("enableDbl"); + param3->setLabels("Enabled by Enabler", "Enabled by Enabler", "Enabled by Enabler"); + + + BooleanParamDescriptor* bparam = desc.defineBooleanParam("Insignificant"); + bparam->setLabels("Insignificant", "Insignificant", "Insignificant"); + bparam->setHint("Shouldn't cause a re-render."); + bparam->setEvaluateOnChange(false); + + BooleanParamDescriptor* bparam2 = desc.defineBooleanParam("secretTest"); + bparam2->setLabels("SECRET!", "SECRET!", "SECRET!"); + bparam2->setIsSecret(true); + bparam2->setHint("Shouldn't be shown in the user interface."); + + BooleanParamDescriptor* bparam3 = desc.defineBooleanParam("nonPersistant"); + bparam3->setLabels("Non-persistant", "Non-persistant", "Non-persistant"); + bparam3->setHint("Shouldn't be saved in the plugin description."); + bparam3->setIsPersistant(false); + + DoubleParamDescriptor *param5 = desc.defineDoubleParam("animateDbl"); + param5->setLabels("No Animation", "No Animation", "No Animation"); + param5->setAnimates(false); + + DoubleParamDescriptor *param6 = desc.defineDoubleParam("angleTest"); + param6->setLabels("Angle?", "Angle?", "Angle?"); + param6->setRange(-180.0, 180.0); + param6->setHint("An angle parameter."); + param6->setDoubleType(eDoubleTypeAngle); + + PushButtonParamDescriptor* pb = desc.definePushButtonParam("pbButton"); + pb->setLabels("Push Me", "Push Me", "Push Me"); + + PushButtonParamDescriptor* pb2 = desc.definePushButtonParam("analyseButton"); + pb2->setLabels("Analyse", "Analyse", "Analyse"); + + DoubleParamDescriptor *param7 = desc.defineDoubleParam("analysisParam"); + param7->setLabels("Analysis Slave", "Analysis Slave", "Analysis Slave"); + + Double2DParamDescriptor* widgetPos = desc.defineDouble2DParam("widgetPos"); + widgetPos->setLabels("Widget Position", "Widget Position", "Widget Position"); + widgetPos->setDoubleType(OFX::eDoubleTypeXYAbsolute); + widgetPos->setDefaultCoordinateSystem(eCoordinatesNormalised); + widgetPos->setDimensionLabels("X Position", "Y Position"); + widgetPos->setDefault(0.5, 0.5); +} + +OFX::ImageEffect* GenericTestExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/) +{ + return new GenericTestPlugin(handle); +} + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static GenericTestExamplePluginFactory p("net.sf.openfx.GenericTestPlugin", 1, 0); + ids.push_back(&p); + } + } +} diff --git a/third_party/openfx/Support/Plugins/Tester/Tester.vcproj b/third_party/openfx/Support/Plugins/Tester/Tester.vcproj new file mode 100644 index 000000000..35220a0b9 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Tester/Tester.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/Transition/Info.plist b/third_party/openfx/Support/Plugins/Transition/Info.plist new file mode 100644 index 000000000..cfbee0c70 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Transition/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + crossFade.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/Plugins/Transition/crossFade.cpp b/third_party/openfx/Support/Plugins/Transition/crossFade.cpp new file mode 100644 index 000000000..ca007cbfa --- /dev/null +++ b/third_party/openfx/Support/Plugins/Transition/crossFade.cpp @@ -0,0 +1,260 @@ + + +#include +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" + +#include "../include/ofxsProcessing.H" +#include "../include/ofxsImageBlender.H" + +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class CrossFadePlugin : public OFX::ImageEffect { +protected : + // do not need to delete these, the ImageEffect is managing them for us + OFX::Clip *dstClip_; + OFX::Clip *fromClip_; + OFX::Clip *toClip_; + + OFX::DoubleParam *transition_; + +public : + /** @brief ctor */ + CrossFadePlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , dstClip_(0) + , fromClip_(0) + , toClip_(0) + , transition_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + fromClip_ = fetchClip(kOfxImageEffectTransitionSourceFromClipName); + toClip_ = fetchClip(kOfxImageEffectTransitionSourceToClipName); + transition_ = fetchDoubleParam("Transition"); + } + + /* Override the render */ + virtual void render(const OFX::RenderArguments &args); + + /* override is identity */ + virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime); + + /* set up and run a processor */ + void + setupAndProcess(OFX::ImageBlenderBase &, const OFX::RenderArguments &args); +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the filter */ + +//////////////////////////////////////////////////////////////////////////////// +// basic plugin render function, just a skelington to instantiate templates from + +// make sure components are sane +static void +checkComponents(const OFX::Image &src, + OFX::BitDepthEnum dstBitDepth, + OFX::PixelComponentEnum dstComponents) +{ + OFX::BitDepthEnum srcBitDepth = src.getPixelDepth(); + OFX::PixelComponentEnum srcComponents = src.getPixelComponents(); + + // see if they have the same depths and bytes and all + if(srcBitDepth != dstBitDepth || srcComponents != dstComponents) + throw int(1); // HACK!! need to throw an sensible exception here! +} + +/* set up and run a processor */ +void +CrossFadePlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::RenderArguments &args) +{ + // get a dst image + std::unique_ptr dst(dstClip_->fetchImage(args.time)); + OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dst->getPixelComponents(); + + // fetch the two source images + std::unique_ptr fromImg(fromClip_->fetchImage(args.time)); + std::unique_ptr toImg(toClip_->fetchImage(args.time)); + + // make sure bit depths are sane + if(fromImg.get()) checkComponents(*fromImg, dstBitDepth, dstComponents); + if(toImg.get()) checkComponents(*toImg, dstBitDepth, dstComponents); + + // get the transition value + float blend = (float)transition_->getValueAtTime(args.time); + + // set the images + processor.setDstImg(dst.get()); + processor.setFromImg(fromImg.get()); + processor.setToImg(toImg.get()); + + // set the render window + processor.setRenderWindow(args.renderWindow); + + // set the scales + processor.setBlend(blend); + + // Call the base class process member, this will call the derived templated process code + processor.process(); +} + +// the overridden render function +void +CrossFadePlugin::render(const OFX::RenderArguments &args) +{ + // instantiate the render code based on the pixel depth of the dst clip + OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth(); + OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents(); + + // do the rendering + if(dstComponents == OFX::ePixelComponentRGBA) { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } + else { + switch(dstBitDepth) { +case OFX::eBitDepthUByte : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthUShort : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; + +case OFX::eBitDepthFloat : { + OFX::ImageBlender fred(*this); + setupAndProcess(fred, args); + } + break; +default : + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + } + } // switch +} + +// overridden is identity +bool +CrossFadePlugin::isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime) +{ + // get the transition value + float blend = (float)transition_->getValueAtTime(args.time); + + identityTime = args.time; + + // at the start? + if(blend <= 0.0) { + identityClip = fromClip_; + identityTime = args.time; + return true; + } + + // at the end? + if(blend >= 1.0) { + identityClip = toClip_; + identityTime = args.time; + return true; + } + + // nope, identity we isnt + return false; +} + +mDeclarePluginFactory(CrossFadeExamplePluginFactory, {}, {}); +using namespace OFX; + +void CrossFadeExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + // basic labels + desc.setLabels("Cross Fade", "Cross Fade", "Cross Fade"); + desc.setPluginGrouping("OFX Example (Support)"); + + // Say we are a transition context + desc.addSupportedContext(eContextTransition); + desc.addSupportedContext(eContextGeneral); + + // Add supported pixel depths + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + + // set a few flags + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); + +} + +void CrossFadeExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum /*context*/) +{ + // we are a transition, so define the sourceFrom input clip + ClipDescriptor *fromClip = desc.defineClip(kOfxImageEffectTransitionSourceFromClipName); + fromClip->addSupportedComponent(ePixelComponentRGBA); + fromClip->addSupportedComponent(ePixelComponentAlpha); + fromClip->setTemporalClipAccess(false); + fromClip->setSupportsTiles(true); + + // we are a transition, so define the sourceTo input clip + ClipDescriptor *toClip = desc.defineClip(kOfxImageEffectTransitionSourceToClipName); + toClip->addSupportedComponent(ePixelComponentRGBA); + toClip->addSupportedComponent(ePixelComponentAlpha); + toClip->setTemporalClipAccess(false); + toClip->setSupportsTiles(true); + + // create the mandated output clip + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->addSupportedComponent(ePixelComponentAlpha); + dstClip->setSupportsTiles(true); + + // Define the mandated "Transition" param, note that we don't do anything with this other than. + // describe it. It is not a true param but how the host indicates to the plug-in how far through + // the transition it is. It appears on no plug-in side UI, it is purely the hosts to manage. + DoubleParamDescriptor *param = desc.defineDoubleParam("Transition"); + (void)param; +} + +ImageEffect* CrossFadeExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/) +{ + return new CrossFadePlugin(handle); +} + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static CrossFadeExamplePluginFactory p("net.sf.openfx.crossFade", 1, 0); + ids.push_back(&p); + } + } +} diff --git a/third_party/openfx/Support/Plugins/Transition/crossFade.dsp b/third_party/openfx/Support/Plugins/Transition/crossFade.dsp new file mode 100755 index 000000000..406c4bcef --- /dev/null +++ b/third_party/openfx/Support/Plugins/Transition/crossFade.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="crossFade" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=crossFade - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "crossFade.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "crossFade.mak" CFG="crossFade - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "crossFade - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "crossFade - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "crossFade - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/crossFade.ofx" + +!ELSEIF "$(CFG)" == "crossFade - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\CrossFade.ofx.bundle\Contents\Win32\crossFade.ofx" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "crossFade - Win32 Release" +# Name "crossFade - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\crossFade.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/third_party/openfx/Support/Plugins/Transition/crossFade.dsw b/third_party/openfx/Support/Plugins/Transition/crossFade.dsw new file mode 100755 index 000000000..5689f7aaa --- /dev/null +++ b/third_party/openfx/Support/Plugins/Transition/crossFade.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "crossFade"=.\crossFade.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name ofxsupport + End Project Dependency +}}} + +############################################################################### + +Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/Plugins/Transition/crossFade.vcproj b/third_party/openfx/Support/Plugins/Transition/crossFade.vcproj new file mode 100755 index 000000000..8d94e35a6 --- /dev/null +++ b/third_party/openfx/Support/Plugins/Transition/crossFade.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/Plugins/include/README b/third_party/openfx/Support/Plugins/include/README new file mode 100644 index 000000000..d4a1355b0 --- /dev/null +++ b/third_party/openfx/Support/Plugins/include/README @@ -0,0 +1,3 @@ +This directory contains header code that is used by the OFX Support library example plugins to perform basic processing functions. + +The code in this directory is not so much a skin on the base OFX classes, but code used in implementing specific image processing algorithms. As such it does not sit in the support include lib, but in its own include directory. \ No newline at end of file diff --git a/third_party/openfx/Support/Plugins/include/ofxsImageBlender.H b/third_party/openfx/Support/Plugins/include/ofxsImageBlender.H new file mode 100644 index 000000000..c5f349bc5 --- /dev/null +++ b/third_party/openfx/Support/Plugins/include/ofxsImageBlender.H @@ -0,0 +1,95 @@ + + +#ifndef _ofxsImageBlender_h_ +#define _ofxsImageBlender_h_ + +#include "ofxsProcessing.H" + +namespace OFX { + + /** @brief Base class used to blend two images together */ + class ImageBlenderBase : public OFX::ImageProcessor { + protected : + const OFX::Image *_fromImg; // be this at 0 + const OFX::Image *_toImg; // be this at 1 + float _blend; // how much to blend + + public : + /** @brief no arg ctor */ + ImageBlenderBase(OFX::ImageEffect &instance) + : OFX::ImageProcessor(instance) + , _fromImg(0) + , _toImg(0) + , _blend(0.5f) + { + } + + /** @brief set the src image */ + void setFromImg(const OFX::Image *v) {_fromImg = v;} + void setToImg(const OFX::Image *v) {_toImg = v;} + + /** @brief set the scale */ + void setBlend(float v) {_blend = v;} + }; + + /** @brief templated class to blend between two images */ + template + class ImageBlender : public ImageBlenderBase { + public : + // ctor + ImageBlender(OFX::ImageEffect &instance) + : ImageBlenderBase(instance) + {} + + static PIX Lerp(const PIX &v1, + const PIX &v2, + float blend) + { + return PIX((v2 - v1) * blend + v1); + } + + // and do some processing + void multiThreadProcessImages(OfxRectI procWindow) + { + float blend = _blend; + float blendComp = 1.0f - blend; + + for(int y = procWindow.y1; y < procWindow.y2; y++) { + if(_effect.abort()) break; + + PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); + + for(int x = procWindow.x1; x < procWindow.x2; x++) { + + PIX *fromPix = (PIX *) (_fromImg ? _fromImg->getPixelAddress(x, y) : 0); + PIX *toPix = (PIX *) (_toImg ? _toImg->getPixelAddress(x, y) : 0); + + if(fromPix && toPix) { + for(int c = 0; c < nComponents; c++) + dstPix[c] = Lerp(fromPix[c], toPix[c], blend); + } + else if(fromPix) { + for(int c = 0; c < nComponents; c++) + dstPix[c] = PIX(fromPix[c] * blendComp); + } + else if(toPix) { + for(int c = 0; c < nComponents; c++) + dstPix[c] = PIX(toPix[c] * blend); + } + else { + for(int c = 0; c < nComponents; c++) + dstPix[c] = PIX(0); + } + + dstPix += nComponents; + } + } + } + + }; + +}; + +#endif + + diff --git a/third_party/openfx/Support/Plugins/include/ofxsProcessing.H b/third_party/openfx/Support/Plugins/include/ofxsProcessing.H new file mode 100644 index 000000000..982475e8d --- /dev/null +++ b/third_party/openfx/Support/Plugins/include/ofxsProcessing.H @@ -0,0 +1,121 @@ + + +#ifndef _ofxsProcessing_h_ +#define _ofxsProcessing_h_ + +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +#include +#include + +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" + +/** @file This file contains a useful base class that can be used to process images + +The code below is not so much a skin on the base OFX classes, but code used in implementing +specific image processing algorithms. As such it does not sit in the support include lib, but in +its own include directory. +*/ + +namespace OFX { + + //////////////////////////////////////////////////////////////////////////////// + // base class to process images with + class ImageProcessor : public OFX::MultiThread::Processor { + protected : + OFX::ImageEffect &_effect; /**< @brief effect to render with */ + OFX::Image *_dstImg; /**< @brief image to process into */ + OfxRectI _renderWindow; /**< @brief render window to use */ + + public : + /** @brief ctor */ + ImageProcessor(OFX::ImageEffect &effect) + : _effect(effect) + , _dstImg(0) + { + _renderWindow.x1 = _renderWindow.y1 = _renderWindow.x2 = _renderWindow.y2 = 0; + } + + /** @brief set the destination image */ + void setDstImg(OFX::Image *v) {_dstImg = v; } + + /** @brief reset the render window */ + void setRenderWindow(OfxRectI rect) {_renderWindow = rect;} + + /** @brief overridden from OFX::MultiThread::Processor. This function is called once on each SMP thread by the base class */ + void multiThreadFunction(unsigned int threadId, unsigned int nThreads) + { + // slice the y range into the number of threads it has + unsigned int dy = _renderWindow.y2 - _renderWindow.y1; + // the following is equivalent to std::ceil(dy/(double)nThreads); + unsigned int h = (dy+nThreads-1)/nThreads; + if (h == 0) { + // there are more threads than lines to process + h = 1; + } + if (threadId * h >= dy) { + // empty render subwindow + return; + } + unsigned int y1 = _renderWindow.y1 + threadId * h; + + unsigned int step = (threadId + 1) * h; + unsigned int y2 = _renderWindow.y1 + (step < dy ? step : dy); + + OfxRectI win = _renderWindow; + win.y1 = y1; win.y2 = y2; + + // and render that thread on each + multiThreadProcessImages(win); + } + + /** @brief called before any MP is done */ + virtual void preProcess(void) {} + + /** @brief this is called by multiThreadFunction to actually process images, override in derived classes */ + virtual void multiThreadProcessImages(OfxRectI window) = 0; + + /** @brief called before any MP is done */ + virtual void postProcess(void) {} + + /** @brief called to process everything */ + virtual void process(void) + { + // If _dstImg was set, check that the _renderWindow is lying into dstBounds + if (_dstImg) { + const OfxRectI& dstBounds = _dstImg->getBounds(); + // is the renderWindow within dstBounds ? + assert(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 && + dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2); + // exit gracefully in case of error + if (!(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 && + dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2) || + (_renderWindow.x1 >= _renderWindow.x2) || + (_renderWindow.y1 >= _renderWindow.y2)) { + return; + } + } + + // call the pre MP pass + preProcess(); + + // make sure there are at least 4096 pixels per CPU and at least 1 line par CPU + unsigned int nCPUs = (std::min(_renderWindow.x2 - _renderWindow.x1, 4096) * + (_renderWindow.y2 - _renderWindow.y1)) / 4096; + // make sure the number of CPUs is valid (and use at least 1 CPU) + nCPUs = std::max(1u, std::min(nCPUs, OFX::MultiThread::getNumCPUs())); + + // call the base multi threading code, should put a pre & post thread calls in too + multiThread(nCPUs); + + // call the post MP pass + postProcess(); + } + + }; + + +}; +#endif diff --git a/third_party/openfx/Support/PropTester/CMakeLists.txt b/third_party/openfx/Support/PropTester/CMakeLists.txt new file mode 100644 index 000000000..bbe75a33c --- /dev/null +++ b/third_party/openfx/Support/PropTester/CMakeLists.txt @@ -0,0 +1,7 @@ +include(OpenFX) +file(GLOB_RECURSE PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") +set(TGT example-PropTester) +add_ofx_plugin(${TGT} .) +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}) diff --git a/third_party/openfx/Support/PropTester/Info.plist b/third_party/openfx/Support/PropTester/Info.plist new file mode 100644 index 000000000..cfbee0c70 --- /dev/null +++ b/third_party/openfx/Support/PropTester/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + crossFade.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/third_party/openfx/Support/PropTester/propTester.cpp b/third_party/openfx/Support/PropTester/propTester.cpp new file mode 100644 index 000000000..5ab1dd3a1 --- /dev/null +++ b/third_party/openfx/Support/PropTester/propTester.cpp @@ -0,0 +1,579 @@ + + +#ifdef _WINDOWS +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#include "ofxsImageEffect.h" + +class ColourInteract : public OFX::ParamInteract +{ +protected: + enum State + { + eDefault, + ePoised, + eDragging + }; + State _state; + double _radius; + +public: + ColourInteract(OfxInteractHandle handle, OFX::ImageEffect* effect, const std::string& paramName): + OFX::ParamInteract(handle, effect), _state(eDefault), _radius(5.0) + { + _param = effect->fetchRGBParam(paramName); + } + virtual bool draw(const OFX::DrawArgs &args) + { + OfxPointI size = getInteractSize(); + glBegin (GL_POLYGON); + + glColor3f (0.0f, 0.0f, 0.0f); + glVertex2f (-0.5f, -0.5f); + + glColor3f (1.0f, 0.0f, 0.0f); + glVertex2f (-0.5f, size.y-0.5f); + + glColor3f (0.0f, 1.0f, 0.0f); + glVertex2f (size.x - 0.5f, size.y - 0.5f); + + glColor3f (0.0f, 0.0f, 1.0f); + glVertex2f (size.x - 0.5f, -0.5f); + + glEnd(); + + double r,g,b,x,y; + _param->getValueAtTime(args.time, r, g, b); + positionFromColour(r, g, b, x, y); + glColor3f(1.0f, 1.0f, 1.0f); + if(_state==ePoised) + glColor3f(0.5f, 0.5f, 0.5f); + + glBegin(GL_POLYGON); + glVertex2d(x - _radius, y - _radius); + glVertex2d(x - _radius, y + _radius); + glVertex2d(x + _radius, y + _radius); + glVertex2d(x + _radius, y - _radius); + glEnd(); + + return true; + } + bool hitTest(double posx, double posy, double time) const + { + double r,g,b,x,y; + _param->getValueAtTime(time, r, g, b); + positionFromColour(r, g, b, x, y); + if(posx > x - _radius && + posy > y - _radius && + posx < x + _radius && + posy < y + _radius) + return true; + return false; + } + void positionFromColour(double r, double g, double b, double& x, double& y) const + { + x = (b/(g+b)) * 100.0 - 0.5; + y = (r/(g+r)) * 100.0 - 0.5; + } + void colourFromPosition(double x, double y, double& r, double& g, double& b) const + { + x += 0.5; + y += 0.5; + x = x*0.01; + y = y*0.01; + r = y * ( 1.0 - x); + b = x * ( 1.0 - y); + g = (1.0 - x) * (1.0 - y); + } + virtual bool penMotion(const OFX::PenArgs &args) + { + if(_state != eDragging) + { + if(hitTest(args.penPosition.x, args.penPosition.y, args.time)) + { + _state = ePoised; + requestRedraw(); + return true; + } + } + else + { + double r,g,b; + colourFromPosition(args.penPosition.x, args.penPosition.y, r, g, b); + _param->setValueAtTime(args.time, r, g, b); + requestRedraw(); + return true; + } + _state = eDefault; + requestRedraw(); + return false; + } + virtual bool penDown(const OFX::PenArgs &args) + { + if(hitTest(args.penPosition.x, args.penPosition.y, args.time)) + { + _state = eDragging; + return true; + } + return false; + } + virtual bool penUp(const OFX::PenArgs &/*args*/) + { + _state = ePoised; + requestRedraw(); + return true; + } + virtual ~ColourInteract(){} +protected: + OFX::RGBParam* _param; +}; + +//Need an instance count as a template parameter in order to generate a different mainEntry point for each instance. +// Hopefully this will be fixed in the next iteration of the OFX standard. +template +class ColourInteractDescriptor : public OFX::DefaultParamInteractDescriptor, ColourInteract> +{ +public: + using OFX::DefaultParamInteractDescriptor,ColourInteract>::setInteractSizeAspect; + using OFX::DefaultParamInteractDescriptor,ColourInteract>::setInteractMinimumSize; + using OFX::DefaultParamInteractDescriptor,ColourInteract>::setInteractPreferredSize; + virtual void describe() + { + setInteractSizeAspect(1.0); + setInteractMinimumSize(50, 50); + setInteractPreferredSize(100, 100); + } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief base class of the plugin */ +class BasePlugin : public OFX::ImageEffect { +protected : + // do not need to delete this, the ImageEffect is managing them for us + OFX::Clip *dstClip_; + +public : + /** @brief ctor */ + BasePlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , dstClip_(0) + { + dstClip_ = fetchClip(kOfxImageEffectOutputClipName); + } + +}; + +//////////////////////////////////////////////////////////////////////////////// +/** @brief generator effect version of the plugin */ +class GeneratorPlugin : public BasePlugin { +public : + /** @brief ctor */ + GeneratorPlugin(OfxImageEffectHandle handle) + : BasePlugin(handle) + {} + + /** @brief client render function, this is one of the few that must be set */ + virtual void render(const OFX::RenderArguments &args); +}; + +//////////////////////////////////////////////////////////////////////////////// +/** @brief filter version of the plugin */ +class FilterPlugin : public BasePlugin { +protected : + // do not need to delete this, the ImageEffect is managing them for us + OFX::Clip *srcClip_; + +public : + /** @brief ctor */ + FilterPlugin(OfxImageEffectHandle handle) + : BasePlugin(handle) + , srcClip_(0) + { + srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName); + } + + /** @brief client render function, this is one of the few that must be set */ + virtual void render(const OFX::RenderArguments &args); +}; + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief filter version of the plugin */ +class GeneralPlugin : public FilterPlugin { +protected : + // do not need to delete this, the ImageEffect is managing them for us + OFX::Clip *extraClip_; + +public : + /** @brief ctor */ + GeneralPlugin(OfxImageEffectHandle handle) + : FilterPlugin(handle) + , extraClip_(0) + { + extraClip_ = fetchClip("Extra"); + } +}; + +using namespace OFX; + +class PropTesterPluginFactory : public OFX::PluginFactoryHelper +{ +public: + PropTesterPluginFactory():OFX::PluginFactoryHelper("net.sf.openfx.propertyTester", 1, 0){} + virtual void describe(OFX::ImageEffectDescriptor &desc); + virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context); + virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context); +}; + +namespace OFX +{ + namespace Plugin + { + void getPluginIDs(OFX::PluginFactoryArray &ids) + { + static PropTesterPluginFactory p; + ids.push_back(&p); + } + } +} + +void PropTesterPluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + // basic labels + desc.setLabels("Prop Tester", "Prop Tester", "Property Tester"); + desc.setPluginGrouping("OFX Example (Support)"); + + // add the supported contexts, only filter at the moment + desc.addSupportedContext(eContextGenerator); + desc.addSupportedContext(eContextFilter); + desc.addSupportedContext(eContextGeneral); + + + // add supported pixel depths + desc.addSupportedBitDepth(eBitDepthUByte); + desc.addSupportedBitDepth(eBitDepthUShort); + desc.addSupportedBitDepth(eBitDepthFloat); + + // set a few flags + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(true); + desc.setSupportsTiles(true); + desc.setTemporalClipAccess(false); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(false); +} + +/** @brief describe a string param with the given name and type */ +static +void describeStringParam(OFX::ImageEffectDescriptor &desc, const std::string &name, StringTypeEnum strType, PageParamDescriptor *page) +{ + StringParamDescriptor *param = desc.defineStringParam(name); + param->setDefault(name); + param->setScriptName(name); + param->setHint("A string parameter"); + param->setLabels(name, name, name); + param->setStringType(strType); + page->addChild(*param); +} + +/** @brief describe a double param */ +static +void describeDoubleParam(OFX::ImageEffectDescriptor &desc, const std::string &name, DoubleTypeEnum doubleType, + double min, double max, PageParamDescriptor *page) +{ + DoubleParamDescriptor *param = desc.defineDoubleParam(name); + param->setLabels(name, name, name); + param->setScriptName(name); + param->setHint("A double parameter"); + param->setDefault(0); + param->setRange(min, max); + param->setDisplayRange(min, max); + param->setDoubleType(doubleType); + page->addChild(*param); +} + +/** @brief describe a double param */ +static +void describe2DDoubleParam(OFX::ImageEffectDescriptor &desc, const std::string &name, DoubleTypeEnum doubleType, + double min, double max, PageParamDescriptor *page) +{ + Double2DParamDescriptor *param = desc.defineDouble2DParam(name); + param->setLabels(name, name, name); + param->setScriptName(name); + param->setHint("A 2D double parameter"); + param->setDefault(0, 0); + param->setRange(min, min, max, max); + param->setDisplayRange(min, min, max, max); + param->setDoubleType(doubleType); + page->addChild(*param); +} + +/** @brief describe a double param */ +static +void describe3DDoubleParam(OFX::ImageEffectDescriptor &desc, const std::string &name, DoubleTypeEnum doubleType, + double min, double max, PageParamDescriptor *page) +{ + Double3DParamDescriptor *param = desc.defineDouble3DParam(name); + param->setLabels(name, name, name); + param->setScriptName(name); + param->setHint("A 3D double parameter"); + param->setDefault(0, 0, 0); + param->setRange(min, min, min, max, max, max); + param->setDisplayRange(min, min, min, max, max, max); + param->setDoubleType(doubleType); + page->addChild(*param); +} + +/** @brief The describe in context function, passed a plugin descriptor and a context */ +void PropTesterPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context) +{ + // Source clip only in the filter context + if(context == eContextGeneral) { + // create the mandated source clip + ClipDescriptor *srcClip = desc.defineClip("Extra"); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->setTemporalClipAccess(false); + srcClip->setOptional(false); + srcClip->setSupportsTiles(true); + srcClip->setIsMask(false); + } + + // Source clip only in the filter context + if(context == eContextFilter || context == eContextGeneral) { + // create the mandated source clip + ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->setTemporalClipAccess(false); + //srcClip->setOptional(false); + srcClip->setSupportsTiles(true); + srcClip->setIsMask(false); + } + + // create the mandated output clip + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->setTemporalClipAccess(false); + //dstClip->setOptional(false); + dstClip->setSupportsTiles(true); + dstClip->setIsMask(false); + + + // make some pages and to things in + PageParamDescriptor *page1 = desc.definePageParam("page1"); + PageParamDescriptor *page2 = desc.definePageParam("page2"); + PageParamDescriptor *page3 = desc.definePageParam("page3"); + + // make an int param + IntParamDescriptor *iParam = desc.defineIntParam("Int"); + iParam->setLabels("Int", "Int", "Int"); + iParam->setScriptName("int"); + iParam->setHint("An integer parameter"); + iParam->setDefault(0); + iParam->setRange(-100, 100); + iParam->setDisplayRange(-100, 100); + + page1->addChild(*iParam); + + // make a 2D int param + Int2DParamDescriptor *i2DParam = desc.defineInt2DParam("Int2D"); + i2DParam->setLabels("Int2D", "Int2D", "Int2D"); + i2DParam->setScriptName("int2D"); + i2DParam->setHint("A 2D integer parameter"); + i2DParam->setDefault(0, 0); + i2DParam->setRange(-100, -100, 100, 100); + i2DParam->setDisplayRange(-100, -100, 100, 100); + + page1->addChild(*i2DParam); + + // make a 3D int param + Int3DParamDescriptor *i3DParam = desc.defineInt3DParam("Int3D"); + i3DParam->setLabels("Int3D", "Int3D", "Int2D"); + i3DParam->setScriptName("int3D"); + i3DParam->setHint("A 3D integer parameter"); + i3DParam->setDefault(0, 0, 0); + i3DParam->setRange(-100, -100, -100, 100, 100, 100); + i3DParam->setDisplayRange(-100, -100, -100, 100, 100, 100); + + page1->addChild(*i3DParam); + + page1->addChild(PageParamDescriptor::gSkipColumn); + + // boolean + BooleanParamDescriptor *boolean = desc.defineBooleanParam("bool"); + boolean->setLabels("bool", "bool", "bool"); + boolean->setDefault(false); + + page1->addChild(*boolean); + + // choice + ChoiceParamDescriptor *choice = desc.defineChoiceParam("choice"); + choice->setLabels("choice", "choice", "choice"); + choice->appendOption("This", "This"); + choice->appendOption("That", "That"); + choice->appendOption("The Other", "The Other"); + choice->resetOptions(); + choice->appendOption("Tom", "Tom"); + choice->appendOption("Dick", "Dick"); + choice->appendOption("Harry", "Harry"); + choice->setDefault(0); + + page1->addChild(*choice); + + page1->addChild(PageParamDescriptor::gSkipColumn); + + // push button + PushButtonParamDescriptor *push = desc.definePushButtonParam("push"); + push->setLabels("push me", "push me", "push me Big Nose"); + page1->addChild(*push); + + // make a custom param + CustomParamDescriptor *custom = desc.defineCustomParam("custom"); + custom->setLabels("custom", "custom", "custom"); + custom->setDefault("wibble"); + + // rgba colours + RGBAParamDescriptor *rgba = desc.defineRGBAParam("rgba"); + rgba->setLabels("rgba", "rgba", "rgba"); + rgba->setDefault(0, 0, 0, 1); + + page1->addChild(*rgba); + + RGBParamDescriptor *rgba2 = desc.defineRGBParam("rgbaCustom"); + rgba2->setLabels("RGB Custom", "RGB Custom", "RGB Custom"); + rgba2->setDefault(0, 1, 1); + rgba2->setInteractDescriptor(new ColourInteractDescriptor<0>); + page1->addChild(*rgba2); + + RGBParamDescriptor *rgba3 = desc.defineRGBParam("rgbaCustom2"); + rgba3->setLabels("RGB Custom 2", "RGB Custom 2", "RGB Custom 2"); + rgba3->setDefault(1, 0, 1); + rgba3->setInteractDescriptor(new ColourInteractDescriptor<1>); + page1->addChild(*rgba3); + + page1->addChild(PageParamDescriptor::gSkipRow); + + // rgb colour + RGBParamDescriptor *rgb = desc.defineRGBParam("rgb"); + rgb->setLabels("rgb", "rgb", "rgb"); + rgb->setDefault(0, 0, 0); + page1->addChild(*rgb); + + // make a 1D double parameter of each type + describeDoubleParam(desc, "double", eDoubleTypePlain, -100, 100, page2); + describeDoubleParam(desc, "angle", eDoubleTypeAngle, -100, 100, page2); + describeDoubleParam(desc, "scale", eDoubleTypeScale, -1, 1, page2); + describeDoubleParam(desc, "time", eDoubleTypeTime, -100, 100, page2); + describeDoubleParam(desc, "absoluteTime", eDoubleTypeAbsoluteTime, 0, 1000, page2); + describeDoubleParam(desc, "X_Value", eDoubleTypeX, -1, 1, page2); + describeDoubleParam(desc, "Y_Value", eDoubleTypeY, -1, 1, page2); + describeDoubleParam(desc, "X_Position", eDoubleTypeXAbsolute, -1, 1, page2); + describeDoubleParam(desc, "Y_Position", eDoubleTypeYAbsolute, -1, 1, page2); + + page2->addChild(PageParamDescriptor::gSkipColumn); + + // make a 2D double parameter of each type + describe2DDoubleParam(desc, "double2D", eDoubleTypePlain, -100, 100, page2); + describe2DDoubleParam(desc, "angle2D", eDoubleTypeAngle, -100, 100, page2); + describe2DDoubleParam(desc, "scale2D", eDoubleTypeScale, -1, 1, page2); + describe2DDoubleParam(desc, "XY_Value", eDoubleTypeXY, -1, 1, page2); + describe2DDoubleParam(desc, "XY_Position", eDoubleTypeXYAbsolute, -1, 1, page2); + + page2->addChild(PageParamDescriptor::gSkipColumn); + + // make a 3D double parameter of each type + describe3DDoubleParam(desc, "double3D", eDoubleTypePlain, -100, 100, page2); + describe3DDoubleParam(desc, "angle3D", eDoubleTypeAngle, -100, 100, page2); + describe3DDoubleParam(desc, "scale3D", eDoubleTypeScale, -1, 1, page2); + + // make a string param param of each type + describeStringParam(desc, "singleLine", eStringTypeSingleLine, page3); + describeStringParam(desc, "multiLine", eStringTypeMultiLine, page3); + describeStringParam(desc, "filePath", eStringTypeFilePath, page3); + describeStringParam(desc, "dirPath", eStringTypeDirectoryPath, page3); + describeStringParam(desc, "label", eStringTypeLabel, page3); + +} + +/** @brief The create instance function, the plugin must return an object derived from the \ref OFX::ImageEffect class */ +ImageEffect* PropTesterPluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum context) +{ + if(context == eContextFilter) + return new FilterPlugin(handle); + else if(context == eContextGenerator) + return new GeneratorPlugin(handle); + else if(context == eContextGeneral) + return new GeneralPlugin(handle); + + + // HACK!!! Throw something here! + return NULL; // to shut the warning up +} + + + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the generator */ +void +GeneratorPlugin::render(const OFX::RenderArguments &args) +{ + OFX::Image *dst = 0; + + try { + // get a dst image + dst = dstClip_->fetchImage(args.time); + + // push some pixels + // blah; + // blah; + // blah; + } + + catch(...) { + delete dst; + throw; + } + + // delete them + delete dst; +} + +//////////////////////////////////////////////////////////////////////////////// +/** @brief render for the filter */ +void +FilterPlugin::render(const OFX::RenderArguments &args) +{ + OFX::Image *src = 0, *dst = 0; + + try { + // get a src image + src = srcClip_->fetchImage(args.time); + + // get a dst image + dst = dstClip_->fetchImage(args.time); + + // push some pixels + // blah; + // blah; + // blah; + } + + catch(...) { + delete src; + delete dst; + throw; + } + + // delete them + delete src; + delete dst; +} diff --git a/third_party/openfx/Support/PropTester/propTester.dsp b/third_party/openfx/Support/PropTester/propTester.dsp new file mode 100755 index 000000000..d314ab6c2 --- /dev/null +++ b/third_party/openfx/Support/PropTester/propTester.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="propTester" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=propTester - 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 "propTester.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 "propTester.mak" CFG="propTester - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "propTester - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "propTester - 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)" == "propTester - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.bundle.ofx/Contents/Win32/propTester.ofx" + +!ELSEIF "$(CFG)" == "propTester - 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 /GB /Zp8 /MDd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\PropTester.bundle.ofx\Contents\Win32\propTester.ofx" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "propTester - Win32 Release" +# Name "propTester - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\propTester.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 diff --git a/third_party/openfx/Support/PropTester/propTester.dsw b/third_party/openfx/Support/PropTester/propTester.dsw new file mode 100755 index 000000000..0b3e872e5 --- /dev/null +++ b/third_party/openfx/Support/PropTester/propTester.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "ofxsupport"=..\Library\ofxsupport.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "propTester"=.\propTester.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name ofxsupport + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/third_party/openfx/Support/PropTester/propTester.vcproj b/third_party/openfx/Support/PropTester/propTester.vcproj new file mode 100755 index 000000000..d753e68a2 --- /dev/null +++ b/third_party/openfx/Support/PropTester/propTester.vcproj @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/openfx/Support/README b/third_party/openfx/Support/README new file mode 100644 index 000000000..31c8a766b --- /dev/null +++ b/third_party/openfx/Support/README @@ -0,0 +1,73 @@ +OFX Support Library + + This directory tree contains the source to a C++ library that skins the OFX + C plugin API with a set of classes. It is meant to act as a guide to people implementing + plugins and hosts using the API and reveal the logical structure of the OFX API. + + +******************************************************************************** +Copyright and License + + The library is copyright OpenFX and contributors to the OpenFX project, and was + written by Bruno Nicoletti (bruno@thefoundry.co.uk). + + It was originally released under the GNU Lesser General Public License. + + It has subsequently been released under a 'BSD-3-Clause' license. See the + file 'LICENSE' for details. + +******************************************************************************** +Structure + - include - contains the headers for any client code. + - Library - contains the code that implements the support library. + - PropTester - contains code for a plugin that performs extensive property testing. + - Plugins - contains a set of example plugins using the support library. + +******************************************************************************** +Building + Plug-ins and library have OSX makefiles and windows MSDEV project files. They build and link and load happily on compliant hosts. + +******************************************************************************** +Problems And Debugging + + - unsupported properties on a host. If a hosts returns kOfxStatErrUnsupported when the plugin sets a property that is not absolutely essential (eg the hint property on a parameter), an exception is thrown at line 39 of Library/ofxsProperty.cpp. This in turn will cause the plug-in to return kOfxStatFailed. Comment out this line out if you encounter failure on a host and it may run. + + - if compiled in debug, the plugin writes a log file out, call "ofxTestLog.txt" in the current directory. This log will contain a variety of error messages. The most important of which concern property validation. The file Library/ofxsPropertyValidation.cpp contains code to validate each possible type of property handle used by OFX, making sure the host has the correct properties on each. If it finds a property not to exist, or to have the wrong default, it will print messages to the log file. + +******************************************************************************** +Release Notes + + +31-1-2005 + All accessor functions have had 'get' prepended to their name. + Added integrate and differentiate functions to 2D and 3D double parameters. + The generic memory allocator takes an option ImageEffect pointer, not a void * handle. + Refactored plugins to use new member names. + Added a root makefile to the plugins directory. + Added a 'clean' target to the plugin makefiles. + +13-01-2005 Version 0.2 + + Skinned everything except message suite and parameter interacts custom GUIS, + Skinned overlays, + Build enviromnments for OSX and MSDEV, + Example plug-ins written for each context, + Doxygen documentation (especially proud of my 15 line plugin writing guide), + Still to be done, + decent set of exceptions and exception specifiers on each function, + skin the parameter custom interact, + parameter integration and differentiation functions needed on 2D and 3D doubles and the colour classses, + parameters should return their values in a struct, as well as by a reference arg (some do already), + write examples showing custom param and param animation, + write an example showing use of external resource files, + more testing. + +15-12-2004 Version 0.1 + + Implemented most of the basic classes, need to do more work on clip instances and image effect instances. + Library builds fine on OSX 10.3, not fully tested yet. + No where near finsihed yet, + Need to finish off the actions. + Need to do a cleaner set of exception classes. + Need to test somewhat more (hey they do compile though!). + Need to build on more machines too (OSX 10.3 fine) and come up with make files for the appropriates diff --git a/third_party/openfx/Support/Support.xcodeproj/project.pbxproj b/third_party/openfx/Support/Support.xcodeproj/project.pbxproj new file mode 100644 index 000000000..2b9b6b9bb --- /dev/null +++ b/third_party/openfx/Support/Support.xcodeproj/project.pbxproj @@ -0,0 +1,1691 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXAggregateTarget section */ + 1E551F461799509100A4135C /* all */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 1E551F471799509100A4135C /* Build configuration list for PBXAggregateTarget "all" */; + buildPhases = ( + ); + dependencies = ( + 1E3E3D27179960AC005F2132 /* PBXTargetDependency */, + 1E3E3D29179960AC005F2132 /* PBXTargetDependency */, + 1E3E3D2B179960AC005F2132 /* PBXTargetDependency */, + 1E3E3D2D179960AC005F2132 /* PBXTargetDependency */, + 1E3E3D2F179960AC005F2132 /* PBXTargetDependency */, + 1E3E3D52179961ED005F2132 /* PBXTargetDependency */, + 1E3E3D6817996270005F2132 /* PBXTargetDependency */, + 1E3E3D8217996301005F2132 /* PBXTargetDependency */, + 1E3E3D98179963C5005F2132 /* PBXTargetDependency */, + 1E3E3DAC17996479005F2132 /* PBXTargetDependency */, + ); + name = all; + productName = all; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 1E08327B19A1E2C100A819A5 /* pluginLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E08327919A1E2C100A819A5 /* pluginLoader.cpp */; }; + 1E3E3CB317995CC9005F2132 /* basic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB217995CC9005F2132 /* basic.cpp */; }; + 1E3E3CBE17995D5C005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3CBF17995D5C005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3CC017995D5C005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3CC117995D5C005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3CC217995D5C005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3CC317995D5C005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3CC417995D5C005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3CC517995D5C005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3CC617995D8C005F2132 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E551F5A179950EC00A4135C /* OpenGL.framework */; }; + 1E3E3CCA17995DBB005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3CCB17995DBB005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3CCC17995DBB005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3CCD17995DBB005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3CCE17995DBB005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3CCF17995DBB005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3CD017995DBB005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3CD117995DBB005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3CDB17995DF6005F2132 /* field.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CDA17995DF6005F2132 /* field.cpp */; }; + 1E3E3CDE17995E76005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3CDF17995E76005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3CE017995E76005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3CE117995E76005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3CE217995E76005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3CE317995E76005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3CE417995E76005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3CE517995E76005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3CF117995F2C005F2132 /* noise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CEE17995F2C005F2132 /* noise.cpp */; }; + 1E3E3CF217995F2C005F2132 /* randomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CEF17995F2C005F2132 /* randomGenerator.cpp */; }; + 1E3E3CF517995F57005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3CF617995F57005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3CF717995F57005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3CF817995F57005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3CF917995F57005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3CFA17995F57005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3CFB17995F57005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3CFC17995F57005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D0717995F83005F2132 /* invert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D0617995F83005F2132 /* invert.cpp */; }; + 1E3E3D0A17995FB3005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3D0B17995FB3005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3D0C17995FB3005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3D0D17995FB3005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3D0E17995FB3005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3D0F17995FB3005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3D1017995FB3005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3D1117995FB3005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D2217996042005F2132 /* multibundle1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D1A17996029005F2132 /* multibundle1.cpp */; }; + 1E3E3D2317996042005F2132 /* multibundle2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D1C1799602A005F2132 /* multibundle2.cpp */; }; + 1E3E3D2417996042005F2132 /* PluginRegistration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D1E1799602A005F2132 /* PluginRegistration.cpp */; }; + 1E3E3D251799609D005F2132 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E551F5A179950EC00A4135C /* OpenGL.framework */; }; + 1E3E3D3B179961B4005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3D3C179961B4005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3D3D179961B4005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3D3E179961B4005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3D3F179961B4005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3D40179961B4005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3D41179961B4005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3D42179961B4005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D50179961E2005F2132 /* retimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D4E179961D6005F2132 /* retimer.cpp */; }; + 1E3E3D5517996232005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3D5617996232005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3D5717996232005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3D5817996232005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3D5917996232005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3D5A17996232005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3D5B17996232005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3D5C17996232005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D6617996262005F2132 /* Tester.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D6517996262005F2132 /* Tester.cpp */; }; + 1E3E3D691799629F005F2132 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E551F5A179950EC00A4135C /* OpenGL.framework */; }; + 1E3E3D6C179962A4005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3D6D179962A4005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3D6E179962A4005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3D6F179962A4005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3D70179962A4005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3D71179962A4005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3D72179962A4005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3D73179962A4005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D80179962DE005F2132 /* crossFade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D7F179962DE005F2132 /* crossFade.cpp */; }; + 1E3E3D8517996363005F2132 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1E3E3D8617996363005F2132 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1E3E3D8717996363005F2132 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1E3E3D8817996363005F2132 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1E3E3D8917996363005F2132 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1E3E3D8A17996363005F2132 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1E3E3D8B17996363005F2132 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1E3E3D8C17996363005F2132 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1E3E3D96179963B4005F2132 /* propTester.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3D95179963B4005F2132 /* propTester.cpp */; }; + 1E3E3D99179963E0005F2132 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E551F5A179950EC00A4135C /* OpenGL.framework */; }; + 1E3E3DAA1799646E005F2132 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E3E3DA91799646E005F2132 /* CoreFoundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1E3E3D26179960AC005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3CA317995BEE005F2132; + remoteInfo = basic.ofx; + }; + 1E3E3D28179960AC005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3CC717995DBB005F2132; + remoteInfo = field.ofx; + }; + 1E3E3D2A179960AC005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3CDC17995E76005F2132; + remoteInfo = noise.ofx; + }; + 1E3E3D2C179960AC005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3CF317995F57005F2132; + remoteInfo = invert.ofx; + }; + 1E3E3D2E179960AC005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D0817995FB3005F2132; + remoteInfo = multibundle.ofx; + }; + 1E3E3D51179961ED005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D39179961B4005F2132; + remoteInfo = retimer.ofx; + }; + 1E3E3D6717996270005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D5317996232005F2132; + remoteInfo = tester.ofx; + }; + 1E3E3D8117996301005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D6A179962A4005F2132; + remoteInfo = transition.ofx; + }; + 1E3E3D97179963C5005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D8317996363005F2132; + remoteInfo = PropTester.ofx; + }; + 1E3E3DAB17996479005F2132 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1E551EB917994D4000A4135C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1E3E3D9D1799644B005F2132; + remoteInfo = pluginLoader; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 1E3E3D9C1799644B005F2132 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1E009D5C17F44C72003071CC /* ofxsImageBlender.H */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ofxsImageBlender.H; sourceTree = ""; }; + 1E009D5D17F44C72003071CC /* ofxsProcessing.H */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ofxsProcessing.H; sourceTree = ""; }; + 1E009D5E17F44D5C003071CC /* ofxsHWNDInteract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxsHWNDInteract.h; sourceTree = ""; }; + 1E009D5F17F44D70003071CC /* ofxCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxCore.h; path = ../../include/ofxCore.h; sourceTree = ""; }; + 1E009D6017F44D70003071CC /* ofxImageEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxImageEffect.h; path = ../../include/ofxImageEffect.h; sourceTree = ""; }; + 1E009D6117F44D70003071CC /* ofxInteract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxInteract.h; path = ../../include/ofxInteract.h; sourceTree = ""; }; + 1E009D6217F44D70003071CC /* ofxKeySyms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxKeySyms.h; path = ../../include/ofxKeySyms.h; sourceTree = ""; }; + 1E009D6317F44D70003071CC /* ofxMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxMemory.h; path = ../../include/ofxMemory.h; sourceTree = ""; }; + 1E009D6417F44D70003071CC /* ofxMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxMessage.h; path = ../../include/ofxMessage.h; sourceTree = ""; }; + 1E009D6517F44D70003071CC /* ofxMultiThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxMultiThread.h; path = ../../include/ofxMultiThread.h; sourceTree = ""; }; + 1E009D6617F44D70003071CC /* ofxOpenGLRender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxOpenGLRender.h; path = ../../include/ofxOpenGLRender.h; sourceTree = ""; }; + 1E009D6717F44D70003071CC /* ofxParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxParam.h; path = ../../include/ofxParam.h; sourceTree = ""; }; + 1E009D6817F44D70003071CC /* ofxParametricParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxParametricParam.h; path = ../../include/ofxParametricParam.h; sourceTree = ""; }; + 1E009D6917F44D70003071CC /* ofxPixels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxPixels.h; path = ../../include/ofxPixels.h; sourceTree = ""; }; + 1E009D6A17F44D70003071CC /* ofxProgress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxProgress.h; path = ../../include/ofxProgress.h; sourceTree = ""; }; + 1E009D6B17F44D70003071CC /* ofxProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxProperty.h; path = ../../include/ofxProperty.h; sourceTree = ""; }; + 1E009D6C17F44D70003071CC /* ofxTimeLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxTimeLine.h; path = ../../include/ofxTimeLine.h; sourceTree = ""; }; + 1E08326B19A1E1B900A819A5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 1E08326C19A1E1B900A819A5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 1E08326D19A1E1B900A819A5 /* support.doxy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = support.doxy; sourceTree = ""; }; + 1E08326E19A1E1B900A819A5 /* TODO */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO; sourceTree = ""; }; + 1E08326F19A1E23C00A819A5 /* linuxSymbols */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = linuxSymbols; path = include/linuxSymbols; sourceTree = ""; }; + 1E08327019A1E23C00A819A5 /* osxDeploy.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = osxDeploy.sh; path = include/osxDeploy.sh; sourceTree = ""; }; + 1E08327119A1E23C00A819A5 /* osxSymbols */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = osxSymbols; path = include/osxSymbols; sourceTree = ""; }; + 1E08327219A1E23C00A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08327319A1E23C00A819A5 /* ofxSupport.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ofxSupport.dsp; path = Library/ofxSupport.dsp; sourceTree = ""; }; + 1E08327419A1E23C00A819A5 /* ofxsupport.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ofxsupport.dsw; path = Library/ofxsupport.dsw; sourceTree = ""; }; + 1E08327519A1E23C00A819A5 /* ofxsupport.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = ofxsupport.vcproj; path = Library/ofxsupport.vcproj; sourceTree = ""; }; + 1E08327619A1E25600A819A5 /* ofxsHWNDInteract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsHWNDInteract.cpp; sourceTree = ""; }; + 1E08327819A1E2C100A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08327919A1E2C100A819A5 /* pluginLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluginLoader.cpp; sourceTree = ""; }; + 1E08327D19A1E30D00A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08327E19A1E30D00A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08327F19A1E30D00A819A5 /* propTester.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = propTester.dsp; sourceTree = ""; }; + 1E08328019A1E30D00A819A5 /* propTester.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = propTester.dsw; sourceTree = ""; }; + 1E08328119A1E30D00A819A5 /* propTester.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = propTester.vcproj; sourceTree = ""; }; + 1E08328219A1E32500A819A5 /* ExamplePlugs.sln */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ExamplePlugs.sln; sourceTree = ""; }; + 1E08328419A1E34E00A819A5 /* basic.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = basic.dsp; sourceTree = ""; }; + 1E08328519A1E34E00A819A5 /* basic.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = basic.dsw; sourceTree = ""; }; + 1E08328619A1E34E00A819A5 /* basic.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = basic.vcproj; sourceTree = ""; }; + 1E08328719A1E34E00A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08328819A1E34E00A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08328919A1E36800A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08328A19A1E36800A819A5 /* Makefile.master */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.master; sourceTree = ""; }; + 1E08328C19A1E39600A819A5 /* field.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = field.vcproj; sourceTree = ""; }; + 1E08328D19A1E39600A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08328E19A1E39600A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08329019A1E3C300A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08329119A1E3C300A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08329219A1E3C300A819A5 /* noise.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = noise.dsp; sourceTree = ""; }; + 1E08329319A1E3C400A819A5 /* noise.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = noise.dsw; sourceTree = ""; }; + 1E08329419A1E3C400A819A5 /* noise.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = noise.vcproj; sourceTree = ""; }; + 1E08329919A1E43500A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08329A19A1E43500A819A5 /* invert.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = invert.vcproj; sourceTree = ""; }; + 1E08329B19A1E43500A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08329C19A1E46C00A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E08329D19A1E46C00A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E08329E19A1E46C00A819A5 /* multibundle.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = multibundle.vcproj; sourceTree = ""; }; + 1E08329F19A1E48500A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E0832A019A1E48500A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E0832A119A1E48500A819A5 /* Tester.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Tester.vcproj; sourceTree = ""; }; + 1E0832A219A1E4A600A819A5 /* crossFade.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = crossFade.dsp; sourceTree = ""; }; + 1E0832A319A1E4A600A819A5 /* crossFade.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = crossFade.dsw; sourceTree = ""; }; + 1E0832A419A1E4A600A819A5 /* crossFade.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = crossFade.vcproj; sourceTree = ""; }; + 1E0832A519A1E4A600A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1E0832A619A1E4A600A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1E0832A819A1E4D900A819A5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Retimer/Info.plist; sourceTree = ""; }; + 1E0832A919A1E4D900A819A5 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Retimer/Makefile; sourceTree = ""; }; + 1E0832AA19A1E4D900A819A5 /* retimer.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = retimer.dsp; path = Retimer/retimer.dsp; sourceTree = ""; }; + 1E0832AB19A1E4D900A819A5 /* retimer.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = retimer.dsw; path = Retimer/retimer.dsw; sourceTree = ""; }; + 1E0832AC19A1E4D900A819A5 /* retimer.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = retimer.vcproj; path = Retimer/retimer.vcproj; sourceTree = ""; }; + 1E0832AE19A1E50100A819A5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 1E378A86194DCF4200800F5F /* ofxReadWrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxReadWrite.h; sourceTree = ""; }; + 1E3E3CA417995BEE005F2132 /* basic.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = basic.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3CB217995CC9005F2132 /* basic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = basic.cpp; sourceTree = ""; }; + 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsCore.cpp; sourceTree = ""; }; + 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsImageEffect.cpp; sourceTree = ""; }; + 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsInteract.cpp; sourceTree = ""; }; + 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsLog.cpp; sourceTree = ""; }; + 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsMultiThread.cpp; sourceTree = ""; }; + 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsParams.cpp; sourceTree = ""; }; + 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsProperty.cpp; sourceTree = ""; }; + 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxsPropertyValidation.cpp; sourceTree = ""; }; + 1E3E3CBD17995D5C005F2132 /* ofxsSupportPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxsSupportPrivate.h; sourceTree = ""; }; + 1E3E3CD817995DBB005F2132 /* field.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = field.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3CDA17995DF6005F2132 /* field.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field.cpp; sourceTree = ""; }; + 1E3E3CEC17995E76005F2132 /* noise.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = noise.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3CEE17995F2C005F2132 /* noise.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = noise.cpp; sourceTree = ""; }; + 1E3E3CEF17995F2C005F2132 /* randomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = randomGenerator.cpp; sourceTree = ""; }; + 1E3E3CF017995F2C005F2132 /* randomGenerator.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = randomGenerator.H; sourceTree = ""; }; + 1E3E3D0417995F57005F2132 /* invert.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = invert.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D0617995F83005F2132 /* invert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = invert.cpp; sourceTree = ""; }; + 1E3E3D1817995FB3005F2132 /* multibundle.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = multibundle.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D1A17996029005F2132 /* multibundle1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multibundle1.cpp; sourceTree = ""; }; + 1E3E3D1B17996029005F2132 /* multibundle1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multibundle1.h; sourceTree = ""; }; + 1E3E3D1C1799602A005F2132 /* multibundle2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multibundle2.cpp; sourceTree = ""; }; + 1E3E3D1D1799602A005F2132 /* multibundle2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multibundle2.h; sourceTree = ""; }; + 1E3E3D1E1799602A005F2132 /* PluginRegistration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginRegistration.cpp; sourceTree = ""; }; + 1E3E3D3117996112005F2132 /* ofxsCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsCore.h; sourceTree = ""; }; + 1E3E3D3217996112005F2132 /* ofxsImageEffect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsImageEffect.h; sourceTree = ""; }; + 1E3E3D3317996112005F2132 /* ofxsInteract.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsInteract.h; sourceTree = ""; }; + 1E3E3D3417996112005F2132 /* ofxsLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsLog.h; sourceTree = ""; }; + 1E3E3D3517996112005F2132 /* ofxsMemory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsMemory.h; sourceTree = ""; }; + 1E3E3D3617996112005F2132 /* ofxsMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsMessage.h; sourceTree = ""; }; + 1E3E3D3717996112005F2132 /* ofxsMultiThread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsMultiThread.h; sourceTree = ""; }; + 1E3E3D3817996112005F2132 /* ofxsParam.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ofxsParam.h; sourceTree = ""; }; + 1E3E3D4C179961B4005F2132 /* retimer.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = retimer.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D4E179961D6005F2132 /* retimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = retimer.cpp; path = Retimer/retimer.cpp; sourceTree = ""; }; + 1E3E3D6317996232005F2132 /* tester.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = tester.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D6517996262005F2132 /* Tester.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tester.cpp; sourceTree = ""; }; + 1E3E3D7B179962A4005F2132 /* transition.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = transition.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D7F179962DE005F2132 /* crossFade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = crossFade.cpp; sourceTree = ""; }; + 1E3E3D9317996363005F2132 /* PropTester.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PropTester.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3D95179963B4005F2132 /* propTester.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propTester.cpp; sourceTree = ""; }; + 1E3E3D9E1799644B005F2132 /* pluginLoader */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pluginLoader; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3E3DA91799646E005F2132 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; + 1E551F5A179950EC00A4135C /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 1E985639194F2BC300D20D5D /* ofxNatron.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofxNatron.h; path = ../../include/ofxNatron.h; sourceTree = ""; }; + 1E9FC1CE180BF74400EFE0F9 /* camera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = camera.h; sourceTree = ""; }; + 1E9FC1CF180BF74400EFE0F9 /* fnPublicOfxExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fnPublicOfxExtensions.h; sourceTree = ""; }; + 1EA6849218C51E42006EE43D /* fnOfxExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fnOfxExtensions.h; sourceTree = ""; }; + 1ECA10E818C7492E00D6E38C /* ofxDialog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ofxDialog.h; path = ../../include/ofxDialog.h; sourceTree = ""; }; + 1ECA10E918C7492E00D6E38C /* ofxSonyVegas.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ofxSonyVegas.h; path = ../../include/ofxSonyVegas.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1E3E3CA117995BEE005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3CC617995D8C005F2132 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CD217995DBB005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CE717995E76005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CFF17995F57005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D1317995FB3005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D251799609D005F2132 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D46179961B4005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D5E17996232005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D691799629F005F2132 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D75179962A4005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D8E17996363005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D99179963E0005F2132 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D9B1799644B005F2132 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3DAA1799646E005F2132 /* CoreFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1E08326A19A1E19F00A819A5 /* Other */ = { + isa = PBXGroup; + children = ( + 1E08326F19A1E23C00A819A5 /* linuxSymbols */, + 1E08327019A1E23C00A819A5 /* osxDeploy.sh */, + 1E08327119A1E23C00A819A5 /* osxSymbols */, + 1E08327319A1E23C00A819A5 /* ofxSupport.dsp */, + 1E08327419A1E23C00A819A5 /* ofxsupport.dsw */, + 1E08327519A1E23C00A819A5 /* ofxsupport.vcproj */, + 1E08326B19A1E1B900A819A5 /* LICENSE */, + 1E08326C19A1E1B900A819A5 /* README */, + 1E08326D19A1E1B900A819A5 /* support.doxy */, + 1E08326E19A1E1B900A819A5 /* TODO */, + ); + name = Other; + sourceTree = ""; + }; + 1E08327719A1E26300A819A5 /* OSXStaticLoader */ = { + isa = PBXGroup; + children = ( + 1E08327819A1E2C100A819A5 /* Makefile */, + 1E08327919A1E2C100A819A5 /* pluginLoader.cpp */, + ); + path = OSXStaticLoader; + sourceTree = ""; + }; + 1E08327C19A1E2DC00A819A5 /* PropTester */ = { + isa = PBXGroup; + children = ( + 1E3E3D95179963B4005F2132 /* propTester.cpp */, + 1E08327D19A1E30D00A819A5 /* Info.plist */, + 1E08327E19A1E30D00A819A5 /* Makefile */, + 1E08327F19A1E30D00A819A5 /* propTester.dsp */, + 1E08328019A1E30D00A819A5 /* propTester.dsw */, + 1E08328119A1E30D00A819A5 /* propTester.vcproj */, + ); + path = PropTester; + sourceTree = ""; + }; + 1E08328319A1E33700A819A5 /* Basic */ = { + isa = PBXGroup; + children = ( + 1E3E3CB217995CC9005F2132 /* basic.cpp */, + 1E08328419A1E34E00A819A5 /* basic.dsp */, + 1E08328519A1E34E00A819A5 /* basic.dsw */, + 1E08328619A1E34E00A819A5 /* basic.vcproj */, + 1E08328719A1E34E00A819A5 /* Info.plist */, + 1E08328819A1E34E00A819A5 /* Makefile */, + ); + path = Basic; + sourceTree = ""; + }; + 1E08328B19A1E37B00A819A5 /* Field */ = { + isa = PBXGroup; + children = ( + 1E3E3CDA17995DF6005F2132 /* field.cpp */, + 1E08328C19A1E39600A819A5 /* field.vcproj */, + 1E08328D19A1E39600A819A5 /* Info.plist */, + 1E08328E19A1E39600A819A5 /* Makefile */, + ); + path = Field; + sourceTree = ""; + }; + 1E08328F19A1E3A200A819A5 /* Generator */ = { + isa = PBXGroup; + children = ( + 1E3E3CEE17995F2C005F2132 /* noise.cpp */, + 1E3E3CEF17995F2C005F2132 /* randomGenerator.cpp */, + 1E3E3CF017995F2C005F2132 /* randomGenerator.H */, + 1E08329019A1E3C300A819A5 /* Info.plist */, + 1E08329119A1E3C300A819A5 /* Makefile */, + 1E08329219A1E3C300A819A5 /* noise.dsp */, + 1E08329319A1E3C400A819A5 /* noise.dsw */, + 1E08329419A1E3C400A819A5 /* noise.vcproj */, + ); + path = Generator; + sourceTree = ""; + }; + 1E08329519A1E3E400A819A5 /* Invert */ = { + isa = PBXGroup; + children = ( + 1E3E3D0617995F83005F2132 /* invert.cpp */, + 1E08329919A1E43500A819A5 /* Info.plist */, + 1E08329A19A1E43500A819A5 /* invert.vcproj */, + 1E08329B19A1E43500A819A5 /* Makefile */, + ); + path = Invert; + sourceTree = ""; + }; + 1E08329619A1E3EA00A819A5 /* MultiBundle */ = { + isa = PBXGroup; + children = ( + 1E3E3D1A17996029005F2132 /* multibundle1.cpp */, + 1E3E3D1B17996029005F2132 /* multibundle1.h */, + 1E3E3D1C1799602A005F2132 /* multibundle2.cpp */, + 1E3E3D1D1799602A005F2132 /* multibundle2.h */, + 1E3E3D1E1799602A005F2132 /* PluginRegistration.cpp */, + 1E08329C19A1E46C00A819A5 /* Info.plist */, + 1E08329D19A1E46C00A819A5 /* Makefile */, + 1E08329E19A1E46C00A819A5 /* multibundle.vcproj */, + ); + path = MultiBundle; + sourceTree = ""; + }; + 1E08329719A1E3F700A819A5 /* Tester */ = { + isa = PBXGroup; + children = ( + 1E3E3D6517996262005F2132 /* Tester.cpp */, + 1E08329F19A1E48500A819A5 /* Info.plist */, + 1E0832A019A1E48500A819A5 /* Makefile */, + 1E0832A119A1E48500A819A5 /* Tester.vcproj */, + ); + path = Tester; + sourceTree = ""; + }; + 1E08329819A1E3FF00A819A5 /* Transition */ = { + isa = PBXGroup; + children = ( + 1E3E3D7F179962DE005F2132 /* crossFade.cpp */, + 1E0832A219A1E4A600A819A5 /* crossFade.dsp */, + 1E0832A319A1E4A600A819A5 /* crossFade.dsw */, + 1E0832A419A1E4A600A819A5 /* crossFade.vcproj */, + 1E0832A519A1E4A600A819A5 /* Info.plist */, + 1E0832A619A1E4A600A819A5 /* Makefile */, + ); + path = Transition; + sourceTree = ""; + }; + 1E0832A719A1E4B200A819A5 /* Retimer */ = { + isa = PBXGroup; + children = ( + 1E0832A819A1E4D900A819A5 /* Info.plist */, + 1E0832A919A1E4D900A819A5 /* Makefile */, + 1E0832AA19A1E4D900A819A5 /* retimer.dsp */, + 1E0832AB19A1E4D900A819A5 /* retimer.dsw */, + 1E0832AC19A1E4D900A819A5 /* retimer.vcproj */, + 1E3E3D4E179961D6005F2132 /* retimer.cpp */, + ); + name = Retimer; + sourceTree = ""; + }; + 1E0832AD19A1E4E700A819A5 /* Plugins */ = { + isa = PBXGroup; + children = ( + 1E009D5C17F44C72003071CC /* ofxsImageBlender.H */, + 1E009D5D17F44C72003071CC /* ofxsProcessing.H */, + 1E0832AE19A1E50100A819A5 /* README */, + ); + name = Plugins; + path = ../Plugins/include; + sourceTree = ""; + }; + 1E0832AF19A1E51900A819A5 /* Support */ = { + isa = PBXGroup; + children = ( + 1E3E3D3117996112005F2132 /* ofxsCore.h */, + 1E009D5E17F44D5C003071CC /* ofxsHWNDInteract.h */, + 1E3E3D3217996112005F2132 /* ofxsImageEffect.h */, + 1E3E3D3317996112005F2132 /* ofxsInteract.h */, + 1E3E3D3417996112005F2132 /* ofxsLog.h */, + 1E3E3D3517996112005F2132 /* ofxsMemory.h */, + 1E3E3D3617996112005F2132 /* ofxsMessage.h */, + 1E3E3D3717996112005F2132 /* ofxsMultiThread.h */, + 1E3E3D3817996112005F2132 /* ofxsParam.h */, + ); + name = Support; + sourceTree = ""; + }; + 1E378A81194DCEF500800F5F /* tuttle */ = { + isa = PBXGroup; + children = ( + 1E378A86194DCF4200800F5F /* ofxReadWrite.h */, + ); + name = tuttle; + path = ../../include/tuttle; + sourceTree = ""; + }; + 1E3E3CB117995CB1005F2132 /* Plugins */ = { + isa = PBXGroup; + children = ( + 1E08328919A1E36800A819A5 /* Makefile */, + 1E08328A19A1E36800A819A5 /* Makefile.master */, + 1E08328219A1E32500A819A5 /* ExamplePlugs.sln */, + 1E08328319A1E33700A819A5 /* Basic */, + 1E08328B19A1E37B00A819A5 /* Field */, + 1E08328F19A1E3A200A819A5 /* Generator */, + 1E08329519A1E3E400A819A5 /* Invert */, + 1E08329619A1E3EA00A819A5 /* MultiBundle */, + 1E0832A719A1E4B200A819A5 /* Retimer */, + 1E08329719A1E3F700A819A5 /* Tester */, + 1E08329819A1E3FF00A819A5 /* Transition */, + ); + path = Plugins; + sourceTree = ""; + }; + 1E3E3CB417995D15005F2132 /* Library */ = { + isa = PBXGroup; + children = ( + 1E08327219A1E23C00A819A5 /* Makefile */, + 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */, + 1E08327619A1E25600A819A5 /* ofxsHWNDInteract.cpp */, + 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */, + 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */, + 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */, + 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */, + 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */, + 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */, + 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */, + 1E3E3CBD17995D5C005F2132 /* ofxsSupportPrivate.h */, + ); + path = Library; + sourceTree = ""; + }; + 1E3E3D30179960F9005F2132 /* Headers */ = { + isa = PBXGroup; + children = ( + 1E0832AF19A1E51900A819A5 /* Support */, + 1E0832AD19A1E4E700A819A5 /* Plugins */, + 1E378A81194DCEF500800F5F /* tuttle */, + 1E9FC1CC180BF70A00EFE0F9 /* nuke */, + 1E009D5F17F44D70003071CC /* ofxCore.h */, + 1ECA10E818C7492E00D6E38C /* ofxDialog.h */, + 1E009D6017F44D70003071CC /* ofxImageEffect.h */, + 1E009D6117F44D70003071CC /* ofxInteract.h */, + 1E009D6217F44D70003071CC /* ofxKeySyms.h */, + 1E009D6317F44D70003071CC /* ofxMemory.h */, + 1E009D6417F44D70003071CC /* ofxMessage.h */, + 1E009D6517F44D70003071CC /* ofxMultiThread.h */, + 1E985639194F2BC300D20D5D /* ofxNatron.h */, + 1E009D6617F44D70003071CC /* ofxOpenGLRender.h */, + 1E009D6717F44D70003071CC /* ofxParam.h */, + 1E009D6817F44D70003071CC /* ofxParametricParam.h */, + 1E009D6917F44D70003071CC /* ofxPixels.h */, + 1E009D6A17F44D70003071CC /* ofxProgress.h */, + 1E009D6B17F44D70003071CC /* ofxProperty.h */, + 1ECA10E918C7492E00D6E38C /* ofxSonyVegas.h */, + 1E009D6C17F44D70003071CC /* ofxTimeLine.h */, + ); + name = Headers; + path = include; + sourceTree = ""; + }; + 1E551EB817994D4000A4135C = { + isa = PBXGroup; + children = ( + 1E3E3DA91799646E005F2132 /* CoreFoundation.framework */, + 1E3E3D30179960F9005F2132 /* Headers */, + 1E551ED217994DEF00A4135C /* Sources */, + 1E08326A19A1E19F00A819A5 /* Other */, + 1E551EDA17994E8100A4135C /* Frameworks */, + 1E551EC217994D4000A4135C /* Products */, + ); + sourceTree = ""; + }; + 1E551EC217994D4000A4135C /* Products */ = { + isa = PBXGroup; + children = ( + 1E3E3CA417995BEE005F2132 /* basic.ofx.bundle */, + 1E3E3CD817995DBB005F2132 /* field.ofx.bundle */, + 1E3E3CEC17995E76005F2132 /* noise.ofx.bundle */, + 1E3E3D0417995F57005F2132 /* invert.ofx.bundle */, + 1E3E3D1817995FB3005F2132 /* multibundle.ofx.bundle */, + 1E3E3D4C179961B4005F2132 /* retimer.ofx.bundle */, + 1E3E3D6317996232005F2132 /* tester.ofx.bundle */, + 1E3E3D7B179962A4005F2132 /* transition.ofx.bundle */, + 1E3E3D9317996363005F2132 /* PropTester.ofx.bundle */, + 1E3E3D9E1799644B005F2132 /* pluginLoader */, + ); + name = Products; + sourceTree = ""; + }; + 1E551ED217994DEF00A4135C /* Sources */ = { + isa = PBXGroup; + children = ( + 1E08327C19A1E2DC00A819A5 /* PropTester */, + 1E08327719A1E26300A819A5 /* OSXStaticLoader */, + 1E3E3CB417995D15005F2132 /* Library */, + 1E3E3CB117995CB1005F2132 /* Plugins */, + ); + name = Sources; + sourceTree = ""; + }; + 1E551EDA17994E8100A4135C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1E551F5A179950EC00A4135C /* OpenGL.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 1E9FC1CC180BF70A00EFE0F9 /* nuke */ = { + isa = PBXGroup; + children = ( + 1E9FC1CE180BF74400EFE0F9 /* camera.h */, + 1EA6849218C51E42006EE43D /* fnOfxExtensions.h */, + 1E9FC1CF180BF74400EFE0F9 /* fnPublicOfxExtensions.h */, + ); + name = nuke; + path = ../../include/nuke; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1E3E3CA317995BEE005F2132 /* basic.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3CAE17995BEE005F2132 /* Build configuration list for PBXNativeTarget "basic.ofx" */; + buildPhases = ( + 1E3E3CA017995BEE005F2132 /* Sources */, + 1E3E3CA117995BEE005F2132 /* Frameworks */, + 1E3E3CA217995BEE005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = basic.ofx; + productName = basic.ofx; + productReference = 1E3E3CA417995BEE005F2132 /* basic.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3CC717995DBB005F2132 /* field.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3CD517995DBB005F2132 /* Build configuration list for PBXNativeTarget "field.ofx" */; + buildPhases = ( + 1E3E3CC817995DBB005F2132 /* Sources */, + 1E3E3CD217995DBB005F2132 /* Frameworks */, + 1E3E3CD417995DBB005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = field.ofx; + productName = basic.ofx; + productReference = 1E3E3CD817995DBB005F2132 /* field.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3CDC17995E76005F2132 /* noise.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3CE917995E76005F2132 /* Build configuration list for PBXNativeTarget "noise.ofx" */; + buildPhases = ( + 1E3E3CDD17995E76005F2132 /* Sources */, + 1E3E3CE717995E76005F2132 /* Frameworks */, + 1E3E3CE817995E76005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = noise.ofx; + productName = basic.ofx; + productReference = 1E3E3CEC17995E76005F2132 /* noise.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3CF317995F57005F2132 /* invert.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D0117995F57005F2132 /* Build configuration list for PBXNativeTarget "invert.ofx" */; + buildPhases = ( + 1E3E3CF417995F57005F2132 /* Sources */, + 1E3E3CFF17995F57005F2132 /* Frameworks */, + 1E3E3D0017995F57005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = invert.ofx; + productName = basic.ofx; + productReference = 1E3E3D0417995F57005F2132 /* invert.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D0817995FB3005F2132 /* multibundle.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D1517995FB3005F2132 /* Build configuration list for PBXNativeTarget "multibundle.ofx" */; + buildPhases = ( + 1E3E3D0917995FB3005F2132 /* Sources */, + 1E3E3D1317995FB3005F2132 /* Frameworks */, + 1E3E3D1417995FB3005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = multibundle.ofx; + productName = basic.ofx; + productReference = 1E3E3D1817995FB3005F2132 /* multibundle.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D39179961B4005F2132 /* retimer.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D49179961B4005F2132 /* Build configuration list for PBXNativeTarget "retimer.ofx" */; + buildPhases = ( + 1E3E3D3A179961B4005F2132 /* Sources */, + 1E3E3D46179961B4005F2132 /* Frameworks */, + 1E3E3D48179961B4005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = retimer.ofx; + productName = basic.ofx; + productReference = 1E3E3D4C179961B4005F2132 /* retimer.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D5317996232005F2132 /* tester.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D6017996232005F2132 /* Build configuration list for PBXNativeTarget "tester.ofx" */; + buildPhases = ( + 1E3E3D5417996232005F2132 /* Sources */, + 1E3E3D5E17996232005F2132 /* Frameworks */, + 1E3E3D5F17996232005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = tester.ofx; + productName = basic.ofx; + productReference = 1E3E3D6317996232005F2132 /* tester.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D6A179962A4005F2132 /* transition.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D78179962A4005F2132 /* Build configuration list for PBXNativeTarget "transition.ofx" */; + buildPhases = ( + 1E3E3D6B179962A4005F2132 /* Sources */, + 1E3E3D75179962A4005F2132 /* Frameworks */, + 1E3E3D77179962A4005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = transition.ofx; + productName = basic.ofx; + productReference = 1E3E3D7B179962A4005F2132 /* transition.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D8317996363005F2132 /* PropTester.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3D9017996363005F2132 /* Build configuration list for PBXNativeTarget "PropTester.ofx" */; + buildPhases = ( + 1E3E3D8417996363005F2132 /* Sources */, + 1E3E3D8E17996363005F2132 /* Frameworks */, + 1E3E3D8F17996363005F2132 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PropTester.ofx; + productName = basic.ofx; + productReference = 1E3E3D9317996363005F2132 /* PropTester.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 1E3E3D9D1799644B005F2132 /* pluginLoader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1E3E3DA41799644B005F2132 /* Build configuration list for PBXNativeTarget "pluginLoader" */; + buildPhases = ( + 1E3E3D9A1799644B005F2132 /* Sources */, + 1E3E3D9B1799644B005F2132 /* Frameworks */, + 1E3E3D9C1799644B005F2132 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = pluginLoader; + productName = pluginLoader; + productReference = 1E3E3D9E1799644B005F2132 /* pluginLoader */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1E551EB917994D4000A4135C /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + ORGANIZATIONNAME = OpenFX; + }; + buildConfigurationList = 1E551EBC17994D4000A4135C /* Build configuration list for PBXProject "Support" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 1E551EB817994D4000A4135C; + productRefGroup = 1E551EC217994D4000A4135C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1E551F461799509100A4135C /* all */, + 1E3E3CA317995BEE005F2132 /* basic.ofx */, + 1E3E3CC717995DBB005F2132 /* field.ofx */, + 1E3E3CDC17995E76005F2132 /* noise.ofx */, + 1E3E3CF317995F57005F2132 /* invert.ofx */, + 1E3E3D0817995FB3005F2132 /* multibundle.ofx */, + 1E3E3D39179961B4005F2132 /* retimer.ofx */, + 1E3E3D5317996232005F2132 /* tester.ofx */, + 1E3E3D6A179962A4005F2132 /* transition.ofx */, + 1E3E3D8317996363005F2132 /* PropTester.ofx */, + 1E3E3D9D1799644B005F2132 /* pluginLoader */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1E3E3CA217995BEE005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CD417995DBB005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CE817995E76005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D0017995F57005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D1417995FB3005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D48179961B4005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D5F17996232005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D77179962A4005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D8F17996363005F2132 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1E3E3CA017995BEE005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3CBE17995D5C005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3CBF17995D5C005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3CC017995D5C005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3CC117995D5C005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3CC217995D5C005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3CC317995D5C005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3CC417995D5C005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3CC517995D5C005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3CB317995CC9005F2132 /* basic.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CC817995DBB005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3CCA17995DBB005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3CCB17995DBB005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3CCC17995DBB005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3CCD17995DBB005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3CCE17995DBB005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3CCF17995DBB005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3CD017995DBB005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3CD117995DBB005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3CDB17995DF6005F2132 /* field.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CDD17995E76005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3CDE17995E76005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3CDF17995E76005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3CE017995E76005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3CE117995E76005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3CE217995E76005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3CE317995E76005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3CE417995E76005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3CE517995E76005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3CF117995F2C005F2132 /* noise.cpp in Sources */, + 1E3E3CF217995F2C005F2132 /* randomGenerator.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3CF417995F57005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3CF517995F57005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3CF617995F57005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3CF717995F57005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3CF817995F57005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3CF917995F57005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3CFA17995F57005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3CFB17995F57005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3CFC17995F57005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D0717995F83005F2132 /* invert.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D0917995FB3005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D0A17995FB3005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3D0B17995FB3005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3D0C17995FB3005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3D0D17995FB3005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3D0E17995FB3005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3D0F17995FB3005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3D1017995FB3005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3D1117995FB3005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D2217996042005F2132 /* multibundle1.cpp in Sources */, + 1E3E3D2317996042005F2132 /* multibundle2.cpp in Sources */, + 1E3E3D2417996042005F2132 /* PluginRegistration.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D3A179961B4005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D3B179961B4005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3D3C179961B4005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3D3D179961B4005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3D3E179961B4005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3D3F179961B4005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3D40179961B4005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3D41179961B4005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3D42179961B4005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D50179961E2005F2132 /* retimer.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D5417996232005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D5517996232005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3D5617996232005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3D5717996232005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3D5817996232005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3D5917996232005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3D5A17996232005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3D5B17996232005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3D5C17996232005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D6617996262005F2132 /* Tester.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D6B179962A4005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D6C179962A4005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3D6D179962A4005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3D6E179962A4005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3D6F179962A4005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3D70179962A4005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3D71179962A4005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3D72179962A4005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3D73179962A4005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D80179962DE005F2132 /* crossFade.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D8417996363005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E3E3D8517996363005F2132 /* ofxsCore.cpp in Sources */, + 1E3E3D8617996363005F2132 /* ofxsImageEffect.cpp in Sources */, + 1E3E3D8717996363005F2132 /* ofxsInteract.cpp in Sources */, + 1E3E3D8817996363005F2132 /* ofxsLog.cpp in Sources */, + 1E3E3D8917996363005F2132 /* ofxsMultiThread.cpp in Sources */, + 1E3E3D8A17996363005F2132 /* ofxsParams.cpp in Sources */, + 1E3E3D8B17996363005F2132 /* ofxsProperty.cpp in Sources */, + 1E3E3D8C17996363005F2132 /* ofxsPropertyValidation.cpp in Sources */, + 1E3E3D96179963B4005F2132 /* propTester.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1E3E3D9A1799644B005F2132 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E08327B19A1E2C100A819A5 /* pluginLoader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1E3E3D27179960AC005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3CA317995BEE005F2132 /* basic.ofx */; + targetProxy = 1E3E3D26179960AC005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D29179960AC005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3CC717995DBB005F2132 /* field.ofx */; + targetProxy = 1E3E3D28179960AC005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D2B179960AC005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3CDC17995E76005F2132 /* noise.ofx */; + targetProxy = 1E3E3D2A179960AC005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D2D179960AC005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3CF317995F57005F2132 /* invert.ofx */; + targetProxy = 1E3E3D2C179960AC005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D2F179960AC005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D0817995FB3005F2132 /* multibundle.ofx */; + targetProxy = 1E3E3D2E179960AC005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D52179961ED005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D39179961B4005F2132 /* retimer.ofx */; + targetProxy = 1E3E3D51179961ED005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D6817996270005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D5317996232005F2132 /* tester.ofx */; + targetProxy = 1E3E3D6717996270005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D8217996301005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D6A179962A4005F2132 /* transition.ofx */; + targetProxy = 1E3E3D8117996301005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3D98179963C5005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D8317996363005F2132 /* PropTester.ofx */; + targetProxy = 1E3E3D97179963C5005F2132 /* PBXContainerItemProxy */; + }; + 1E3E3DAC17996479005F2132 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1E3E3D9D1799644B005F2132 /* pluginLoader */; + targetProxy = 1E3E3DAB17996479005F2132 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1E3E3CAF17995BEE005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Basic/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3CB017995BEE005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Basic/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3CD617995DBB005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Field/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = field.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3CD717995DBB005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Field/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = field.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3CEA17995E76005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Generator/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = noise.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3CEB17995E76005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Generator/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = noise.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D0217995F57005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Invert/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = invert.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D0317995F57005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Invert/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = invert.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D1617995FB3005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/MultiBundle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = multibundle.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D1717995FB3005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/MultiBundle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = multibundle.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D4A179961B4005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Retimer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = retimer.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D4B179961B4005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Retimer/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = retimer.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D6117996232005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Tester/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = tester.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D6217996232005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Tester/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = tester.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D79179962A4005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Transition/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = transition.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D7A179962A4005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = Plugins/Transition/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = transition.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3D9117996363005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = PropTester/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = PropTester.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1E3E3D9217996363005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + HEADER_SEARCH_PATHS = ( + "$(OFX_PATH)/include", + include, + ); + INFOPLIST_FILE = PropTester/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = PropTester.ofx; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1E3E3DA51799644B005F2132 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + 1E3E3DA61799644B005F2132 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; + 1E551ECD17994D4000A4135C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + OFX_SUPPORTS_OPENGLRENDER, + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(OFX_PATH)/include"; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries"; + OFX_PATH = ..; + ONLY_ACTIVE_ARCH = YES; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + ); + }; + name = Debug; + }; + 1E551ECE17994D4000A4135C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NDEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(OFX_PATH)/include"; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries"; + OFX_PATH = ..; + WARNING_CFLAGS = ( + "-Wall", + "-Wextra", + ); + }; + name = Release; + }; + 1E551F481799509100A4135C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 1E551F491799509100A4135C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1E3E3CAE17995BEE005F2132 /* Build configuration list for PBXNativeTarget "basic.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3CAF17995BEE005F2132 /* Debug */, + 1E3E3CB017995BEE005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3CD517995DBB005F2132 /* Build configuration list for PBXNativeTarget "field.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3CD617995DBB005F2132 /* Debug */, + 1E3E3CD717995DBB005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3CE917995E76005F2132 /* Build configuration list for PBXNativeTarget "noise.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3CEA17995E76005F2132 /* Debug */, + 1E3E3CEB17995E76005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D0117995F57005F2132 /* Build configuration list for PBXNativeTarget "invert.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D0217995F57005F2132 /* Debug */, + 1E3E3D0317995F57005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D1517995FB3005F2132 /* Build configuration list for PBXNativeTarget "multibundle.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D1617995FB3005F2132 /* Debug */, + 1E3E3D1717995FB3005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D49179961B4005F2132 /* Build configuration list for PBXNativeTarget "retimer.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D4A179961B4005F2132 /* Debug */, + 1E3E3D4B179961B4005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D6017996232005F2132 /* Build configuration list for PBXNativeTarget "tester.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D6117996232005F2132 /* Debug */, + 1E3E3D6217996232005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D78179962A4005F2132 /* Build configuration list for PBXNativeTarget "transition.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D79179962A4005F2132 /* Debug */, + 1E3E3D7A179962A4005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3D9017996363005F2132 /* Build configuration list for PBXNativeTarget "PropTester.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3D9117996363005F2132 /* Debug */, + 1E3E3D9217996363005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E3E3DA41799644B005F2132 /* Build configuration list for PBXNativeTarget "pluginLoader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E3E3DA51799644B005F2132 /* Debug */, + 1E3E3DA61799644B005F2132 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E551EBC17994D4000A4135C /* Build configuration list for PBXProject "Support" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E551ECD17994D4000A4135C /* Debug */, + 1E551ECE17994D4000A4135C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1E551F471799509100A4135C /* Build configuration list for PBXAggregateTarget "all" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E551F481799509100A4135C /* Debug */, + 1E551F491799509100A4135C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1E551EB917994D4000A4135C /* Project object */; +} diff --git a/third_party/openfx/Support/TODO b/third_party/openfx/Support/TODO new file mode 100644 index 000000000..0da9952a3 --- /dev/null +++ b/third_party/openfx/Support/TODO @@ -0,0 +1,8 @@ + - Skin message suite. + - Skin the parameter custom interacts. + - Return native OFX types from the various param functions, currently tend to return via reference args. + - integrate/differentiate on all the various param instances, + - Come up with a set of exception classes that the plugin can throw that will be trapped by the main routine so it can return an appropriate error code. + - Exception specs on all functions. + - test test test! + - examples examples examples! \ No newline at end of file diff --git a/third_party/openfx/Support/include/ofxsCore.h b/third_party/openfx/Support/include/ofxsCore.h new file mode 100755 index 000000000..d0884634e --- /dev/null +++ b/third_party/openfx/Support/include/ofxsCore.h @@ -0,0 +1,334 @@ + + +#ifndef _ofxsCore_H_ +#define _ofxsCore_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + + +/** @mainpage OFX Support Library + +@section mainpageIntro Introduction + +This support library skins the raw OFX C API with a set of C++ classes and functions that makes it easier to understand and write plug-ins to the API. Look at the examples to see how it is done. + +
+ +@section fifteenLineGuide Fifteen Line Plugin Writing Guide + +- work from the examples +- you need to write the following functions.... +- void OFX::Plugin::getPluginID(OFX::PluginID &id) +- gives the unique name and version numbers of the plug-in +- void OFX::Plugin::loadAction(void) +- called after the plug-in is first loaded, and before any instance has been made, +- void OFX::Plugin::unloadAction(void) +- called before the plug-in is unloaded, and all instances have been destroyed, +- void OFX::Plugin::describe(OFX::ImageEffectDescriptor &desc) +- called to describe the plugin to the host +- void OFX::Plugin::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context) +- called to describe the plugin to the host for a context reported in OFX::Plugin::describe +- OFX::ImageEffect * OFX::Plugin::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context) +- called when a new instance of a plug-in needs to be created. You need to derive a class from ImageEffect, new it and return it. + +The OFX::ImageEffect class has a set of members you can override to do various things, like rendering an effect. Again, look at the examples. + +
+ +@section license Copyright and License + +The library is Copyright OpenFX and contributors to the OpenFX project. and was +written by Bruno Nicoletti (bruno@thefoundry.co.uk). + +It has been released under the GNU Lesser General Public License, see the +top of any source file for details. + +*/ + +/** @file This file contains core code that wraps OFX 'objects' with C++ classes. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. +*/ + +#ifdef _MSC_VER +#pragma warning( disable : 4290 ) +#endif + +#include "ofxCore.h" +#include "ofxImageEffect.h" +#include "ofxInteract.h" +#include "ofxKeySyms.h" +#include "ofxMemory.h" +#include "ofxMessage.h" +#include "ofxMultiThread.h" +#include "ofxParam.h" +#include "ofxProperty.h" +#include "ofxPixels.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef OFX_CLIENT_EXCEPTION_HEADER +#include OFX_CLIENT_EXCEPTION_HEADER +#endif + +/** @brief Defines an integer 3D point + +Should migrate this to the ofxCore.h in a v1.1 +*/ +struct Ofx3DPointI { + int x, y, z; +}; + +/** @brief Defines a double precision 3D point + +Should migrate this to the ofxCore.h in a v1.1 +*/ +struct Ofx3DPointD { + double x, y, z; +}; + +/** @brief Nasty macro used to define empty protected copy ctors and assign ops */ +#define mDeclareProtectedAssignAndCC(CLASS) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &) {assert(false); } + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. +*/ +namespace OFX { + /** forward class declarations */ + class PropertySet; + + /** @brief Enumerates the different types a property can be */ + enum PropertyTypeEnum { + ePointer, + eInt, + eString, + eDouble + }; + + /** @brief Enumerates the reasons a plug-in instance may have had one of its values changed */ + enum InstanceChangeReason { + eChangeUserEdit, /**< @brief A user actively editted something in the plugin, eg: changed the value of an integer param on an interface */ + eChangePluginEdit, /**< @brief The plugin's own code changed something in the instance, eg: a callback on on param settting the value of another */ + eChangeTime /**< @brief The current value of a parameter has changed because the param animates and the current time has changed */ + }; + + /** @brief maps a status to a string for debugging purposes, note a c-str for printf */ + const char * mapStatusToString(OfxStatus stat); + + /** @brief namespace for OFX support lib exceptions, all derive from std::exception, calling it */ + namespace Exception { + + /** @brief thrown when a suite returns a dud status code + */ + class Suite : public std::exception { + protected : + OfxStatus _status; + public : + Suite(OfxStatus s) : _status(s) {} + OfxStatus status(void) const {return _status;} + operator OfxStatus() const {return _status;} + + /** @brief reimplemented from std::exception */ + virtual const char * what () const noexcept {return mapStatusToString(_status);} + + }; + + /** @brief Exception indicating that a host doesn't know about a property that is should do */ + class PropertyUnknownToHost : public std::exception { + protected : + std::string _what; + public : + PropertyUnknownToHost(const char *what) : _what(what) {} + virtual ~PropertyUnknownToHost() noexcept {} + + /** @brief reimplemented from std::exception */ + virtual const char * what () const noexcept + { + return _what.c_str(); + } + }; + + /** @brief exception indicating that the host thinks a property has an illegal value */ + class PropertyValueIllegalToHost : public std::exception { + protected : + std::string _what; + public : + PropertyValueIllegalToHost(const char *what) : _what(what) {} + virtual ~PropertyValueIllegalToHost() noexcept {} + + /** @brief reimplemented from std::exception */ + virtual const char * what () const noexcept + { + return _what.c_str(); + } + }; + + /** @brief exception indicating a request for a named thing exists (eg: a param), but is of the wrong type, should never make it back to the main entry + indicates a logical error in the code. Asserts are raised in debug code in these situations. + */ + class TypeRequest : public std::exception { + protected : + std::string _what; + public : + TypeRequest(const char *what) : _what(what) {} + virtual ~TypeRequest() noexcept {} + + /** @brief reimplemented from std::exception */ + virtual const char * what () const noexcept + { + return _what.c_str(); + } + }; + + //////////////////////////////////////////////////////////////////////////////// + // These exceptions are to be thrown by the plugin if it hits a problem, the + // code managing the main entry will trap the exception and return a suitable + // status code to the host. + + /** @brief exception indicating a required host feature is missing */ + class HostInadequate : public std::exception { + protected : + std::string _what; + public : + HostInadequate(const char *what) : _what(what) {} + virtual ~HostInadequate() noexcept {} + + /** @brief reimplemented from std::exception */ + virtual const char * what () const noexcept + { + return _what.c_str(); + } + }; + + }; // end of Exception namespace + + /** @brief Throws an @ref OFX::Exception::Suite depending on the status flag passed in */ + void + throwSuiteStatusException(OfxStatus stat); + + void + throwHostMissingSuiteException(std::string name); + + /** @brief This struct is used to return an identifier for the plugin by the function @ref OFX:Plugin::getPlugin. + The members correspond to those in the OfxPlugin struct defined in ofxCore.h. + */ + + class ImageEffectDescriptor; + class ImageEffect; + + /** @brief This class wraps up an OFX property set */ + class PropertySet { + protected : + /** @brief The raw property handle */ + OfxPropertySetHandle _propHandle; + + /** @brief Class static, whether we are logging each property action */ + static int _gPropLogging; + + /** @brief Do not throw an exception if a host returns 'unsupported' when setting a property */ + static bool _gThrowOnUnsupported; + + public : + /** @brief turns on logging of property access functions */ + static void propEnableLogging(void) {++_gPropLogging;} + + /** @brief turns off logging of property access functions */ + static void propDisableLogging(void) {--_gPropLogging;} + + /** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */ + static void setThrowOnUnsupportedProperties(bool v) {_gThrowOnUnsupported = v;} + + /** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */ + static bool getThrowOnUnsupportedProperties(void) {return _gThrowOnUnsupported;} + + /** @brief construct a property set */ + PropertySet(OfxPropertySetHandle h = 0) : _propHandle(h) {} + virtual ~PropertySet(); + + /** @brief set the handle to use for this set */ + void propSetHandle(OfxPropertySetHandle h) { _propHandle = h;} + + /** @brief return the handle for this property set */ + OfxPropertySetHandle propSetHandle(void) const {return _propHandle;} + + int propGetDimension(const char* property, bool throwOnFailure = true) const; + void propReset(const char* property); + + // set single values + void propSetPointer(const char* property, void *value, int idx, bool throwOnFailure = true); + void propSetString(const char* property, const std::string &value, int idx, bool throwOnFailure = true); + void propSetDouble(const char* property, double value, int idx, bool throwOnFailure = true); + void propSetInt(const char* property, int value, int idx, bool throwOnFailure = true); + + // set multiple values + void propSetDoubleN(const char* property, const double *value, int count, bool throwOnFailure = true); + + void propSetPointer(const char* property, void *value, bool throwOnFailure = true) + {propSetPointer(property, value, 0, throwOnFailure);} + + void propSetString(const char* property, const std::string &value, bool throwOnFailure = true) + {propSetString(property, value, 0, throwOnFailure);} + + void propSetDouble(const char* property, double value, bool throwOnFailure = true) + {propSetDouble(property, value, 0, throwOnFailure);} + + void propSetInt(const char* property, int value, bool throwOnFailure = true) + {propSetInt(property, value, 0, throwOnFailure);} + + + /// get a pointer property + void *propGetPointer(const char* property, int idx, bool throwOnFailure = true) const; + + /// get a string property + std::string propGetString(const char* property, int idx, bool throwOnFailure = true) const; + /// get a double property + double propGetDouble(const char* property, int idx, bool throwOnFailure = true) const; + + /// get an int property + int propGetInt(const char* property, int idx, bool throwOnFailure = true) const; + + /// get a pointer property with index 0 + void* propGetPointer(const char* property, bool throwOnFailure = true) const + { + return propGetPointer(property, 0, throwOnFailure); + } + + /// get a string property with index 0 + std::string propGetString(const char* property, bool throwOnFailure = true) const + { + return propGetString(property, 0, throwOnFailure); + } + + /// get a double property with index 0 + double propGetDouble(const char* property, bool throwOnFailure = true) const + { + return propGetDouble(property, 0, throwOnFailure); + } + + /// get an int property with index 0 + int propGetInt(const char* property, bool throwOnFailure = true) const + { + return propGetInt(property, 0, throwOnFailure); + } + + std::list propGetNString(const char* property, bool throwOnFailure = true) const; + + }; + + // forward decl of the image effect + class ImageEffect; +}; + +// undeclare the protected assign and CC macro +#undef mDeclareProtectedAssignAndCC + +#endif diff --git a/third_party/openfx/Support/include/ofxsImageEffect.h b/third_party/openfx/Support/include/ofxsImageEffect.h new file mode 100644 index 000000000..1cce91a07 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsImageEffect.h @@ -0,0 +1,1224 @@ + + +#ifndef _ofxsImageEffect_H_ +#define _ofxsImageEffect_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +/** @file This file contains core code that wraps OFX 'objects' with C++ classes. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. +*/ +#include +#include +#include +#include +#include "ofxsParam.h" +#include "ofxsInteract.h" +#include "ofxsMessage.h" +#include "ofxProgress.h" +#include "ofxTimeLine.h" +#include "ofxParametricParam.h" + +/** @brief Nasty macro used to define empty protected copy ctors and assign ops */ +#define mDeclareProtectedAssignAndCC(CLASS) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &) {assert(false); } +#define mDeclareProtectedAssignAndCCBase(CLASS,BASE) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &c) : BASE(c) {assert(false); } + +namespace OFX +{ + namespace Private + { + OfxStatus mainEntryStr(const char *actionRaw, + const void *handleRaw, + OfxPropertySetHandle inArgsRaw, + OfxPropertySetHandle outArgsRaw, + const char* plugname); + + OfxStatus customParamInterpolationV1Entry( + const void* handleRaw, + OfxPropertySetHandle inArgsRaw, + OfxPropertySetHandle outArgsRaw); + } +} + + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. +*/ +namespace OFX { + /** forward class declarations */ + class ClipDescriptor; + class ImageEffectDescriptor; + + class Image; + class Clip; + class ImageEffect; + class ImageMemory; + + /** @brief Enumerates the contexts a plugin can be used in */ + enum ContextEnum {eContextNone, + eContextGenerator, + eContextFilter, + eContextTransition, + eContextPaint, + eContextGeneral, + eContextRetimer, + }; + + /** @brief Enumerates the pixel depths supported */ + enum BitDepthEnum {eBitDepthNone, /**< @brief bit depth that indicates no data is present */ + eBitDepthUByte, + eBitDepthUShort, + eBitDepthHalf, + eBitDepthFloat, + eBitDepthCustom, ///< some non standard bit depth + }; + + /** @brief Enumerates the component types supported */ + enum PixelComponentEnum {ePixelComponentNone, + ePixelComponentRGBA, + ePixelComponentRGB, + ePixelComponentAlpha, + ePixelComponentCustom ///< some non standard pixel type + }; + + /** @brief Enumerates the ways a fielded image can be extracted from a clip */ + enum FieldExtractionEnum {eFieldExtractBoth, /**< @brief extract both fields */ + eFieldExtractSingle, /**< @brief extracts a single field, so you have a half height image */ + eFieldExtractDoubled /**< @brief extracts a single field, but doubles up the field, so you have a full height image */ + }; + + /** @brief Enumerates the kind of render thread safety a plugin has */ + enum RenderSafetyEnum {eRenderUnsafe, /**< @brief can only render a single instance at any one time */ + eRenderInstanceSafe, /**< @brief can call a single render on an instance, but can render multiple instances simultaneously */ + eRenderFullySafe /**< @brief can call render any number of times on an instance, and render multiple instances simultaneously */ + }; + + /** @brief Enumerates the fields present in an image */ + enum FieldEnum {eFieldNone, /**< @brief unfielded image */ + eFieldBoth, /**< @brief fielded image with both fields present */ + eFieldLower, /**< @brief only the spatially lower field is present */ + eFieldUpper, /**< @brief only the spatially upper field is present */ + eFieldSingle, /**< @brief image that consists of a single field, and so is half height */ + eFieldDoubled /**< @brief image that consists of a single field, but each scan line is double, and so is full height */ + }; + + enum PreMultiplicationEnum { eImageOpaque, /**< @brief the image is opaque and so has no premultiplication state */ + eImagePreMultiplied, /**< @brief the image is premultiplied by it's alpha */ + eImageUnPreMultiplied, /**< @brief the image is unpremultiplied */ + }; + + enum NativeOriginEnum { + eNativeOriginBottomLeft, + eNativeOriginTopLeft, + eNativeOriginCenter + }; + + /** @brief turns a field string into and enum */ + FieldEnum mapStrToFieldEnum(const std::string &str); + + //////////////////////////////////////////////////////////////////////////////// + /** @brief map a std::string to a context enum */ + ContextEnum mapToContextEnum(const std::string &s); + + const char* mapContextEnumToStr(ContextEnum context); + + const char* mapMessageTypeEnumToStr(OFX::Message::MessageTypeEnum type); + + OFX::Message::MessageReplyEnum mapToMessageReplyEnum(OfxStatus stat); + + InstanceChangeReason mapToInstanceChangedReason(const std::string &s); + + BitDepthEnum mapStrToBitDepthEnum(const std::string &str); + + const char* mapBitDepthEnumToStr(BitDepthEnum bitDepth); + + PixelComponentEnum mapStrToPixelComponentEnum(const std::string &str); + + const char* mapPixelComponentEnumToStr(PixelComponentEnum pixelComponent); + + class PluginFactory + { + public: + virtual void load() {} + virtual void unload() {} + virtual void describe(OFX::ImageEffectDescriptor &desc) = 0; + virtual void describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context) = 0; + virtual ImageEffect* createInstance(OfxImageEffectHandle handle, ContextEnum context) = 0; + virtual const std::string& getID() const = 0; + virtual const std::string& getUID() const = 0; + virtual unsigned int getMajorVersion() const = 0; + virtual unsigned int getMinorVersion() const = 0; + virtual OfxPluginEntryPoint* getMainEntry() = 0; + }; + + template + class FactoryMainEntryHelper + { + protected: + const std::string& getHelperID() const { return _id; } + unsigned int getHelperMajorVersion() const { return _maj; } + unsigned int getHelperMinorVersion() const { return _min; } + std::string toString(unsigned int val) + { + std::ostringstream ss; + ss << val; + return ss.str(); + } + FactoryMainEntryHelper(const std::string& id, unsigned int maj, unsigned int min): _id(id), _maj(maj), _min(min) + { + assert(_uid.empty()); // constructor should only be called once + _uid = id + toString(maj) + toString(min); + } + const std::string& getHelperUID() const { return _uid; } + static OfxStatus mainEntry(const char *action, const void* handle, OfxPropertySetHandle in, OfxPropertySetHandle out) + { + return OFX::Private::mainEntryStr(action, handle, in, out, _uid.c_str()); + } + + static std::string _uid; + std::string _id; + unsigned int _maj; + unsigned int _min; + }; + template std::string OFX::FactoryMainEntryHelper::_uid; + + template + class PluginFactoryHelper : public FactoryMainEntryHelper, public PluginFactory + { + public: + PluginFactoryHelper(const std::string& id, unsigned int maj, unsigned int min): FactoryMainEntryHelper(id, maj, min) + {} + OfxPluginEntryPoint* getMainEntry() { return FactoryMainEntryHelper::mainEntry; } + const std::string& getID() const { return FactoryMainEntryHelper::getHelperID(); } + const std::string& getUID() const { return FactoryMainEntryHelper::getHelperUID(); } + unsigned int getMajorVersion() const { return FactoryMainEntryHelper::getHelperMajorVersion(); } + unsigned int getMinorVersion() const { return FactoryMainEntryHelper::getHelperMinorVersion(); } + }; + +#define mDeclarePluginFactory(CLASS, LOADFUNCDEF, UNLOADFUNCDEF) \ + class CLASS : public OFX::PluginFactoryHelper \ + { \ + public: \ + CLASS(const std::string& id, unsigned int verMaj, unsigned int verMin):OFX::PluginFactoryHelper(id, verMaj, verMin){} \ + virtual void load() LOADFUNCDEF ;\ + virtual void unload() UNLOADFUNCDEF ;\ + virtual void describe(OFX::ImageEffectDescriptor &desc); \ + virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context); \ + virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context); \ + }; + + typedef std::vector PluginFactoryArray; + + /** @brief Fetch's a suite from the host and logs errors + + All the standard suites are fetched by the support code, you should use this + to fetch any extra non-standard suites. + */ + const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional = false); + + //////////////////////////////////////////////////////////////////////////////// + /** @brief A class that lists all the properties of a host */ + struct ImageEffectHostDescription { + public : + int APIVersionMajor; + int APIVersionMinor; + std::string hostName; + std::string hostLabel; + int versionMajor; + int versionMinor; + int versionMicro; + std::string versionLabel; + bool hostIsBackground; + bool supportsOverlays; + bool supportsMultiResolution; + bool supportsTiles; + bool temporalClipAccess; + bool supportsMultipleClipDepths; + bool supportsMultipleClipPARs; + bool supportsSetableFrameRate; + bool supportsSetableFielding; + int sequentialRender; + bool supportsStringAnimation; + bool supportsCustomInteract; + bool supportsChoiceAnimation; + bool supportsStrChoice; + bool supportsStrChoiceAnimation; + bool supportsBooleanAnimation; + bool supportsCustomAnimation; + void* osHandle; + bool supportsParametricParameter; + bool supportsParametricAnimation; + bool supportsRenderQualityDraft; + NativeOriginEnum nativeOrigin; + bool supportsOpenCLRender; + bool supportsCudaRender; + bool supportsCudaStream; + bool supportsMetalRender; +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool supportsOpenGLRender; +#endif + int maxParameters; + int maxPages; + int pageRowCount; + int pageColumnCount; + typedef std::vector PixelComponentArray; + PixelComponentArray _supportedComponents; + typedef std::vector ContextArray; + ContextArray _supportedContexts; + typedef std::vector PixelDepthArray; + PixelDepthArray _supportedPixelDepths; + bool supportsProgressSuite; + bool supportsTimeLineSuite; + bool supportsMessageSuiteV2; + + public: + bool supportsPixelComponent(const PixelComponentEnum component) const; + bool supportsBitDepth( const BitDepthEnum bitDepth) const; + bool supportsContext(const ContextEnum context) const; + + /** @return default pixel depth supported by host application. */ + BitDepthEnum getDefaultPixelDepth() const; + + /** @return default pixel component supported by host application. */ + PixelComponentEnum getDefaultPixelComponent() const; + }; + + + /// retrieve the host description + ImageEffectHostDescription* getImageEffectHostDescription(); + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a clip */ + class ClipDescriptor { + protected : + mDeclareProtectedAssignAndCC(ClipDescriptor); + ClipDescriptor(void) {assert(false);} + + protected : + /** @brief name of the clip */ + std::string _clipName; + + /** @brief properties for this clip */ + PropertySet _clipProps; + + protected : + /** @brief hidden constructor */ + ClipDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ImageEffectDescriptor; + + public : + const PropertySet &getPropertySet() const {return _clipProps;} + + PropertySet &getPropertySet() {return _clipProps;} + + + /** @brief set the label properties */ + void setLabel(const std::string &label); + + /** @brief set the label properties */ + void setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel); + + /** @brief set how fielded images are extracted from the clip defaults to eFieldExtractDoubled */ + void setFieldExtraction(FieldExtractionEnum v); + + /** @brief set which components are supported, defaults to none set, this must be called at least once! */ + void addSupportedComponent(PixelComponentEnum v); + + /** @brief set which components are supported. This version adds by the raw C-string label, allowing you to add + custom component types */ + void addSupportedComponent(const std::string &comp); + + /** @brief say whether we are going to do random temporal access on this clip, defaults to false */ + void setTemporalClipAccess(bool v); + + /** @brief say whether if the clip is optional, defaults to false */ + void setOptional(bool v); + + /** @brief say whether this clip supports tiling, defaults to true */ + void setSupportsTiles(bool v); + + /** @brief say whether this clip is a 'mask', so the host can know to replace with a roto or similar, defaults to false */ + void setIsMask(bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an effect descriptor, used in the describe actions */ + class ImageEffectDescriptor : public ParamSetDescriptor + { + protected : + mDeclareProtectedAssignAndCCBase(ImageEffectDescriptor,ParamSetDescriptor); + ImageEffectDescriptor(void) {assert(false);} + + protected : + /** @brief The effect handle */ + OfxImageEffectHandle _effectHandle; + + /** @brief properties for this clip */ + PropertySet _effectProps; + + /** @brief Set of all previously defined parameters, defined on demand */ + std::map _definedClips; + + /** @brief Set of strings for clip preferences action (stored in here so the array persists and can be used in a property name)*/ + std::map _clipComponentsPropNames; + std::map _clipDepthPropNames; + std::map _clipPARPropNames; + std::map _clipROIPropNames; + std::map _clipFrameRangePropNames; + + std::unique_ptr _overlayDescriptor; + public : + /** @brief ctor */ + ImageEffectDescriptor(OfxImageEffectHandle handle); + + /** @brief dtor */ + ~ImageEffectDescriptor(); + + const PropertySet &getPropertySet() const {return _effectProps;} + + PropertySet &getPropertySet() {return _effectProps;} + + /** @brief, set the label properties in a plugin */ + void setLabel(const std::string &label); + + /** @brief, set the label properties in a plugin */ + void setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel); + + /** @brief, set the version properties in a plugin */ + void setVersion(int major, int minor, int micro, int build, const std::string &versionLabel); + + /** @brief Set the plugin grouping, defaults to "" */ + void setPluginGrouping(const std::string &group); + + /** @brief Set the plugin description, defaults to "" */ + void setPluginDescription(const std::string &description); + + /** @brief Add a context to those supported, defaults to none, must be called at least once */ + void addSupportedContext(ContextEnum v); + + /** @brief Add a pixel depth to those supported, defaults to none, must be called at least once */ + void addSupportedBitDepth(BitDepthEnum v); + + /** @brief Add a pixel depth to those supported for OpenGL rendering, defaults to all */ + void addSupportedOpenGLBitDepth(BitDepthEnum v); + + /** @brief Is the plugin single instance only ? defaults to false */ + void setSingleInstance(bool v); + + /** @brief Does the plugin expect the host to perform per frame SMP threading defaults to true */ + void setHostFrameThreading(bool v); + + /** @brief Does the plugin support multi resolution images, defaults to true */ + void setSupportsMultiResolution(bool v); + + /** @brief Does the plugin support image tiling, defaults to true */ + void setSupportsTiles(bool v); + + /** @brief Does the plugin perform temporal clip access, defaults to false */ + void setTemporalClipAccess(bool v); + + /** @brief Does the plugin want to have render called twice per frame in all circumanstances for fielded images ? defaults to true */ + void setRenderTwiceAlways(bool v); + + /** @brief Does the plugin support inputs and output clips of differing depths, defaults to false */ + void setSupportsMultipleClipDepths(bool v); + + /** @brief Does the plugin support inputs and output clips of pixel aspect ratios, defaults to false */ + void setSupportsMultipleClipPARs(bool v); + + /** @brief How thread safe is the plugin, defaults to eRenderInstanceSafe */ + void setRenderThreadSafety(RenderSafetyEnum v); + + /** @brief If the slave param changes the clip preferences need to be re-evaluated */ + void addClipPreferencesSlaveParam(ParamDescriptor &p); + + /** @brief Does the plugin support OpenCL Buffers Render, defaults to false */ + void setSupportsOpenCLBuffersRender(bool v); + + /** @brief Does the plugin support OpenCL Images Render, defaults to false */ + void setSupportsOpenCLImagesRender(bool v); + + /** @brief Does the plugin support CUDA Render, defaults to false */ + void setSupportsCudaRender(bool v); + + /** @brief Does the plugin support CUDA Stream Render, defaults to false */ + void setSupportsCudaStream(bool v); + + /** @brief Does the plugin support Metal Render, defaults to false */ + void setSupportsMetalRender(bool v); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief Does the plugin support OpenGL accelerated rendering (but is also capable of CPU rendering) ? */ + void setSupportsOpenGLRender(bool v); + + /** @brief Does the plugin require OpenGL accelerated rendering ? */ + void setNeedsOpenGLRender(bool v); + void addOpenGLBitDepth(BitDepthEnum bitDepth); +#endif + + /** @brief Create a clip, only callable from describe in context + + The returned clip \em must not be deleted by the client code. This is all managed by the ImageEffectDescriptor itself. + */ + ClipDescriptor *defineClip(const std::string &name); + + /** @brief Access to the string maps needed for runtime properties. Because the char array must persist after the call, + we need these to be stored in the descriptor, which is only deleted on unload.*/ + + const std::map& getClipComponentPropNames() const { return _clipComponentsPropNames; } + const std::map& getClipDepthPropNames() const { return _clipDepthPropNames; } + const std::map& getClipPARPropNames() const { return _clipPARPropNames; } + const std::map& getClipROIPropNames() const { return _clipROIPropNames; } + const std::map& getClipFrameRangePropNames() const { return _clipFrameRangePropNames; } + + /** @brief override this to create an interact for the effect */ + virtual void setOverlayInteractDescriptor(EffectOverlayDescriptor* desc); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an image */ + class ImageBase { + protected : + /** @brief the handle that holds this image */ + PropertySet _imageProps; + + /** @brief friend so we get access to ctor */ + //friend class Clip; + + PixelComponentEnum _pixelComponents; /**< @brief get the components in the image */ + int _pixelComponentCount; + int _rowBytes; /**< @brief the number of bytes per scanline */ + int _pixelBytes; /**< @brief the number of bytes per pixel */ + BitDepthEnum _pixelDepth; /**< @brief get the pixel depth */ + PreMultiplicationEnum _preMultiplication; /**< @brief premultiplication on the image */ + OfxRectI _regionOfDefinition; /**< @brief the RoD in pixel coordinates, this may be more or less than the bounds! */ + OfxRectI _bounds; /**< @brief the bounds on the pixel data */ + double _pixelAspectRatio; /**< @brief the pixel aspect ratio */ + FieldEnum _field; /**< @brief which field this represents */ + std::string _uniqueID; /**< @brief the unique ID of this image */ + OfxPointD _renderScale; /**< @brief any scaling factor applied to the image */ + + public : + /** @brief ctor */ + ImageBase(OfxPropertySetHandle props); + + /** @brief dtor */ + virtual ~ImageBase(); + + const PropertySet &getPropertySet() const {return _imageProps;} + + PropertySet &getPropertySet() {return _imageProps;} + + /** @brief get the pixel depth */ + BitDepthEnum getPixelDepth(void) const {return _pixelDepth;} + + /** @brief get the components in the image */ + PixelComponentEnum getPixelComponents(void) const { return _pixelComponents;} + + /** @brief get the number of components in the image */ + int getPixelComponentCount(void) const { return _pixelComponentCount; } + + /** @brief get the string representing the pixel components */ + std::string getPixelComponentsProperty(void) const { return _imageProps.propGetString(kOfxImageEffectPropComponents);} + + /** @brief premultiplication on the image */ + PreMultiplicationEnum getPreMultiplication(void) const { return _preMultiplication;} + + /** @brief get the scale factor that has been applied to this image */ + const OfxPointD& getRenderScale(void) const { return _renderScale;} + + /** @brief get the scale factor that has been applied to this image */ + double getPixelAspectRatio(void) const { return _pixelAspectRatio;} + + /** @brief get the region of definition (in pixel coordinates) of this image */ + const OfxRectI& getRegionOfDefinition(void) const { return _regionOfDefinition;} + + /** @brief get the bounds on the image data (in pixel coordinates) of this image */ + const OfxRectI& getBounds(void) const { return _bounds;} + + /** @brief get the row bytes, may be negative */ + int getRowBytes(void) const { return _rowBytes;} + + /** @brief get the fielding of this image */ + FieldEnum getField(void) const { return _field;} + + /** @brief the unique ID of this image */ + const std::string& getUniqueIdentifier(void) const { return _uniqueID;} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an image */ + class Image : public ImageBase { + protected : + void *_pixelData; /**< @brief the base address of the image */ + void *_OpenCLImage; /**< @brief the OpenCL Image handle */ + + public : + /** @brief ctor */ + Image(OfxPropertySetHandle props); + + /** @brief dtor */ + virtual ~Image(); + + /** @brief get the pixel data for this image */ + void *getPixelData(void) { return _pixelData;} + + /** @brief get the pixel data for this image */ + const void *getPixelData(void) const { return _pixelData;} + + /** @brief get the OpenCL Image for this image */ + void *getOpenCLImage(void) { return _OpenCLImage;} + + /** @brief get the OpenCL Image for this image */ + const void *getOpenCLImage(void) const { return _OpenCLImage;} + + /** @brief return a pixel pointer, returns NULL if (x,y) is outside the image bounds + + x and y are in pixel coordinates + + If the components are custom, then this will return NULL as the support code + can't know the pixel size to do the work. + */ + void *getPixelAddress(int x, int y); + + /** @brief return a pixel pointer, returns NULL if (x,y) is outside the image bounds + + x and y are in pixel coordinates + + If the components are custom, then this will return NULL as the support code + can't know the pixel size to do the work. + */ + const void *getPixelAddress(int x, int y) const; + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an OpenGL texture */ + class Texture : public ImageBase { + protected : + int _index; + int _target; + + public : + /** @brief ctor */ + Texture(OfxPropertySetHandle props); + + /** @brief dtor */ + virtual ~Texture(); + + /** @brief get OpenGL texture id (cast to GLuint) */ + inline int getIndex() const {return _index;} + + /** @brief get OpenGL texture target (cast to GLenum) */ + inline int getTarget() const {return _target;} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a clip instance */ + class Clip { + protected : + mDeclareProtectedAssignAndCC(Clip); + + /** @brief name of the clip */ + std::string _clipName; + + /** @brief properties for this clip */ + PropertySet _clipProps; + + /** @brief handle for this clip */ + OfxImageClipHandle _clipHandle; + + /** @brief effect instance that owns this clip */ + ImageEffect *_effect; + + /** @brief hidden constructor */ + Clip(ImageEffect *effect, const std::string &name, OfxImageClipHandle handle, OfxPropertySetHandle props); + + /** @brief so one can be made */ + friend class ImageEffect; + + public : + /// get the underlying property set on this clip + const PropertySet &getPropertySet() const {return _clipProps;} + + /// get the underlying property set on this clip + PropertySet &getPropertySet() {return _clipProps;} + + /// get the OFX clip handle + OfxImageClipHandle getHandle() {return _clipHandle;} + + /** @brief get the name */ + const std::string &name(void) const {return _clipName;} + + /** @brief fetch the label */ + void getLabel(std::string &label) const; + + /** @brief fetch the labels */ + void getLabels(std::string &label, std::string &shortLabel, std::string &longLabel) const; + + /** @brief what is the pixel depth images will be given to us as */ + BitDepthEnum getPixelDepth(void) const; + + /** @brief what is the components images will be given to us as */ + PixelComponentEnum getPixelComponents(void) const; + + /** @brief get the number of components in the image */ + int getPixelComponentCount(void) const; + + /** @brief get the string representing the pixel components */ + std::string getPixelComponentsProperty(void) const { return _clipProps.propGetString(kOfxImageEffectPropComponents);} + + /** @brief what is the actual pixel depth of the clip */ + BitDepthEnum getUnmappedPixelDepth(void) const; + + /** @brief what is the component type of the clip */ + PixelComponentEnum getUnmappedPixelComponents(void) const; + + /** @brief get the string representing the pixel components */ + std::string getUnmappedPixelComponentsProperty(void) const { return _clipProps.propGetString(kOfxImageClipPropUnmappedComponents);} + + /** @brief get the components in the image */ + PreMultiplicationEnum getPreMultiplication(void) const; + + /** @brief which spatial field comes first temporally */ + FieldEnum getFieldOrder(void) const; + + /** @brief is the clip connected */ + bool isConnected(void) const; + + /** @brief can the clip be continuously sampled */ + bool hasContinuousSamples(void) const; + + /** @brief get the scale factor that has been applied to this clip */ + double getPixelAspectRatio(void) const; + + /** @brief get the frame rate, in frames per second on this clip, after any clip preferences have been applied */ + double getFrameRate(void) const; + + /** @brief return the range of frames over which this clip has images, after any clip preferences have been applied */ + OfxRangeD getFrameRange(void) const; + + /** @brief get the frame rate, in frames per second on this clip, before any clip preferences have been applied */ + double getUnmappedFrameRate(void) const; + + /** @brief return the range of frames over which this clip has images, before any clip preferences have been applied */ + OfxRangeD getUnmappedFrameRange(void) const; + + /** @brief get the RoD for this clip in the cannonical coordinate system */ + OfxRectD getRegionOfDefinition(double t); + + /** @brief fetch an image + + When finished with, the client code must delete the image. + + If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. + */ + Image *fetchImage(double t); + + /** @brief fetch an image, with a specific region in cannonical coordinates + + When finished with, the client code must delete the image. + + If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. + */ + Image *fetchImage(double t, const OfxRectD &bounds); + + /** @brief fetch an image, with a specific region in cannonical coordinates + + When finished with, the client code must delete the image. + + If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. + */ + Image *fetchImage(double t, const OfxRectD *bounds) + { + if(bounds) + return fetchImage(t, *bounds); + else + return fetchImage(t); + } + +#ifdef OFX_SUPPORTS_OPENGLRENDER + Texture *loadTexture(double t, BitDepthEnum format = eBitDepthNone, const OfxRectD *region = NULL); +#endif + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Class that skins image memory allocation */ + class ImageMemory { + protected : + OfxImageMemoryHandle _handle; + + public : + /** @brief ctor */ + ImageMemory(size_t nBytes, ImageEffect *associatedEffect = 0); + + /** @brief dtor */ + ~ImageMemory(); + + /** @brief lock the memory and return a pointer to it */ + void *lock(void); + + /** @brief unlock the memory */ + void unlock(void); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief POD struct to pass rendering arguments into @ref ImageEffect::render */ + struct RenderArguments { + double time; + OfxPointD renderScale; + OfxRectI renderWindow; + FieldEnum fieldToRender; + bool isEnabledOpenCLRender; + bool isEnabledCudaRender; + bool isEnabledMetalRender; + void* pOpenCLCmdQ; + void* pCudaStream; + void* pMetalCmdQ; +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool openGLEnabled; +#endif + bool sequentialRenderStatus; + bool interactiveRenderStatus; + bool renderQualityDraft; + }; + + /** @brief POD struct to pass rendering arguments into @ref OFX::ImageEffect::isIdentity */ + struct IsIdentityArguments { + double time; + OfxPointD renderScale; + OfxRectI renderWindow; + FieldEnum fieldToRender; + }; + + /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::render */ + struct BeginSequenceRenderArguments { + OfxRangeD frameRange; + double frameStep; + bool isInteractive; + OfxPointD renderScale; + bool isEnabledOpenCLRender; + bool isEnabledCudaRender; + bool isEnabledMetalRender; + void* pOpenCLCmdQ; + void* pCudaStream; + void* pMetalCmdQ; +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool openGLEnabled; +#endif + bool sequentialRenderStatus; + bool interactiveRenderStatus; + }; + + /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::beginSequenceRender */ + struct EndSequenceRenderArguments { + bool isInteractive; + OfxPointD renderScale; + bool isEnabledOpenCLRender; + bool isEnabledCudaRender; + bool isEnabledMetalRender; + void* pOpenCLCmdQ; + void* pCudaStream; + void* pMetalCmdQ; +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool openGLEnabled; +#endif + bool sequentialRenderStatus; + bool interactiveRenderStatus; + }; + + /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getRegionOfDefinition */ + struct RegionOfDefinitionArguments { + double time; + OfxPointD renderScale; + }; + + /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getRegionsOfInterest */ + struct RegionsOfInterestArguments { + double time; + OfxPointD renderScale; + OfxRectD regionOfInterest; + }; + + /** @brief Class used to set regions of interest on a clip in @ref OFX::ImageEffect::getRegionsOfInterest + + This is a base class, the actual class is private and you don't need to see the glue involved. + */ + class RegionOfInterestSetter { + public : + /** @brief function to set the RoI of a clip, pass in the clip to set the RoI of, and the RoI itself */ + virtual void setRegionOfInterest(const Clip &clip, const OfxRectD &RoI) = 0; + }; + + /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getFramesNeeded */ + struct FramesNeededArguments { + double time; + }; + + /** @brief Class used to set the frames needed to render a single frame of a clip in @ref OFX::ImageEffect::getFramesNeeded + + This is a base class, the actual class is private and you don't need to see the glue involved. + */ + class FramesNeededSetter { + public : + /** @brief function to set the frames needed on a clip, the range is min <= time <= max */ + virtual void setFramesNeeded(const Clip &clip, const OfxRangeD &range) = 0; + }; + + /** @brief Class used to set the clip preferences of the effect. + */ + class ClipPreferencesSetter { + OFX::PropertySet outArgs_; + bool doneSomething_; + typedef std::map StringStringMap; + const StringStringMap& clipDepthPropNames_; + const StringStringMap& clipComponentPropNames_; + const StringStringMap& clipPARPropNames_; + const std::string& extractValueForName(const StringStringMap& m, const std::string& name); + public : + ClipPreferencesSetter( OFX::PropertySet props, + const StringStringMap& depthPropNames, + const StringStringMap& componentPropNames, + const StringStringMap& PARPropNames) + : outArgs_(props) + , doneSomething_(false) + , clipDepthPropNames_(depthPropNames) + , clipComponentPropNames_(componentPropNames) + , clipPARPropNames_(PARPropNames) + {} + + bool didSomething(void) const {return doneSomething_;} + + /** @brief, force the host to set a clip's mapped component type to be \em comps. + + Only callable on non optional clips in all contexts. Must set comps to be one of the types the effect says it supports on the given clip. + + See the OFX API documentation for the default values of this. + */ + void setClipComponents(Clip &clip, PixelComponentEnum comps); + + /** @brief, force the host to set a clip's mapped bit depth be \em bitDepth + + Only callable if the OFX::ImageEffectHostDescription::supportsMultipleClipDepths is true. + + See the OFX API documentation for the default values of this. + */ + void setClipBitDepth(Clip &clip, BitDepthEnum bitDepth); + + /** @brief, force the host to set a clip's mapped Pixel Aspect Ratio to be \em PAR + + Only callable if the OFX::ImageEffectHostDescription::supportsMultipleClipPARs is true. + + Default is up to the host, generally based on the input clips. + + Not supported by most host applications. + */ + void setPixelAspectRatio(Clip &clip, double PAR); + + /** @brief Allows an effect to change the output frame rate + + Only callable if OFX::ImageEffectHostDescription::supportsSetableFrameRate is true. + + Default is controlled by the host, typically the framerate of the input clips. + */ + void setOutputFrameRate(double v); + + /** @brief Set the premultiplication state of the output clip. + + Defaults to the premultiplication state of ??? + */ + void setOutputPremultiplication(PreMultiplicationEnum v); + + /** @brief Set whether the effect can be continously sampled. + + Defaults to false. + */ + void setOutputHasContinousSamples(bool v); + + /** @brief Sets whether the effect will produce different images in all frames, even if the no params or input images are varying (eg: a noise generator). + + Defaults to false. + */ + void setOutputFrameVarying(bool v); + + /** @brief Sets the output fielding + + Default is host dependent, must be one of + - eFieldNone, + - eFieldLower, + - eFieldUpper + */ + void setOutputFielding(FieldEnum v); + }; + + /** @brief POD data structure passing in the instance changed args */ + struct InstanceChangedArgs { + InstanceChangeReason reason; /**< @brief why did it change */ + double time; /**< time of the change */ + OfxPointD renderScale; /**< the renderscale on the instance */ + }; + + /** @brief struct to pass arguments into @ref OFX::ImageEffect::interpolateCustomParam. + It is non-POD (it contains std::string), but it is passed as const ref, so that does + not matter */ + struct InterpolateCustomArgs { + double time; + std::string value1; + std::string value2; + double keytime1; + double keytime2; + double amount; + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an effect instance, plugin implementations need to inherit from this */ + class ImageEffect : public ParamSet + { + protected : + mDeclareProtectedAssignAndCCBase(ImageEffect,ParamSet); + + private : + /** @brief to get access to the effect handle without exposing it generally via a function */ + friend class ImageMemory; + + /** @brief The effect handle */ + OfxImageEffectHandle _effectHandle; + + /** @brief properties for this clip */ + PropertySet _effectProps; + + /** @brief the context of the effect */ + ContextEnum _context; + + /** @brief Set of all previously defined parameters, defined on demand */ + std::map _fetchedClips; + + /** @brief the overlay interacts that are open on this image effect */ + std::list _overlayInteracts; + + /** @brief cached result of whether progress start succeeded. */ + bool _progressStartSuccess; + public : + /** @brief ctor */ + ImageEffect(OfxImageEffectHandle handle); + + /** @brief dtor */ + virtual ~ImageEffect(); + + const PropertySet &getPropertySet() const {return _effectProps;} + + PropertySet &getPropertySet() {return _effectProps;} + + + OfxImageEffectHandle getHandle(void) const {return _effectHandle;} + + /** @brief the context this effect was instantiate in */ + ContextEnum getContext(void) const; + + /** @brief size of the project */ + OfxPointD getProjectSize(void) const; + + /** @brief origin of the project */ + OfxPointD getProjectOffset(void) const; + + /** @brief extent of the project */ + OfxPointD getProjectExtent(void) const; + + /** @brief pixel aspect ratio of the project */ + double getProjectPixelAspectRatio(void) const; + + /** @brief how long does the effect last */ + double getEffectDuration(void) const; + + /** @brief the frame rate of the project */ + double getFrameRate(void) const; + + /** @brief is the instance currently being interacted with */ + bool isInteractive(void) const; + + /** @brief set the instance to be sequentially renderred, this should have been part of clip preferences! */ + void setSequentialRender(bool v); + + /** @brief Have we informed the host we want to be seqentially renderred ? */ + bool getSequentialRender(void) const; + + /** @brief Does the plugin support image tiling ? Can only be called from changedParam or changedClip. */ + void setSupportsTiles(bool v); + + /** @brief Have we informed the host we support image tiling ? */ + bool getSupportsTiles(void) const; + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief Does the plugin support OpenGL accelerated rendering (but is also capable of CPU rendering) ? Can only be called from changedParam or changedClip. */ + void setSupportsOpenGLRender(bool v); + + /** @brief Does the plugin require OpenGL accelerated rendering ? Can only be called from changedParam or changedClip. */ + void setNeedsOpenGLRender(bool v); +#endif + + /** @brief notify host that the internal data structures need syncing back to parameters for persistance and so on. This is reset by the host after calling SyncPrivateData. */ + void setParamSetNeedsSyncing(); + + OFX::Message::MessageReplyEnum sendMessage(OFX::Message::MessageTypeEnum type, const std::string& id, const std::string& msg); + + OFX::Message::MessageReplyEnum setPersistentMessage(OFX::Message::MessageTypeEnum type, const std::string& id, const std::string& msg); + OFX::Message::MessageReplyEnum clearPersistentMessage(); + + /** @brief Fetch the named clip from this instance + + The returned clip \em must not be deleted by the client code. This is all managed by the ImageEffect itself. + */ + Clip *fetchClip(const std::string &name); + + /** @brief does the host want us to abort rendering? */ + bool abort(void) const; + + /** @brief adds a new interact to the set of interacts open on this effect */ + void addOverlayInteract(OverlayInteract *interact); + + /** @brief removes an interact to the set of interacts open on this effect */ + void removeOverlayInteract(OverlayInteract *interact); + + /** @brief force all overlays on this interact to be redrawn */ + void redrawOverlays(void); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + bool flushOpenGLResources(void); +#endif + + //////////////////////////////////////////////////////////////////////////////// + // these are actions that need to be overridden by a plugin that implements an effect host + + /** @brief The purge caches action, a request for an instance to free up as much memory as possible in low memory situations */ + virtual void purgeCaches(void); + + /** @brief The sync private data action, called when the effect needs to sync any private data to persistant parameters */ + virtual void syncPrivateData(void); + + /** @brief client render function, this is one of the few that must be overridden */ + virtual void render(const RenderArguments &args) = 0; + + /** @brief client begin sequence render function */ + virtual void beginSequenceRender(const BeginSequenceRenderArguments &args); + + /** @brief client end sequence render function */ + virtual void endSequenceRender(const EndSequenceRenderArguments &args); + + /** @brief client is identity function, returns the clip and time for the identity function + + If the effect would do no processing for the given param set and render arguments, then this + function should return true and set the \em identityClip pointer to point to the clip that is the identity + and \em identityTime to be the time at which to access the clip for the identity operation. + */ + virtual bool isIdentity(const IsIdentityArguments &args, Clip * &identityClip, double &identityTime); + + /** @brief The get RoD action. + + If the effect wants change the rod from the default value (which is the union of RoD's of all input clips) + it should set the \em rod argument and return true. + + This is all in cannonical coordinates. + */ + virtual bool getRegionOfDefinition(const RegionOfDefinitionArguments &args, OfxRectD &rod); + + /** @brief the get region of interest action + + If the effect wants change its region of interest on any input clip from the default values (which is the same as the RoI in the arguments) + it should do so by calling the OFX::RegionOfInterestSetter::setRegionOfInterest function on the \em rois argument. + + Note, everything is in \em cannonical \em coordinates. + */ + virtual void getRegionsOfInterest(const RegionsOfInterestArguments &args, RegionOfInterestSetter &rois); + + /** @brief the get frames needed action + + If the effect wants change the frames needed on an input clip from the default values (which is the same as the frame to be renderred) + it should do so by calling the OFX::FramesNeededSetter::setFramesNeeded function on the \em frames argument. + */ + virtual void getFramesNeeded(const FramesNeededArguments &args, FramesNeededSetter &frames); + + /** @brief get the clip preferences */ + virtual void getClipPreferences(ClipPreferencesSetter &clipPreferences); + + /** @brief the effect is about to be actively edited by a user, called when the first user interface is opened on an instance */ + virtual void beginEdit(void); + + /** @brief the effect is no longer being edited by a user, called when the last user interface is closed on an instance */ + virtual void endEdit(void); + + /** @brief the effect is about to have some values changed */ + virtual void beginChanged(InstanceChangeReason reason); + + /** @brief called when a param has just had its value changed */ + virtual void changedParam(const InstanceChangedArgs &args, const std::string ¶mName); + + /** @brief called when a clip has just been changed in some way (a rewire maybe) */ + virtual void changedClip(const InstanceChangedArgs &args, const std::string &clipName); + + /** @brief the effect has just had some values changed */ + virtual void endChanged(InstanceChangeReason reason); + + /** @brief called when a custom param needs to be interpolated */ + virtual std::string interpolateCustomParam(const InterpolateCustomArgs &args, const std::string ¶mName); + + /** @brief what is the time domain of this effect, valid only in the general context + + return true is range was set, otherwise the default (the union of the time domain of all input clips) is used + */ + virtual bool getTimeDomain(OfxRangeD &range); + +#ifdef OFX_SUPPORTS_OPENGLRENDER + /** @brief OpenGL context attached */ + virtual void contextAttached(void); + + /** @brief OpenGL context detached */ + virtual void contextDetached(void); +#endif + + /// Start doing progress. + void progressStart(const std::string &message, const std::string &messageid = ""); + + /// finish yer progress + void progressEnd(); + + /// set the progress to some level of completion, returns + /// false if you should abandon processing, true to continue + bool progressUpdate(double t); + + /// get the current time on the timeline. This is not necessarily the same + /// time as being passed to an action (eg render) + double timeLineGetTime(); + + /// set the timeline to a specific time + void timeLineGotoTime(double t); + + /// get the first and last times available on the effect's timeline + void timeLineGetBounds(double &t1, double &t2); + }; + + + //////////////////////////////////////////////////////////////////////////////// + /** @brief The OFX::Plugin namespace. All the functions in here needs to be defined by each plugin that uses the support libs. + */ + namespace Plugin { + /** @brief Plugin side function used to identify the plugin to the support library */ + void getPluginIDs(OFX::PluginFactoryArray &id); + + /// If the client has defined its own exception type, allow it to catch it in the main function +#ifdef OFX_CLIENT_EXCEPTION_TYPE + OfxStatus catchException(OFX_CLIENT_EXCEPTION_TYPE &ex); +#endif + }; + +}; + +// undeclare the protected assign and CC macro +#undef mDeclareProtectedAssignAndCC +#undef mDeclareProtectedAssignAndCCBase + +#endif diff --git a/third_party/openfx/Support/include/ofxsInteract.h b/third_party/openfx/Support/include/ofxsInteract.h new file mode 100644 index 000000000..8d2feca38 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsInteract.h @@ -0,0 +1,286 @@ + + +#ifndef _ofxsInteract_H_ +#define _ofxsInteract_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +/** @file This file contains core code that wraps OFX 'objects' with C++ classes. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. +*/ +#include "ofxsParam.h" + +#include + +/** @brief Nasty macro used to define empty protected copy ctors and assign ops */ +#define mDeclareProtectedAssignAndCC(CLASS) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &) {assert(false); } + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. +*/ +namespace OFX { + + /** @brief forward declaration */ + class ImageEffect; + + /// all image effect interacts have these argumens + struct InteractArgs { + /// ctor + InteractArgs(const PropertySet &props); + double time; /**< @brief The current effect time to draw at */ + OfxPointD renderScale; /**< @brief The current render scale being applied to any image that would be fetched */ + }; + + /** @brief struct to pass arguments into OFX::Interact::draw */ + struct DrawArgs : public InteractArgs { + DrawArgs(const PropertySet &props); + +#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4 + OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */ +#endif + OfxPointD pixelScale; /**< @brief The current effect time to draw at */ + OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */ + }; + + /** @brief POD to pass arguments into OFX::Interact pen actions */ + struct PenArgs : public InteractArgs { + PenArgs(const PropertySet &props); + +#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4 + OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */ +#endif + OfxPointD pixelScale; /**< @brief The current effect time to draw at */ + OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */ + OfxPointD penPosition; /**< @brief The current pen position */ + OfxPointD penViewportPosition;/**< @brief The current pen position in viewport coordinates */ + double penPressure; /**< @brief The normalised pressure on the pen */ + }; + + /** @brief struct to pass arguments into OFX::Interact key actions + + Note + - some keys cannot be represented as UTF8 strings (eg: the key pad page down key kOfxKey_KP_Page_Up), in which case the key string will be set to "". + - some UTF8 symbols (generally non-English language ones) cannot be represented by one of the keySymbols, in which case the UTF8 string will be set to some non empty value, but the keySymbol will be set to kOfxKey_Unknown. + - in no case will keyString be set to "" and keySymbol be set to kOfxKey_Unknown. + */ + struct KeyArgs : public InteractArgs { + KeyArgs(const PropertySet &props); + + int keySymbol; /**< @brief The key represented as one of the entries in ofxKeySyms.h, see note in OFX::KeyArgs */ + std::string keyString; /**< @brief That key as a UTF8 string, see note in OFX::KeyArgs */ + }; + + /** @brief struct to pass arguments into OFX::Interact focus actions */ + struct FocusArgs : public InteractArgs { + FocusArgs(const PropertySet &props); + + OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */ + OfxPointD pixelScale; /**< @brief The current effect time to draw at */ + OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */ + }; + + /** @brief Wraps up an OFX interact object for an Image Effect. It won't work for any other plug-in type at present (it would need to be broken into a hierarchy of classes). + */ + class Interact { + protected : + OfxInteractHandle _interactHandle; /**< @brief The handle for this interact */ + PropertySet _interactProperties; /**< @brief The property set on this interact */ + std::list _slaveParams; /**< @brief List of params we are currently slaved to */ + ImageEffect *_effect; /**< @brief The instance we are associated with */ + + public : + /** @brief ctor */ + Interact(OfxInteractHandle handle); + + /** @brief virtual destructor */ + virtual ~Interact(); + + PropertySet &getProperties() { return _interactProperties; } + + /** @brief The bitdepth of each component in the openGL frame buffer */ + int getBitDepth(void) const; + + /** @brief Does the openGL frame buffer have an alpha */ + bool hasAlpha(void) const; + + /** @brief Returns the size of a real screen pixel under the interact's cannonical projection */ + OfxPointD getPixelScale(void) const; + + /** @brief The suggested colour to draw a widget in an interact. Returns false if there is no suggestion. */ + bool getSuggestedColour(OfxRGBColourD &c) const; + + /** @brief the background colour */ + OfxRGBColourD getBackgroundColour(void) const; + + /** @brief Set a param that the interact should be redrawn on if its value changes */ + void addParamToSlaveTo(Param *p); + + /** @brief Remova a param that the interact should be redrawn on if its value changes */ + void removeParamToSlaveTo(Param *p); + + /** @brief Request a redraw */ + void requestRedraw(void) const; + + /** @brief Swap a buffer in the case of a double bufferred interact, this is possibly a silly one */ + void swapBuffers(void) const; + + //////////////////////////////////////////////////////////////////////////////// + // override the below in derived classes to do something useful + + /** @brief the function called to draw in the interact */ + virtual bool draw(const DrawArgs &args); + + /** @brief the function called to handle pen motion in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool penMotion(const PenArgs &args); + + /** @brief the function called to handle pen down events in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool penDown(const PenArgs &args); + + /** @brief the function called to handle pen up events in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool penUp(const PenArgs &args); + + /** @brief the function called to handle key down events in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool keyDown(const KeyArgs &args); + + /** @brief the function called to handle key up events in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool keyUp(const KeyArgs &args); + + /** @brief the function called to handle key down repeat events in the interact + + returns true if the interact trapped the action in some sense. This will block the action being passed to + any other interact that may share the viewer. + */ + virtual bool keyRepeat(const KeyArgs &args); + + /** @brief Called when the interact is given input focus */ + virtual void gainFocus(const FocusArgs &args); + + /** @brief Called when the interact is loses input focus */ + virtual void loseFocus(const FocusArgs &args); + }; + + /** @brief an interact for an image effect overlay */ + class OverlayInteract : public Interact { + public : + /** @brief ctor */ + OverlayInteract(OfxInteractHandle handle); + + /** @brief dtor */ + virtual ~OverlayInteract(); + }; + + class InteractDescriptor + { + public: + InteractDescriptor():_props(0) {} + virtual ~InteractDescriptor() {} + void setPropertySet(OFX::PropertySet* props){ _props = props; } + virtual Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) = 0; + void setHasAlpha(); + bool getHasAlpha() const; + void setBitDepth(); + int getBitDepth() const; + virtual OfxPluginEntryPoint* getMainEntry() = 0; + virtual void describe() {} + protected: + OFX::PropertySet* _props; + }; + + typedef InteractDescriptor EffectOverlayDescriptor; + + class ParamInteractDescriptor : public InteractDescriptor + { + public: + ParamInteractDescriptor():InteractDescriptor(){} + virtual ~ParamInteractDescriptor() {} + void setInteractSizeAspect(double asp); + void setInteractMinimumSize(int x, int y); + void setInteractPreferredSize(int x, int y); + virtual void setParamName(const std::string& pName) { _paramName = pName; } + protected: + std::string _paramName; + }; + + class ParamInteract : public Interact + { + public: + ParamInteract(OfxInteractHandle handle, ImageEffect* effect); + virtual ~ParamInteract() {} + double getInteractSizeAspect() const; + OfxPointI getInteractMinimumSize() const; + OfxPointI getInteractPreferredSize() const; + OfxPointI getInteractSize() const; + protected: + ImageEffect* _effect; + }; + + namespace Private + { + OfxStatus interactMainEntry(const char *actionRaw, + const void *handleRaw, + OfxPropertySetHandle inArgsRaw, + OfxPropertySetHandle outArgsRaw, + InteractDescriptor& desc); + } + + template + class InteractMainEntry + { + protected: + static OfxStatus overlayInteractMainEntry(const char *action, const void* handle, OfxPropertySetHandle in, OfxPropertySetHandle out) + { + static DESC desc; + return OFX::Private::interactMainEntry(action, handle, in, out, desc); + } + }; + + template + class DefaultEffectOverlayDescriptor : public EffectOverlayDescriptor, public InteractMainEntry + { + public: + Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) { return new INSTANCE(handle, effect); } + virtual OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry::overlayInteractMainEntry; } + }; + + template + class DefaultParamInteractDescriptor : public ParamInteractDescriptor, public InteractMainEntry + { + public: + Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) { return new INSTANCE(handle, effect, _paramNameStatic); } + virtual OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry::overlayInteractMainEntry; } + virtual void setParamName(const std::string& pName) { _paramNameStatic = pName; } + protected: + static std::string _paramNameStatic; + }; + + template std::string OFX::DefaultParamInteractDescriptor::_paramNameStatic; +}; + + +#undef mDeclareProtectedAssignAndCC + +#endif + diff --git a/third_party/openfx/Support/include/ofxsLog.h b/third_party/openfx/Support/include/ofxsLog.h new file mode 100644 index 000000000..1a78e975b --- /dev/null +++ b/third_party/openfx/Support/include/ofxsLog.h @@ -0,0 +1,43 @@ + + +#ifndef _ofxsLog_H_ +#define _ofxsLog_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +/** @file This file contains OFX logging header code +*/ + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. +*/ +namespace OFX { + + /** @brief this namespace wraps up logging functionality */ + namespace Log { + /** @brief Indent it, not MP sane at the moment */ + void indent(void); + + /** @brief Outdent it, not MP sane at the moment */ + void outdent(void); + + /** @brief Sets the name of the log file. */ + void setFileName(const std::string &value); + + /** @brief Opens the log file, returns whether this was sucessful or not. */ + bool open(void); + + /** @brief Closes the log file. */ + void close(void); + + /** @brief Prints to the log file. */ + void print(const char *format, ...); + + /** @brief Prints to the log file only if the condition is true and prepends a warning notice. */ + void warning(bool condition, const char *format, ...); + + /** @brief Prints to the log file only if the condition is true and prepends an error notice. */ + void error(bool condition, const char *format, ...); + }; +}; + +#endif diff --git a/third_party/openfx/Support/include/ofxsMemory.h b/third_party/openfx/Support/include/ofxsMemory.h new file mode 100644 index 000000000..b73a24951 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsMemory.h @@ -0,0 +1,45 @@ + + +#ifndef _ofxsMemory_H_ +#define _ofxsMemory_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +/** @file This file contains core code that wraps the ofx memory allocator with C++ functions. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. +*/ + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. +*/ +namespace OFX { + + // forward declaration of class + class ImageEffect; + + /** @brief Namespace for general purpose memory allocation */ + namespace Memory { + /** @brief Allocate memory. + + \arg \e nBytes - the number of bytes to allocate + \arg \e handle - effect instance to assosciate with this memory allocation, or NULL + + This function has the host allocate memory using it's own memory resources + and returns that to the plugin. This memory is distinct to any image memory allocation. + + Succeeds or throws std::bad_alloc + */ + void *allocate(size_t nBytes, + ImageEffect *handle = 0); + + /** @brief release memory + + \arg \e ptr - pointer previously returned by OFX::Memory::allocate + */ + void free(void *ptr) noexcept; + }; + +}; + +#endif diff --git a/third_party/openfx/Support/include/ofxsMessage.h b/third_party/openfx/Support/include/ofxsMessage.h new file mode 100644 index 000000000..648814cd9 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsMessage.h @@ -0,0 +1,30 @@ + + +#ifndef _ofxsMessage_H_ +#define _ofxsMessage_H_ + +namespace OFX +{ + namespace Message + { + enum MessageReplyEnum + { + eMessageReplyOK, + eMessageReplyYes, + eMessageReplyNo, + eMessageReplyFailed + }; + + enum MessageTypeEnum + { + eMessageFatal, + eMessageError, + eMessageMessage, + eMessageWarning, + eMessageLog, + eMessageQuestion + }; + }; +}; + +#endif diff --git a/third_party/openfx/Support/include/ofxsMultiThread.h b/third_party/openfx/Support/include/ofxsMultiThread.h new file mode 100644 index 000000000..757996ba5 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsMultiThread.h @@ -0,0 +1,106 @@ + + +#ifndef _ofxsMultiThread_H_ +#define _ofxsMultiThread_H_ +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +/** @file This file contains core code that wraps OFX 'objects' with C++ classes. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. +*/ + +#include "ofxsCore.h" + +typedef struct OfxMutex* OfxMutexHandle; + +namespace OFX { + + /** @brief Multi thread namespace */ + namespace MultiThread { + + /** @brief Class that wraps up SMP multi-processing */ + class Processor { + private : + /** @brief Function to pass to the multi thread suite */ + static void staticMultiThreadFunction(unsigned int threadIndex, unsigned int threadMax, void *customArg); + + public : + /** @brief ctor */ + Processor(); + + /** @brief dtor */ + virtual ~Processor(); + + /** @brief function that will be called in each thread. ID is from 0..nThreads-1 nThreads are the number of threads it is being run over */ + virtual void multiThreadFunction(unsigned int threadID, unsigned int nThreads) = 0; + + /** @brief call this to kick off multi threading + + The nCPUs is 0, the maximum allowable number of CPUs will be used. + */ + virtual void multiThread(unsigned int nCPUs = 0); + }; + + /** @brief Has the current thread been spawned from an MP */ + bool isSpawnedThread(void); + + /** @brief The number of CPUs that can be used for MP-ing */ + unsigned int getNumCPUs(void); + + /** @brief The index of the current thread. From 0 to numCPUs() - 1 */ + unsigned int getThreadIndex(void); + + /** @brief An OFX mutex */ + class Mutex { + protected : + OfxMutexHandle _handle; /**< @brief The handle */ + + public : + /** @brief ctor */ + Mutex(int lockCount = 0); + + /** @brief dtor */ + virtual ~Mutex(void); + + /** @brief lock it, blocks until lock is gained */ + void lock(); + + /** @brief unlock it */ + void unlock(); + + /** @brief attempt to lock, non-blocking + + \brief returns + - true if the lock was achieved + - false if it could not + */ + bool tryLock(); + }; + + /// a class to wrap around a mutex which is exception safe + /// it locks the mutex on construction and unlocks it on destruction + class AutoMutex { + protected : + Mutex &_mutex; + + public : + /// ctor, acquires the lock + explicit AutoMutex(Mutex &m) + : _mutex(m) + { + _mutex.lock(); + } + + /// dtor, releases the lock + virtual ~AutoMutex() + { + _mutex.unlock(); + } + + }; + }; +}; + +#endif diff --git a/third_party/openfx/Support/include/ofxsParam.h b/third_party/openfx/Support/include/ofxsParam.h new file mode 100644 index 000000000..7603b81a3 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsParam.h @@ -0,0 +1,1868 @@ + + +#ifndef _ofxsParam_H_ +#define _ofxsParam_H_ + +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + + +/** @file This file contains core code that wraps OFX parameters with C++ classes. + +This file only holds code that is visible to a plugin implementation, and so hides much +of the direct OFX objects and any library side only functions. + +The classes that skin parameters are broken into two sets, those used during the description phase, +eg OFX::IntParamDescriptor and those representing instances eg, OFX::IntParamInstance. The members on +each represent the actions that can be carried out on those particular OFX objects. + + */ + +#include +#include +#include "ofxsCore.h" + +/** @brief Nasty macro used to define empty protected copy ctors and assign ops */ +#define mDeclareProtectedAssignAndCC(CLASS) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &) {assert(false); } +#define mDeclareProtectedAssignAndCCBase(CLASS,BASE) \ + CLASS &operator=(const CLASS &) {assert(false); return *this;} \ + CLASS(const CLASS &c) : BASE(c) {assert(false); } + +/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. + */ +namespace OFX { + + class ParamInteractDescriptor; + /* forward class declarations of the descriptors */ + class ParamDescriptor; + class ValueParamDescriptor; + class IntParamDescriptor; + class Int2DParamDescriptor; + class Int3DParamDescriptor; + class DoubleParamDescriptor; + class Double2DParamDescriptor; + class Double3DParamDescriptor; + class StringParamDescriptor; + class RGBAParamDescriptor; + class RGBParamDescriptor; + class BooleanParamDescriptor; + class ChoiceParamDescriptor; + class StrChoiceParamDescriptor; + class GroupParamDescriptor; + class PageParamDescriptor; + class PushButtonParamDescriptor; + class CustomParamDescriptor; + class ParamSetDescriptor; + + /* forward class declarations of the instances */ + class Param; + class ValueParam; + class IntParam; + class Int2DParam; + class Int3DParam; + class DoubleParam; + class Double2DParam; + class Double3DParam; + class RGBAParam; + class RGBParam; + class StringParam; + class BooleanParam; + class ChoiceParam; + class StrChoiceParam; + class CustomParam; + class GroupParam; + class PageParam; + class PushButtonParam; + class ParamSet; + + + /** @brief Enumerates the different types of parameter */ + enum ParamTypeEnum {eDummyParam, + eStringParam, + eIntParam, + eInt2DParam, + eInt3DParam, + eDoubleParam, + eDouble2DParam, + eDouble3DParam, + eRGBParam, + eRGBAParam, + eBooleanParam, + eChoiceParam, + eStrChoiceParam, + eCustomParam, + eGroupParam, + ePageParam, + ePushButtonParam, + eParametricParam, + }; + + /** @brief Enumerates the different types of cache invalidation */ + enum CacheInvalidationEnum {eCacheInvalidateValueChange, + eCacheInvalidateValueChangeToEnd, + eCacheInvalidateValueAll}; + + /** @brief Enumerates how we search for keys in an animating parameter */ + enum KeySearchEnum {eKeySearchBackwards, + eKeySearchNear, + eKeySearchForwards}; + + /** @brief Enumerates the differing types of string params */ + enum StringTypeEnum { + eStringTypeSingleLine, + eStringTypeMultiLine, + eStringTypeFilePath, + eStringTypeDirectoryPath, + eStringTypeLabel, + eStringTypeRichTextFormat + }; + + /** @brief Enumerates the differing types of double params */ + enum DoubleTypeEnum { + eDoubleTypePlain, //!< parameter has no special interpretation + eDoubleTypeAngle, //!< parameter is to be interpretted as an angle + eDoubleTypeScale, //!< parameter is to be interpretted as a scale factor + eDoubleTypeTime, //!< parameter represents a time value (1D only) + eDoubleTypeAbsoluteTime, //!< parameter represents an absolute time value (1D only), + eDoubleTypeX, //!< a size in the X dimension dimension (1D only), new for 1.2 + eDoubleTypeXAbsolute, //!< a position in the X dimension (1D only), new for 1.2 + eDoubleTypeY, //!< a size in the Y dimension dimension (1D only), new for 1.2 + eDoubleTypeYAbsolute, //!< a position in the X dimension (1D only), new for 1.2 + eDoubleTypeXY, //!< a size in the X and Y dimension (2D only), new for 1.2 + eDoubleTypeXYAbsolute, //!< a position in the X and Y dimension (2D only), new for 1.2 +#ifdef kOfxParamDoubleTypeNormalisedX + eDoubleTypeNormalisedX, //!< normalised size with respect to the project's X dimension (1D only), deprecated for 1.2 + eDoubleTypeNormalisedY, //!< normalised absolute position on the X axis (1D only), deprecated for 1.2 + eDoubleTypeNormalisedXAbsolute, //!< normalised size wrt to the project's Y dimension (1D only), deprecated for 1.2 + eDoubleTypeNormalisedYAbsolute, //!< normalised absolute position on the Y axis (1D only), deprecated for 1.2 + eDoubleTypeNormalisedXY, //!< normalised to the project's X and Y size (2D only), deprecated for 1.2 + eDoubleTypeNormalisedXYAbsolute, //!< normalised to the projects X and Y size, and is an absolute position on the image plane, deprecated for 1.2 +#endif + }; + + /** @brief Enumerates the differing types of coordinate system for default values */ + enum DefaultCoordinateSystemEnum { + eCoordinatesCanonical, //!< canonical coordinate system + eCoordinatesNormalised, //!< normalized coordinate system + }; + + /** @brief turns a ParamTypeEnum into the char * that raw OFX uses */ + const char * + mapParamTypeEnumToString(ParamTypeEnum v); + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Base class for all param descriptors */ + class ParamDescriptor { + protected : + mDeclareProtectedAssignAndCC(ParamDescriptor); + ParamDescriptor(void) {assert(false);} + + protected : + std::string _paramName; + ParamTypeEnum _paramType; + PropertySet _paramProps; + + /** @brief hidden constructors */ + ParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + public : + /** @brief dtor */ + virtual ~ParamDescriptor(); + + ParamTypeEnum getType(void) const {return _paramType;} + + /** @brief name */ + const std::string &getName(void) const {return _paramName;} + + /** @brief Get the property set */ + PropertySet &getPropertySet() + { + return _paramProps; + } + + + /** @brief set the label property in a param */ + void setLabel(const std::string &label); + + /** @brief set the label properties in a param */ + void setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel); + + /** @brief set the param hint */ + void setHint(const std::string &hint); + + /** @brief set the script name, default is the name it was created with */ + void setScriptName(const std::string &hint); + + /** @brief set the secretness of the param, defaults to false */ + void setIsSecret(bool v); + + /** @brief set the group param that is the parent of this one, default is to be ungrouped at the root level */ + void setParent(const GroupParamDescriptor &v); + + /** @brief set the icon file name (SVG or PNG) */ + void setIcon(const std::string &v, bool pngFormat); + + /** @brief whether the param is enabled, defaults to true */ + void setEnabled(bool v); + + bool getHostHasNativeOverlayHandle() const; + + void setUseHostNativeOverlayHandle(bool use); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Used to implement dummy parameters for page positioning commands */ + class DummyParamDescriptor : public ParamDescriptor { + public : + /** @brief ctor */ + DummyParamDescriptor(const std::string &name) + : ParamDescriptor(name, eDummyParam, 0) + {} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a value holding param */ + class ValueParamDescriptor : public ParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(ValueParamDescriptor,ParamDescriptor); + ValueParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + ValueParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + std::unique_ptr _interact; + public : + /** @brief dtor */ + ~ValueParamDescriptor(); + + /** @brief set whether the param can animate, defaults to true in most cases */ + void setAnimates(bool v); + + /** @brief set whether the param is persistant, defaults to true */ + void setIsPersistant(bool v); + + /** @brief Set's whether the value of the param is significant (ie: affects the rendered image), defaults to true */ + void setEvaluateOnChange(bool v); + + /** @brief Set's how any cache should be invalidated if the parameter is changed, defaults to eCacheInvalidateValueChange */ + void setCacheInvalidation(CacheInvalidationEnum v); + + /// @brief Set whether the param should appear on any undo stack + void setCanUndo(bool v); + + void setInteractDescriptor(ParamInteractDescriptor* desc); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a string param */ + class StringParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(StringParamDescriptor,ValueParamDescriptor); + StringParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + StringParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the default value, default is 0 */ + void setDefault(const std::string &v); + + /** @brief sets the kind of the string param, defaults to eStringSingleLine */ + void setStringType(StringTypeEnum v); + + /** @brief if the string param is a file path, say that we are picking an existing file, rather than posibly specifying a new one, defaults to true */ + void setFilePathExists(bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an integer param */ + class IntParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(IntParamDescriptor,ValueParamDescriptor); + IntParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + IntParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the default value, default is 0 */ + void setDefault(int v); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int min, int max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int min, int max); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an 2d integer param */ + class Int2DParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(Int2DParamDescriptor,ValueParamDescriptor); + Int2DParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Int2DParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &x, + const std::string &y); + + /** @brief set the default value, default is 0 */ + void setDefault(int x, int y); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int minX, int minY, + int maxX, int maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int minX, int minY, + int maxX, int maxY); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an 3d integer param */ + class Int3DParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(Int3DParamDescriptor,ValueParamDescriptor); + Int3DParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Int3DParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &x, + const std::string &y, + const std::string &z); + + /** @brief set the default value, default is 0 */ + void setDefault(int x, int y, int z); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int minX, int minY, int minZ, + int maxX, int maxY, int maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int minX, int minY, int minZ, + int maxX, int maxY, int maxZ); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Common base to all double param types */ + class BaseDoubleParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(BaseDoubleParamDescriptor,ValueParamDescriptor); + BaseDoubleParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + BaseDoubleParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + public : + /** @brief set the type of the double param, defaults to eDoubleTypePlain */ + void setDoubleType(DoubleTypeEnum v); + + /** @brief set the type of coordinate system for default values */ + void setDefaultCoordinateSystem(DefaultCoordinateSystemEnum v); + + /** @brief set the sensitivity of any gui slider */ + void setIncrement(double v); + + /** @brief set the number of digits printed after a decimal point in any gui */ + void setDigits(int v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a double param */ + class DoubleParamDescriptor : public BaseDoubleParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(DoubleParamDescriptor,BaseDoubleParamDescriptor); + DoubleParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + DoubleParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief if the double type is Absolute time, show a time marker on the time line if possible */ + void setShowTimeMarker(bool v); + + /** @brief set the default value, default is 0 */ + void setDefault(double v); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(double min, double max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double min, double max); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a 2D double param */ + class Double2DParamDescriptor : public BaseDoubleParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(Double2DParamDescriptor,BaseDoubleParamDescriptor); + Double2DParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Double2DParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &x, + const std::string &y); + + /** @brief set kOfxParamPropUseHostOverlayHandle */ + void setUseHostOverlayHandle(bool v); + + /** @brief set the default value, default is 0 */ + void setDefault(double x, double y); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(double minX, double minY, + double maxX, double maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minX, double minY, + double maxX, double maxY); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a 3D double param */ + class Double3DParamDescriptor : public BaseDoubleParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(Double3DParamDescriptor,BaseDoubleParamDescriptor); + Double3DParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Double3DParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + friend class ParamSetDescriptor; + + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &x, + const std::string &y, + const std::string &z); + + /** @brief set the default value, default is 0 */ + void setDefault(double x, double y, double z); + + /** @brief set the hard min/max range, default is -DBL_MAX, DBL_MAX */ + void setRange(double minX, double minY, double minZ, + double maxX, double maxY, double maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minX, double minY, double minZ, + double maxX, double maxY, double maxZ); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an RGB colour param */ + class RGBParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(RGBParamDescriptor,ValueParamDescriptor); + RGBParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + RGBParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &r, + const std::string &g, + const std::string &b); + + /** @brief set the default value */ + void setDefault(double r, double g, double b); + + /** @brief set the hard min/max range, default is 0., 1. */ + void setRange(double minR, double minG, double minB, + double maxR, double maxG, double maxB); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minR, double minG, double minB, + double maxR, double maxG, double maxB); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an RGBA colour param */ + class RGBAParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(RGBAParamDescriptor,ValueParamDescriptor); + RGBAParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + RGBAParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief set the dimension labels */ + void setDimensionLabels(const std::string &r, + const std::string &g, + const std::string &b, + const std::string &a); + + /** @brief set the default value */ + void setDefault(double r, double g, double b, double a); + + /** @brief set the hard min/max range, default is 0., 1. */ + void setRange(double minR, double minG, double minB, double minA, + double maxR, double maxG, double maxB, double maxA); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minR, double minG, double minB, double minA, + double maxR, double maxG, double maxB, double maxA); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a boolean param */ + class BooleanParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(BooleanParamDescriptor,ValueParamDescriptor); + BooleanParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + BooleanParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief set the default value */ + void setDefault(bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a choice param */ + class ChoiceParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(ChoiceParamDescriptor,ValueParamDescriptor); + ChoiceParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + ChoiceParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief set the default value */ + void setDefault(int v); + + /** @brief append an option, default is to have not there */ + void appendOption(const std::string &v, const std::string& label = "", const int order = INT_MIN); + + /** @brief how many options do we have */ + int getNOptions(void); + + /** @brief clear all the options so as to add some new ones in */ + void resetOptions(void); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a string choice param */ + class StrChoiceParamDescriptor : public ValueParamDescriptor + { + protected : + mDeclareProtectedAssignAndCCBase(StrChoiceParamDescriptor, ValueParamDescriptor); + StrChoiceParamDescriptor() { assert(false); } + + protected : + /** @brief hidden constructor */ + StrChoiceParamDescriptor(const std::string& p_Name, OfxPropertySetHandle p_Props); + + // so it can make one + friend class ParamSetDescriptor; + + public : + /** @brief set the default value */ + void setDefault(const std::string& p_DefaultValue); + + /** @brief append an option */ + void appendOption(const std::string& p_Enum, const std::string& p_Option, int order = INT_MIN); + + /** @brief how many options do we have */ + int getNOptions(); + + /** @brief clear all the options so as to add some new ones in */ + void resetOptions(); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a group param, not much to it really */ + class GroupParamDescriptor : public ParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(GroupParamDescriptor,ParamDescriptor); + GroupParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + GroupParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief whether the initial state of a group is open or closed in a hierarchical layout, defaults to false */ + void setOpen(const bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a page param, not much to it really */ + class PageParamDescriptor : public ParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(PageParamDescriptor,ParamDescriptor); + PageParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + PageParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + + /** @brief adds a child parameter. Note the two existing pseudo params, gColumnSkip and gRowSkip */ + void addChild(const ParamDescriptor &p); + + /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */ + static DummyParamDescriptor gSkipRow; + + /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */ + static DummyParamDescriptor gSkipColumn; + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a push button param, not much to it at all */ + class PushButtonParamDescriptor : public ParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(PushButtonParamDescriptor,ParamDescriptor); + PushButtonParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + PushButtonParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a push button param, not much to it at all */ + class ParametricParamDescriptor : public ParamDescriptor + { + protected: + mDeclareProtectedAssignAndCCBase(ParametricParamDescriptor,ParamDescriptor); + ParametricParamDescriptor(void) {assert(false);} + + protected: + /** @brief hidden constructor */ + ParametricParamDescriptor(const std::string& name, OfxPropertySetHandle props); + + OfxParamHandle _ofxParamHandle; + ParamSetDescriptor* _paramSet; + std::unique_ptr _interact; + + // so it can make one + friend class ParamSetDescriptor; + void setParamSet( ParamSetDescriptor& paramSet ); + + public: + void setDimension( const int dimension ); + + void setRange( const double min, const double max ); + + void setDimensionLabel( const std::string& label, const int id ); + + void setUIColour( const int id, const OfxRGBColourD& color ); + + void addControlPoint( const int id, const OfxTime time, const double x, const double y, const bool addKey ); + + void setIdentity( const int id ); + + void setIdentity(); + + void setInteractDescriptor( ParamInteractDescriptor* desc ); + + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a custom param, haven't added animation support yet */ + class CustomParamDescriptor : public ValueParamDescriptor { + protected : + mDeclareProtectedAssignAndCCBase(CustomParamDescriptor,ValueParamDescriptor); + CustomParamDescriptor(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + CustomParamDescriptor(const std::string &name, OfxPropertySetHandle props); + + // so it can make one + friend class ParamSetDescriptor; + public : + /** @brief set the default value of the param */ + void setDefault(const std::string &v); + + void setCustomInterpolation(bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Describes a set of properties */ + class ParamSetDescriptor { + protected : + mDeclareProtectedAssignAndCC(ParamSetDescriptor); + + /** @brief calls the raw OFX routine to define a param */ + void defineRawParam(const std::string &name, ParamTypeEnum paramType, OfxPropertySetHandle &props); + + /** @brief Define a param descriptor of the given type */ + template bool + defineParamDescriptor(const std::string &name, ParamTypeEnum paramType, T * ¶mPtr) + { + paramPtr = NULL; + + // have we made it already in this param set and is it of the correct type + if(ParamDescriptor *param = findPreviouslyDefinedParam(name)) { + if(param->getType() == paramType) { + paramPtr = (T *) param; // could be a dynamic cast here + return true; + } + else + return false; // SHOULD THROW SOMETHING HERE!!!!!!! + } + else { + // ok define one and add it in + OfxPropertySetHandle props; + defineRawParam(name, paramType, props); + + // make out support descriptor class + paramPtr = new T(name, props); + + // add it to our map of described ones + _definedParams[name] = paramPtr; + } + return true; + } + + protected : + /** @brief Properties that belong to this param set */ + PropertySet _paramSetProps; + + /** @brief Parameter set handle */ + OfxParamSetHandle _paramSetHandle; + + /** @brief Set of all previously defined parameters, defined on demand */ + std::map _definedParams; + + /** @brief Hidden ctor */ + ParamSetDescriptor(void); + + /** @brief set the param set handle */ + void setParamSetHandle(OfxParamSetHandle h); + + /** @brief find a param in the map */ + ParamDescriptor *findPreviouslyDefinedParam(const std::string &name); + + public : + OfxParamSetHandle getParamSetHandle() + { + return _paramSetHandle; + } + + virtual ~ParamSetDescriptor(); + /** @brief tries to fetch a ParamDescriptor, returns 0 if it isn't there*/ + ParamDescriptor* getParamDescriptor(const std::string& name) const; + + /** @brief estabilishes the order of page params. Do it by calling it in turn for each page */ + void setPageParamOrder(PageParamDescriptor &p); + + /** @brief Define an integer param */ + IntParamDescriptor *defineIntParam(const std::string &name); + + /** @brief Define a 2D integer param */ + Int2DParamDescriptor *defineInt2DParam(const std::string &name); + + /** @brief Define a 3D integer param */ + Int3DParamDescriptor *defineInt3DParam(const std::string &name); + + /** @brief Define an double param */ + DoubleParamDescriptor *defineDoubleParam(const std::string &name); + + /** @brief Define a 2D double param */ + Double2DParamDescriptor *defineDouble2DParam(const std::string &name); + + /** @brief Define a 3D double param */ + Double3DParamDescriptor *defineDouble3DParam(const std::string &name); + + /** @brief Define a string param */ + StringParamDescriptor *defineStringParam(const std::string &name); + + /** @brief Define a RGBA param */ + RGBAParamDescriptor *defineRGBAParam(const std::string &name); + + /** @brief Define an RGB param */ + RGBParamDescriptor *defineRGBParam(const std::string &name); + + /** @brief Define a Boolean param */ + BooleanParamDescriptor *defineBooleanParam(const std::string &name); + + /** @brief Define a Choice param */ + ChoiceParamDescriptor *defineChoiceParam(const std::string &name); + + /** @brief Define a String Choice param */ + StrChoiceParamDescriptor* defineStrChoiceParam(const std::string& p_Name); + + /** @brief Define a group param */ + GroupParamDescriptor *defineGroupParam(const std::string &name); + + /** @brief Define a Page param */ + PageParamDescriptor *definePageParam(const std::string &name); + + /** @brief Define a push button param */ + PushButtonParamDescriptor *definePushButtonParam(const std::string &name); + + /** @brief Define a parametric param */ + ParametricParamDescriptor* defineParametricParam(const std::string &name); + + /** @brief Define a custom param */ + CustomParamDescriptor *defineCustomParam(const std::string &name); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Base class for all param instances */ + class Param { + protected : + // don't ever use these! + Param &operator=(const Param &/*v1*/) {assert(false); return *this;} + Param(const Param &v) : _paramSet(v._paramSet) {assert(false); } + Param(void) {assert(false);} + + protected : + const ParamSet *_paramSet; // who do I belong to + std::string _paramName; + ParamTypeEnum _paramType; + PropertySet _paramProps; + OfxParamHandle _paramHandle; + + /** @brief hidden constructor */ + Param(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief dtor */ + virtual ~Param(); + + /** @brief get name */ + const std::string &getName(void) const; + + /** @brief, set the label property in a param */ + void setLabel(const std::string &label); + + /** @brief, set the label properties in a param */ + void setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel); + + /** @brief return the derived type of this parameter */ + ParamTypeEnum getType(void) const {return _paramType;} + + /** @brief set the secretness of the param, defaults to false */ + void setIsSecret(bool v); + + /** @brief set the param hint */ + void setHint(const std::string &hint); + + /** @brief whether the param is enabled */ + void setEnabled(bool v); + + /** @brief set the param data ptr */ + void setDataPtr(void* ptr); + + /** @brief fetch the label */ + void getLabel(std::string &label) const; + + /** @brief fetch the labels */ + void getLabels(std::string &label, std::string &shortLabel, std::string &longLabel) const; + + /** @brief get whether the param is secret */ + bool getIsSecret(void) const; + + /** @brief whether the param is enabled */ + bool getIsEnable(void) const; + + /** @brief get the param data ptr */ + void* getDataPtr(void) const; + + /** @brief get the param hint */ + std::string getHint(void) const; + + /** @brief get the script name */ + std::string getScriptName(void) const; + + /** @brief get the group param that is the parent of this one */ + GroupParam *getParent(void) const; + + /** @brief get the icon file name (SVG or PNG) */ + std::string getIcon(bool pngFormat) const; + + bool getHostHasNativeOverlayHandle() const; + + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a value holding param */ + class ValueParam : public Param { + protected : + mDeclareProtectedAssignAndCCBase(ValueParam,Param); + ValueParam(void) {assert(false);} + protected : + /** @brief hidden constructor */ + ValueParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief dtor */ + ~ValueParam(); + + /** @brief Set's whether the value of the param is significant (ie: affects the rendered image) */ + void setEvaluateOnChange(bool v); + + /** @brief is the param animating */ + bool getIsAnimating(void) const; + + /** @brief is the param animating */ + bool getIsAutoKeying(void) const; + + /** @brief is the param animating */ + bool getIsPersistant(void) const; + + /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */ + bool getEvaluateOnChange(void) const; + + /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */ + CacheInvalidationEnum getCacheInvalidation(void) const; + + /** @brief if the param is animating, the number of keys in it, otherwise 0 */ + unsigned int getNumKeys(void); + + /** @brief get the time of the nth key, nth must be between 0 and getNumKeys-1 */ + double getKeyTime(int nthKey); + + /** @brief find the index of a key by a time */ + int getKeyIndex(double time, + KeySearchEnum searchDir); + + /** @brief deletes a key at the given time */ + void deleteKeyAtTime(double time); + + /** @brief delete all the keys */ + void deleteAllKeys(void); + + /** @brief copy parameter from another, including any animation etc... */ + void copyFrom(const ValueParam& from, OfxTime dstOffset, const OfxRangeD *frameRange); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an integer param */ + class IntParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(IntParam,ValueParam); + IntParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + IntParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value */ + void setDefault(int v); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int min, int max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int min, int max); + + /** @brief get the default value */ + void getDefault(int &v); + + /** @brief get the default value */ + int getDefault(void) {int v; getDefault(v); return v;} + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void getRange(int &min, int &max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(int &min, int &max); + + /** @brief get value */ + void getValue(int &v); + + /** @brief and a nicer one */ + int getValue(void) {int v; getValue(v); return v;} + + /** @brief get the value at a time */ + void getValueAtTime(double t, int &v); + + /** @brief and a nicer one */ + int getValueAtTime(double t) {int v; getValueAtTime(t, v); return v;} + + /** @brief set value */ + void setValue(int v); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, int v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an integer param */ + class Int2DParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(Int2DParam,ValueParam); + Int2DParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Int2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(int x, int y); + + /** @brief set the default value, default is 0 */ + void setDefault(const OfxPointI &v) {setDefault(v.x, v.y);} + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int minX, int minY, + int maxX, int maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int minX, int minY, + int maxX, int maxY); + + /** @brief get the default value */ + void getDefault(int &x, int &y); + + /** @brief get the default value */ + OfxPointI getDefault(void) {OfxPointI v; getDefault(v.x, v.y); return v;} + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void getRange(int &minX, int &minY, + int& maxX, int &maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(int &minX, int &minY, + int &maxX, int &maxY); + + /** @brief get value */ + void getValue(int &x, int &y); + + /** @brief get the value */ + OfxPointI getValue(void) {OfxPointI v; getValue(v.x, v.y); return v;} + + /** @brief get the value at a time */ + void getValueAtTime(double t, int &x, int &y); + + /** @brief get the value */ + OfxPointI getValueAtTime(double t) {OfxPointI v; getValueAtTime(t, v.x, v.y); return v;} + + /** @brief set value */ + void setValue(int x, int y); + + /** @brief set the current value */ + void setValue(const OfxPointI &v) {setValue(v.x, v.y);} + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, int x, int y); + + /** @brief set the current value */ + void setValueAtTime(double t, const OfxPointI &v) {setValueAtTime(t, v.x, v.y);} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an integer param */ + class Int3DParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(Int3DParam,ValueParam); + Int3DParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Int3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(int x, int y, int z); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void setRange(int minX, int minY, int minZ, + int maxX, int maxY, int maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(int minX, int minY, int minZ, + int maxX, int maxY, int maxZ); + + /** @brief get the default value */ + void getDefault(int &x, int &y, int &z); + + /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */ + void getRange(int &minX, int &minY, int &minZ, + int& maxX, int &maxY, int &maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(int &minX, int &minY, int &minZ, + int& maxX, int &maxY, int &maxZ); + + /** @brief get value */ + void getValue(int &x, int &y, int &z); + + /** @brief get the value at a time */ + void getValueAtTime(double t, int &x, int &y, int &z); + + /** @brief set value */ + void setValue(int x, int y, int z); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, int x, int y, int z); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Common base to all double param types */ + class BaseDoubleParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(BaseDoubleParam,ValueParam); + BaseDoubleParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + BaseDoubleParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the sensitivity of any gui slider */ + void setIncrement(double v); + + /** @brief set the number of digits printed after a decimal point in any gui */ + void setDigits(int v); + + /** @brief get the sensitivity of any gui slider */ + void getIncrement(double &v); + + /** @brief get the number of digits printed after a decimal point in any gui */ + void getDigits(int &v); + + /** @brief get the type of the double param */ + void getDoubleType(DoubleTypeEnum &v); + + /** @brief get the type of coordinate system for default values */ + void getDefaultCoordinateSystem(DefaultCoordinateSystemEnum &v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an doubleeger param */ + class DoubleParam : public BaseDoubleParam { + protected : + mDeclareProtectedAssignAndCCBase(DoubleParam,BaseDoubleParam); + DoubleParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + DoubleParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value */ + void setDefault(double v); + + /** @brief if the double type is Absolute time, show a time marker on the time line if possible */ + void setShowTimeMarker(bool v); + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void setRange(double min, double max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double min, double max); + + /** @brief get the default value */ + void getDefault(double &v); + + /** @brief get the default value */ + double getDefault(void) {double v; getDefault(v); return v;} + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void getRange(double &min, double &max); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(double &min, double &max); + + /** @brief get value */ + void getValue(double &v); + + /** @brief get value */ + double getValue(void) {double v; getValue(v); return v;} + + /** @brief get the value at a time */ + void getValueAtTime(double t, double &v); + + /** @brief get value */ + double getValueAtTime(double t) {double v; getValueAtTime(t, v); return v;} + + /** @brief set value */ + void setValue(double v); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, double v); + + /** @brief differentiate the param */ + void differentiate(double t, double &v); + + /** @brief differentiate the param */ + double differentiate(double t) {double v; differentiate(t, v); return v;} + + /** @brief integrate the param */ + void integrate(double t1, double t2, double &v); + + /** @brief integrate the param */ + double integrate(double t1, double t2) {double v; integrate(t1, t2, v); return v;} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an doubleeger param */ + class Double2DParam : public BaseDoubleParam { + protected : + mDeclareProtectedAssignAndCCBase(Double2DParam,BaseDoubleParam); + Double2DParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Double2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(double x, double y); + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void setRange(double minX, double minY, + double maxX, double maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minX, double minY, + double maxX, double maxY); + + /** @brief get the default value */ + void getDefault(double &x, double &y); + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void getRange(double &minX, double &minY, + double& maxX, double &maxY); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(double &minX, double &minY, + double &maxX, double &maxY); + + /** @brief get value */ + void getValue(double &x, double &y); + + /** @brief get the value at a time */ + void getValueAtTime(double t, double &x, double &y); + + /** @brief set value */ + void setValue(double x, double y); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, double x, double y); + + /** @brief differentiate the param */ + void differentiate(double t, double &x, double &y); + + /** @brief differentiate the param */ + OfxPointD differentiate(double t) {OfxPointD v; differentiate(t, v.x, v.y); return v;} + + /** @brief integrate the param */ + void integrate(double t1, double t2, double &x, double &y); + + /** @brief integrate the param */ + OfxPointD integrate(double t1, double t2) {OfxPointD v; integrate(t1, t2, v.x, v.y); return v;} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an doubleeger param */ + class Double3DParam : public BaseDoubleParam { + protected : + mDeclareProtectedAssignAndCCBase(Double3DParam,BaseDoubleParam); + Double3DParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + Double3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(double x, double y, double z); + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void setRange(double minX, double minY, double minZ, + double maxX, double maxY, double maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void setDisplayRange(double minX, double minY, double minZ, + double maxX, double maxY, double maxZ); + + /** @brief get the default value */ + void getDefault(double &x, double &y, double &z); + + /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */ + void getRange(double &minX, double &minY, double &minZ, + double& maxX, double &maxY, double &maxZ); + + /** @brief set the display min and max, default is to be the same as the range param */ + void getDisplayRange(double &minX, double &minY, double &minZ, + double& maxX, double &maxY, double &maxZ); + + /** @brief get value */ + void getValue(double &x, double &y, double &z); + + /** @brief get the value at a time */ + void getValueAtTime(double t, double &x, double &y, double &z); + + /** @brief set value */ + void setValue(double x, double y, double z); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, double x, double y, double z); + + /** @brief differentiate the param */ + void differentiate(double t, double &x, double &y, double &z); + + /** @brief differentiate the param */ + Ofx3DPointD differentiate(double t) {Ofx3DPointD v; differentiate(t, v.x, v.y, v.z); return v;} + + /** @brief integrate the param */ + void integrate(double t1, double t2, double &x, double &y, double &z); + + /** @brief integrate the param */ + Ofx3DPointD integrate(double t1, double t2) {Ofx3DPointD v; integrate(t1, t2, v.x, v.y, v.z); return v;} + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an RGB param */ + class RGBParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(RGBParam,ValueParam); + RGBParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + RGBParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(double r, double g, double b); + + /** @brief get default value */ + void getDefault(double &r, double &g, double &b); + + /** @brief get value */ + void getValue(double &r, double &g, double &b); + + /** @brief get the value at a time */ + void getValueAtTime(double t, double &r, double &g, double &b); + + /** @brief set value */ + void setValue(double r, double g, double b); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, double r, double g, double b); + }; + + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up an RGB param */ + class RGBAParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(RGBAParam,ValueParam); + RGBAParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + RGBAParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + public : + /** @brief set the default value, default is 0 */ + void setDefault(double r, double g, double b, double a); + + /** @brief get default value */ + void getDefault(double &r, double &g, double &b, double &a); + + /** @brief get value */ + void getValue(double &r, double &g, double &b, double &a); + + /** @brief get the value at a time */ + void getValueAtTime(double t, double &r, double &g, double &b, double &a); + + /** @brief set value */ + void setValue(double r, double g, double b, double a); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, double r, double g, double b, double a); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a string param */ + class StringParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(StringParam,ValueParam); + StringParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + StringParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + friend class ParamSet; + + public : + /** @brief set the default value */ + void setDefault(const std::string &v); + + /** @brief get the default value */ + void getDefault(std::string &v); + + /** @brief get value */ + void getValue(std::string &v); + + /** @brief get the value at a time */ + void getValueAtTime(double t, std::string &v); + + /** @brief set value */ + void setValue(const std::string &v); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, const std::string &v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a choice param */ + class ChoiceParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(ChoiceParam,ValueParam); + ChoiceParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + ChoiceParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + /** @brief set the default value */ + void setDefault(int v); + + /** @brief get the default value */ + void getDefault(int &v); + + /** @brief how many options do we have */ + int getNOptions(void); + + /** @brief append an option, default is to have not there */ + void appendOption(const std::string &v, const std::string& label = "", const int order = -1); + + /** @brief set an option */ + void setOption(int item, const std::string &str); + + /** @brief get the option value */ + void getOption(int ix, std::string &v); + + /** @brief clear all the options so as to add some new ones in */ + void resetOptions(void); + + /** @brief get value */ + void getValue(int &v); + + /** @brief get the value at a time */ + void getValueAtTime(double t, int &v); + + /** @brief set value */ + void setValue(int v); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, int v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a string choice param */ + class StrChoiceParam : public StringParam + { + protected : + mDeclareProtectedAssignAndCCBase(StrChoiceParam, StringParam); + StrChoiceParam() { assert(false); } + + protected : + /** @brief hidden constructor */ + StrChoiceParam(const ParamSet* p_ParamSet, const std::string& p_Name, OfxParamHandle p_Handle); + + // so it can make one + friend class ParamSet; + + public : + /** @brief how many options do we have */ + int getNOptions(); + + /** @brief append an option */ + void appendOption(const std::string& p_Enum, const std::string& p_Option, int order = INT_MIN); + + /** @brief set an option */ + void setOption(const std::string& p_Index, const std::string& p_Option); + + /** @brief get the option value */ + void getOption(const std::string& p_Index, std::string& p_Option); + + /** @brief clear all the options so as to add some new ones in */ + void resetOptions(); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a boolean param */ + class BooleanParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(BooleanParam,ValueParam); + BooleanParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + BooleanParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + /** @brief set the default value */ + void setDefault(bool v); + + /** @brief get the default value */ + void getDefault(bool &v); + + /** @brief get the default value */ + bool getDefault(void) {bool v; getDefault(v); return v;} + + /** @brief get value */ + void getValue(bool &v); + + /** @brief get value */ + bool getValue(void) {bool v; getValue(v); return v;} + + /** @brief get the value at a time */ + void getValueAtTime(double t, bool &v); + + /** @brief get value */ + bool getValueAtTime(double t) {bool v; getValueAtTime(t, v); return v;} + + /** @brief set value */ + void setValue(bool v); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, bool v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a group param */ + class GroupParam : public Param { + protected : + mDeclareProtectedAssignAndCCBase(GroupParam,Param); + GroupParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + GroupParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + /** @brief whether the initial state of a group is open or closed in a hierarchical layout, defaults to true */ + bool getIsOpen(); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a group param */ + class PageParam : public Param { + protected : + mDeclareProtectedAssignAndCCBase(PageParam,Param); + PageParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + PageParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a custom param, not animation support yet */ + class CustomParam : public ValueParam { + protected : + mDeclareProtectedAssignAndCCBase(CustomParam,ValueParam); + CustomParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + CustomParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + /** @brief set the default value of the param */ + void setDefault(const std::string &v); + + /** @brief get the default value of the param */ + void getDefault(std::string &v); + + /** @brief get value */ + void getValue(std::string &v); + + /** @brief get the value at a time */ + void getValueAtTime(double t, std::string &v); + + /** @brief set value */ + void setValue(const std::string &v); + + /** @brief set value */ + void setValue(const char* str); + + /** @brief set the value at a time, implicitly adds a keyframe */ + void setValueAtTime(double t, const std::string &v); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a push button param, not much to it at all */ + class PushButtonParam : public Param { + protected : + mDeclareProtectedAssignAndCCBase(PushButtonParam,Param); + PushButtonParam(void) {assert(false);} + + protected : + /** @brief hidden constructor */ + PushButtonParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + public : + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief Wraps up a parametric param */ + class ParametricParam : public Param { + private: + mDeclareProtectedAssignAndCCBase(ParametricParam,Param); + ParametricParam(void) {assert( false);} + + protected: + /** @brief hidden constructor */ + ParametricParam(const ParamSet* paramSet, const std::string& name, OfxParamHandle handle); + + // so it can make one + friend class ParamSet; + + public: + double getValue(const int curveIndex, + const OfxTime time, + const double parametricPosition); + int getNControlPoints(const int curveIndex, + const OfxTime time); + std::pair getNthControlPoint(const int curveIndex, + const OfxTime time, + const int nthCtl); + void setNthControlPoints(const int curveIndex, + const OfxTime time, + const int nthCtl, + const double key, + const double value, + const bool addAnimationKey); + void setNthControlPoints(const int curveIndex, + const OfxTime time, + const int nthCtl, + const std::pair ctrlPoint, + const bool addAnimationKey); + void addControlPoint(const int curveIndex, + const OfxTime time, + const double key, + const double value, + const bool addAnimationKey); + void deleteControlPoint(const int curveIndex, + const int nthCtl); + void deleteControlPoint(const int curveIndex); + }; + + //////////////////////////////////////////////////////////////////////////////// + /** @brief A set of parameters in a plugin instance */ + class ParamSet { + protected : + mDeclareProtectedAssignAndCC(ParamSet); + ParamTypeEnum getParamType(const std::string& name) const; + private : + /** @brief Properties that belong to this param set */ + PropertySet _paramSetProps; + + /** @brief Parameter set handle */ + OfxParamSetHandle _paramSetHandle; + + /** @brief Set of all previously fetched parameters, created on demand */ + mutable std::map _fetchedParams; + + /** @brief see if we have a param of the given name in out map */ + Param *findPreviouslyFetchedParam(const std::string &name) const; + + /** @brief calls the raw OFX routine to define a param */ + void fetchRawParam(const std::string &name, ParamTypeEnum paramType, OfxParamHandle &handle) const; + + /** @brief Fetch a param of the given name and type */ + template void + fetchParam(const std::string &name, ParamTypeEnum paramType, T * ¶mPtr) const + { + paramPtr = NULL; + + // have we made it already in this param set and is it an int? + if(Param *param = findPreviouslyFetchedParam(name)) { + if(param->getType() == paramType) { + paramPtr = (T *) param; // could be a dynamic cast here + } + else + throw OFX::Exception::TypeRequest("Fetching param and attempting to return the wrong type"); + } + else { + // ok define one and add it in + OfxParamHandle paramHandle; + fetchRawParam(name, paramType, paramHandle); + + // make out support descriptor class + paramPtr = new T(this, name, paramHandle); + + // add it to our map of described ones + _fetchedParams[name] = paramPtr; + } + } + + protected: + // the following function should be specialized for each param type T + // (see example below with T = CameraParam) + template void + fetchAttribute(OfxImageEffectHandle /*pluginHandle*/, const std::string& /*name*/, T * &/*paramPtr*/) const + { + assert(false); + } + + protected : + /** @brief Hidden ctor */ + ParamSet(void); + + /** @brief set the param set handle */ + void setParamSetHandle(OfxParamSetHandle h); + + public : + virtual ~ParamSet(); + + bool paramExists(const std::string& name) const; + + /// open an undoblock + void beginEditBlock(const std::string &name); + + /// close an undoblock + void endEditBlock(); + + Param* getParam(const std::string& name) const; + + /** @brief Fetch an integer param */ + IntParam *fetchIntParam(const std::string &name) const; + + /** @brief Fetch a 2D integer param */ + Int2DParam *fetchInt2DParam(const std::string &name) const; + + /** @brief Fetch a 3D integer param */ + Int3DParam *fetchInt3DParam(const std::string &name) const; + + /** @brief Fetch an double param */ + DoubleParam *fetchDoubleParam(const std::string &name) const; + + /** @brief Fetch a 2D double param */ + Double2DParam *fetchDouble2DParam(const std::string &name) const; + + /** @brief Fetch a 3D double param */ + Double3DParam *fetchDouble3DParam(const std::string &name) const; + + /** @brief Fetch a string param */ + StringParam *fetchStringParam(const std::string &name) const; + + /** @brief Fetch a RGBA param */ + RGBAParam *fetchRGBAParam(const std::string &name) const; + + /** @brief Fetch an RGB param */ + RGBParam *fetchRGBParam(const std::string &name) const; + + /** @brief Fetch a Boolean param */ + BooleanParam *fetchBooleanParam(const std::string &name) const; + + /** @brief Fetch a Choice param */ + ChoiceParam *fetchChoiceParam(const std::string &name) const; + + /** @brief Fetch a String Choice param */ + StrChoiceParam* fetchStrChoiceParam(const std::string& p_Name) const; + + /** @brief Fetch a group param */ + GroupParam *fetchGroupParam(const std::string &name) const; + + /** @brief Fetch a page param */ + PageParam *fetchPageParam(const std::string &name) const; + + /** @brief Fetch a push button param */ + PushButtonParam *fetchPushButtonParam(const std::string &name) const; + + /** @brief Fetch a custom param */ + CustomParam *fetchCustomParam(const std::string &name) const; + + /** @brief Fetch a parametric param */ + ParametricParam* fetchParametricParam(const std::string &name) const; + }; +}; + +// undeclare the protected assign and CC macro +#undef mDeclareProtectedAssignAndCC +#undef mDeclareProtectedAssignAndCCBase + +#endif diff --git a/third_party/openfx/Support/include/ofxsProcessing.h b/third_party/openfx/Support/include/ofxsProcessing.h new file mode 100644 index 000000000..570788d14 --- /dev/null +++ b/third_party/openfx/Support/include/ofxsProcessing.h @@ -0,0 +1,230 @@ + + +#ifndef _ofxsProcessing_h_ +#define _ofxsProcessing_h_ + +/* + OFX Support Library, a library that skins the OFX plug-in API with C++ classes. + Copyright (C) 2005 The Open Effects Association Ltd + Author Bruno Nicoletti bruno@thefoundry.co.uk + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name The Open Effects Association Ltd, nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The Open Effects Association Ltd +1 Wardour St +London W1D 6PA +England + +*/ + +#include +#include + +#include "ofxsImageEffect.h" +#include "ofxsMultiThread.h" +#include "ofxsLog.h" + +/** @file This file contains a useful base class that can be used to process images + +The code below is not so much a skin on the base OFX classes, but code used in implementing +specific image processing algorithms. +*/ + +namespace OFX { + + //////////////////////////////////////////////////////////////////////////////// + // base class to process images with + class ImageProcessor : public OFX::MultiThread::Processor { + protected : + OFX::ImageEffect &_effect; /**< @brief effect to render with */ + OFX::Image *_dstImg; /**< @brief image to process into */ + OfxRectI _renderWindow; /**< @brief render window to use */ + bool _isEnabledOpenCLRender; /**< @brief is OpenCL Render Enabled */ + bool _isEnabledCudaRender; /**< @brief is Cuda Render Enabled */ + bool _isEnabledMetalRender; /**< @brief is Metal Render Enabled */ + void* _pOpenCLCmdQ; /**< @brief OpenCL Command Queue Handle */ + void* _pCudaStream; /**< @brief Cuda Stream Handle */ + void* _pMetalCmdQ; /**< @brief Metal Command Queue Handle */ + + public : + /** @brief ctor */ + ImageProcessor(OFX::ImageEffect &effect) + : _effect(effect) + , _dstImg(0) + , _isEnabledOpenCLRender(false) + , _isEnabledCudaRender(false) + , _isEnabledMetalRender(false) + , _pOpenCLCmdQ(NULL) + , _pCudaStream(NULL) + , _pMetalCmdQ(NULL) + { + _renderWindow.x1 = _renderWindow.y1 = _renderWindow.x2 = _renderWindow.y2 = 0; + } + + /** @brief set the destination image */ + void setDstImg(OFX::Image *v) {_dstImg = v; } + + /** @brief set OpenCL, CUDA render arguments */ + void setGPURenderArgs(const OFX::RenderArguments& args) + { + _isEnabledOpenCLRender = args.isEnabledOpenCLRender; + _isEnabledCudaRender = args.isEnabledCudaRender; + _isEnabledMetalRender = args.isEnabledMetalRender; + + if (_isEnabledOpenCLRender) + { + _pOpenCLCmdQ = args.pOpenCLCmdQ; + } + if (_isEnabledCudaRender) + { + _pCudaStream = args.pCudaStream; + } + if (_isEnabledMetalRender) + { + _pMetalCmdQ = args.pMetalCmdQ; + } + } + + /** @brief reset the render window */ + void setRenderWindow(OfxRectI rect) {_renderWindow = rect;} + + /** @brief overridden from OFX::MultiThread::Processor. This function is called once on each SMP thread by the base class */ + void multiThreadFunction(unsigned int threadId, unsigned int nThreads) + { + // slice the y range into the number of threads it has + unsigned int dy = _renderWindow.y2 - _renderWindow.y1; + // the following is equivalent to std::ceil(dy/(double)nThreads); + unsigned int h = (dy+nThreads-1)/nThreads; + if (h == 0) { + // there are more threads than lines to process + h = 1; + } + if (threadId * h >= dy) { + // empty render subwindow + return; + } + unsigned int y1 = _renderWindow.y1 + threadId * h; + + unsigned int step = (threadId + 1) * h; + unsigned int y2 = _renderWindow.y1 + (step < dy ? step : dy); + + OfxRectI win = _renderWindow; + win.y1 = y1; win.y2 = y2; + + // and render that thread on each + multiThreadProcessImages(win); + } + + /** @brief called before any MP is done */ + virtual void preProcess(void) {} + + /** @brief this is called by process to actually process images using OpenCL when isEnabledOpenCLRender is true, override in derived classes */ + virtual void processImagesOpenCL(void) + { + OFX::Log::print("processImagesOpenCL not implemented"); + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + }; + + /** @brief this is called by process to actually process images using CUDA when isEnabledCudaRender is true, override in derived classes */ + virtual void processImagesCuda(void) + { + OFX::Log::print("processImagesCuda not implemented"); + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + }; + + /** @brief this is called by process to actually process images using Metal when isEnabledMetalRender is true, override in derived classes */ + virtual void processImagesMetal(void) + { + OFX::Log::print("processImagesMetal not implemented"); + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + }; + + /** @brief this is called by multiThreadFunction to actually process images, override in derived classes */ + virtual void multiThreadProcessImages(OfxRectI window) + { + OFX::Log::print("multiThreadProcessImages not implemented"); + OFX::throwSuiteStatusException(kOfxStatErrUnsupported); + }; + + /** @brief called before any MP is done */ + virtual void postProcess(void) {} + + /** @brief called to process everything */ + virtual void process(void) + { + // If _dstImg was set, check that the _renderWindow is lying into dstBounds + if (_dstImg) { + const OfxRectI& dstBounds = _dstImg->getBounds(); + // is the renderWindow within dstBounds ? + assert(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 && + dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2); + // exit gracefully in case of error + if (!(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 && + dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2) || + (_renderWindow.x1 >= _renderWindow.x2) || + (_renderWindow.y1 >= _renderWindow.y2)) { + return; + } + } + + // call the pre MP pass + preProcess(); + + if (_isEnabledOpenCLRender) + { + OFX::Log::print("processing via OpenCL"); + processImagesOpenCL(); + } + else if (_isEnabledCudaRender) + { + OFX::Log::print("processing via CUDA"); + processImagesCuda(); + } + else if (_isEnabledMetalRender) + { + OFX::Log::print("processing via Metal"); + processImagesMetal(); + } + else // is CPU + { + OFX::Log::print("processing via CPU"); + // make sure there are at least 4096 pixels per CPU and at least 1 line par CPU + unsigned int nCPUs = (std::min(_renderWindow.x2 - _renderWindow.x1, 4096) * + (_renderWindow.y2 - _renderWindow.y1)) / 4096; + // make sure the number of CPUs is valid (and use at least 1 CPU) + nCPUs = std::max(1u, std::min(nCPUs, OFX::MultiThread::getNumCPUs())); + + // call the base multi threading code, should put a pre & post thread calls in too + multiThread(nCPUs); + } + + // call the post MP pass + postProcess(); + } + + }; + + +}; +#endif diff --git a/third_party/openfx/Support/include/osxDeploy.sh b/third_party/openfx/Support/include/osxDeploy.sh new file mode 100755 index 000000000..e4a002aec --- /dev/null +++ b/third_party/openfx/Support/include/osxDeploy.sh @@ -0,0 +1,172 @@ +#!/bin/bash + +# +# Olive Community Edition - Non-Linear Video Editor +# Copyright (C) 2025 Olive CE Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + + + + + + +# Package all local libraries into an application or plugin bundle on OSX +# +# Author: Frederic Devernay +# +# This script copies the .so, .la and .xml files needed to redistribute a mac application +# This file is strongly inspired from the osx-app.sh script from the Inkscape source code +# +# In the XCode project, the "Runtime search paths" of your binaries should be set to +# "@loader_path/../Frameworks @loader_path/../Libraries" so that it finds libraries +# and frameworks at runtime. +# If using a Makefile, you should add the following flags at link time: +# -Wl,-rpath,@loader_path/../Frameworks -Wl,-rpath,@loader_path/../Libraries +# +# References: +# http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html +# http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/ + +# env LANG=C is necessary so that sed doesn't try to interpret the binary file with a specific encoding +LANG=C +export LANG + +if [ $# != 2 ]; then + echo "Usage: $0 AppName.app|Bundle.bundle Executablename" + echo "moves macports and local libraries into AppName.app" + exit 1 +fi + +MACPORTS=/opt/local +HOMEBREW=/brew2/local +LOCAL=/usr/local + +# add to PATH +PATH="$MACPORTS/bin:$HOMEBREW/bin:$LOCAL/bin:$PATH" + +if ! port help > /dev/null 2>&1; then + echo "Please make sure that MacPorts is installed in /opt/local" + exit 1 +fi + + +package="$1" +binary="$package/Contents/MacOS/$2" +libdir="Libraries" +pkglib="$package/Contents/$libdir" + +if [ ! -x "$binary" ]; then + echo "Error: $binary does not exist or is not an executable" + exit 1 +fi + +rpath=`otool -l $binary | grep -A 3 LC_RPATH |grep path|awk '{ print $2 }'` +if [[ ! ("$rpath" == *"@loader_path/../Libraries"*) ]]; then + echo "Error:: The runtime search path in $binary does not contain \"@loader_path/../Libraries\". Please set it in your Xcode project, or link the binary with the flags -Xlinker -rpath -Xlinker \"@loader_path/../Libraries\"" + exit 1 +fi +# Test dirs +test -d "$pkglib" || mkdir "$pkglib" +test -d "$pkglib/share/" || mkdir "$pkglib/share/" + +LIBADD= + +############################# +# test if ImageMagick is used +if otool -L "$binary" | fgrep libMagick > /dev/null; then + # Check that ImageMagick is properly installed + if ! pkg-config --modversion ImageMagick >/dev/null 2>&1; then + echo "Missing ImageMagick -- please install ImageMagick ('sudo port install ImageMagick +no_x11 +universal') and try again." >&2 + exit 1 + fi + + # Update the ImageMagick path in startup script. + IMAGEMAGICKVER=`pkg-config --modversion ImageMagick` + IMAGEMAGICKMAJ=${IMAGEMAGICKVER%.*.*} + IMAGEMAGICKLIB=`pkg-config --variable=libdir ImageMagick` + IMAGEMAGICKSHARE=`pkg-config --variable=prefix ImageMagick`/share + # if I get this right, sed substitutes in the exe the occurences of IMAGEMAGICKVER + # into the actual value retrieved from the package. + # We don't need this because we use MAGICKCORE_PACKAGE_VERSION declared in the + # sed -e "s,IMAGEMAGICKVER,$IMAGEMAGICKVER,g" -i "" $pkgbin/DisparityKillerM + + # copy the ImageMagick libraries (.la and .so) + cp -r "$IMAGEMAGICKLIB/ImageMagick-$IMAGEMAGICKVER" "$pkglib/" + cp -r "$IMAGEMAGICKSHARE/ImageMagick-$IMAGEMAGICKMAJ" "$pkglib/share/" + + LIBADD="$LIBADD $pkglib/ImageMagick-$IMAGEMAGICKVER/modules-*/*/*.so" + WITH_IMAGEMAGICK=yes +fi + +# expand glob patterns in LIBADD +LIBADD=`echo $LIBADD` + +# Find out the library dependencies +# (i.e. $LOCAL or $MACPORTS), then loop until no changes. +a=1 +nfiles=0 +alllibs="" +endl=true +while $endl; do + #echo -e "\033[1mLooking for dependencies.\033[0m Round" $a + libs="`otool -L $pkglib/* $LIBADD $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep -e $LOCAL'\\|'$HOMEBREW'\\|'$MACPORTS | sort | uniq`" + if [ -n "$libs" ]; then + cp -f $libs $pkglib + alllibs="`ls $alllibs $libs | sort | uniq`" + fi + let "a+=1" + nnfiles=`ls $pkglib | wc -l` + if [ $nnfiles = $nfiles ]; then + endl=false + else + nfiles=$nnfiles + fi +done + +# all the libraries were copied, now change the names... +## We use @rpath instead of @executable_path/../$libdir because it's shorter +## than /opt/local, so it always works. The downside is that the XCode project +## has to link the binary with "Runtime search paths" set correctly +## (e.g. to "@loader_path/../Frameworks @loader_path/../Libraries" ). +if [ -n "$alllibs" ]; then + changes="" + for l in $alllibs; do + changes="$changes -change $l @rpath/`basename $l`" + done + + for f in $pkglib/* $LIBADD "$binary"; do + # avoid directories + if [ -f $f ]; then + if ! install_name_tool $changes $f; then + echo "Error: 'install_name_tool $changes $f' failed" + exit 1 + fi + fi + done +fi + +#if [ "$WITH_IMAGEMAGICK" = "yes" ]; then + # and now, obfuscate all the default paths in dynamic libraries + # and ImageMagick modules and config files + + # generate a pseudo-random string which has the same length as $MACPORTS + RANDSTR="R7bUU6jiFvqrPy6zLVPwIC3b93R2b1RG2qD3567t8hC3b93R2b1RG2qD3567t8h" + MACRAND=${RANDSTR:0:${#MACPORTS}} + HOMEBREWRAND=${RANDSTR:0:${#HOMEBREW}} + LOCALRAND=${RANDSTR:0:${#LOCAL}} + find $pkglib -type f -exec sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" {} \; + sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" "$binary" +#fi diff --git a/third_party/openfx/Support/support.doxy b/third_party/openfx/Support/support.doxy new file mode 100644 index 000000000..5aad5f2b5 --- /dev/null +++ b/third_party/openfx/Support/support.doxy @@ -0,0 +1,1074 @@ +# Doxyfile 1.3.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "OFX Support" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = "1.1" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./doc + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = YES + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ./include ./Library + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs + +FILE_PATTERNS = *.cpp *.h *.H + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similiar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/third_party/openfx/include/DocSrc/footer.html b/third_party/openfx/include/DocSrc/footer.html new file mode 100644 index 000000000..b7846293e --- /dev/null +++ b/third_party/openfx/include/DocSrc/footer.html @@ -0,0 +1,35 @@ + + +
+ +Copyright OpenFX and contributors to the OpenFX project. +SPDX-License-Identifier: BSD-3-Clause + +Copying and redistribution with or without +modification, is permitted provided that the following conditions are met: +
    +
  1. Redistributions of the document must retain the above copyright notice + and this list of conditions.
  2. +
  3. Neither the name of The Open Effects Association Ltd nor names of its + contributors may be used to + endorse or promote products derived from this software without specific + prior written permission.
  4. +
+Automatic documentation generated by Doxygen.
+
diff --git a/third_party/openfx/include/DocSrc/ofx_footer.html b/third_party/openfx/include/DocSrc/ofx_footer.html new file mode 100644 index 000000000..0a2e2979e --- /dev/null +++ b/third_party/openfx/include/DocSrc/ofx_footer.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + diff --git a/third_party/openfx/include/DocSrc/ofx_header.html b/third_party/openfx/include/DocSrc/ofx_header.html new file mode 100644 index 000000000..560329d14 --- /dev/null +++ b/third_party/openfx/include/DocSrc/ofx_header.html @@ -0,0 +1,73 @@ + + + + + + + + + +$projectname: $title +$title + + + +$treeview +$search +$mathjax + +$extrastylesheet + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
+
+ + diff --git a/third_party/openfx/include/DocSrc/ofx_style.css b/third_party/openfx/include/DocSrc/ofx_style.css new file mode 100644 index 000000000..18069aa7a --- /dev/null +++ b/third_party/openfx/include/DocSrc/ofx_style.css @@ -0,0 +1,1456 @@ + + +/* The standard CSS for doxygen 1.8.6 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* OFX Top level nav */ +.navbar-nav { + font-size: 13px; + background-color: #222; + border-color: #080808; + &>li>a{ + color: #999; + &:hover{ + color: #fff; + background-color: #000; + } + } +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/third_party/openfx/include/OFX_navheader.png b/third_party/openfx/include/OFX_navheader.png new file mode 100644 index 0000000000000000000000000000000000000000..d2d3ff8f10a56c0fc3af9eacc8b16ea9bd5f951e GIT binary patch literal 8753 zcmcgyRa{hGv_=V~d%%%Fq(R!D5u`gMhL9Y(hb}4U1_5bgq-1E2?rw*a?iO$aoIwOG z{_pdBz2{+{^YE?jti9L%oxRrjPK=g@A~6Aw01FF?SXoI<2Mg;V@%^*jW4!xu)M$b2 z{`SOE9^(1N)yC7u0%naR4Ry7&W>9vvu(j5)wt)J%k624!VLhKwmXp@?UHXxS?`ERx zH)MRim$CQlK+-9J`YhDPaLUL?HoD^lFD@5;%r5aK2F1n5WGX%83?-$x5{8U7xQ2zJ zbrlTnS^8n@N(>gx_4rzg>Re~puiC!~?tSm8c$>rv%CG^y%)VA@`Z^@hafmkU68)Tl zc~@m%HGwi+zd5UJ>r!}p@9Y2fHP7W$0SY19pE^dVig$k9s7Sx<3PsIfb?%`ABdQnv z{JFMexc=vqIVcW~i{b~SSg~}bL)Dd!h(K)9A{=R6?rQhizk~h>QDm{I3TL`ZmKuO1 z4WBA$KwB)2V5e@e^kvp~T8qi4-rscLnq;Nd84vHtx`8yr5H7Og9&aw9+iy-nXJBJ4 zpKNY@s8CKa!{h9;sDXzntTiFgLoZ|GwkjcDf5w8TyJxp{ba7EsQ0{;3Af6*bBEm?z z8mvD3lujG@TQ=g22#Py&BDj8;^$ z8Ka@oh$^kEb=PCcoZ3b9$}mt9MC7Zpq(#-Zi4Yo+`~x>W2d+8RL2k=CDue1roMgPb zDmvjF_7m8(V&hX&9Ur5IqH5hl9xeU{u3!e%K=`&Y(T2yzcW`+9jLcV!d0;JsZenUR zTdkk6Z~4#H8ye`Vf5dih9YSKs6E~4WA8)U@&*lt}O28}<+46)iXB)EfBLwm2AIkZI zwSA!@t>m`@Se}!Ei%`avt3~niW4bD{HlZw~{yUhl*?Q8a|F&oMXmq5{Q}q&8FW2ui z5xWE0Z*23Y;JTa%0$EMfyP*i#Fw-P8R?2C@KXq(+MJep9UXH)hbp=}5s=I$aENhJRJqsNe z|4fF1Cb6ea1GoWkV@~{Voyw;paulo0?l&^5dAD!5=t@4Z|Kom5Er;#C0tIK02n!0{ zMNGKNw5u{^PJ9{|7+Be|#H2&Gyg3WTQYw>e-S^+1_c6cqR#eH`m4F{4kI-i$TPkg-?<1|S)C_t!#jDuh9!1V|K-$Jg7BHdR3mFX*`H@b4p>}Zpb^?o6~{r6AA~_o%!{OB3MPN=&b;n z88lxehov-d%&NWZBg5i~u8zWU$36G_;LW}j+JBQQkS(_JBK}ufh5mbNl5Km1Jj1k; zYk|Jd!80k#`sEf}Y{Nb>f=Df>J1WM35YNF&$+~`#_s`8OVT^C?`byZgRU<^$3Rw&K zVx^pJ^*;958acl`7u&%wHRS3qu%CB`3P-kQODlxUwP(68L3(7JUJQnZ`8oVyy+e>{ zFce5?rtGGvxk1vX=gRjtvF~uFQxrgW7!h*UmZi35Je42B6Xbj0#zG2*0E2>TFfYf} zB+ggrZy)*m_&Yp)aS?Ztm-kj;S$bq^1g}k9N=iyNe!GQ6qknex0kJk=xV{p$AMoy7 zW-30Yi~vrzF3MD=R2JK21g@OX@J%*S*O=F8#{2fGyzSwmpMpdKX@sILc8h_W2GWr= zhUdDx3gt|UKl;01V`CE?9I>2V zXzGs|AV$d*u~88mqF&w^N(rMEPl=x*B+y`B!mwqnQ__HC{}NWI#V_G^Dxh!8N(?nX zWi}8h%+T9fTu0wDe)E{~=FUZX?G>|?o`}ZXI^41rk|2^etC5sU=l$BnoFb~2) zc0YJxw-LxXlPjD0+XfLiI>%=uiF*L=y1FDI?jJR;HF|5p8WKovQ5#}XRkF6Xx956} zA4*3M5hmKfFuMpMk&lyO%^NXvS@RXTKO#;xk$pR}qd&sMy?tHDN^neQ`P-!fzM z(fMZfPnb6k0!gdNN7r-6+qoV+iax7GU9!sx<_CuhoVAU7072H8Bl`F>s^Jascm@os zk>E&IqNp?IrwLPy3f1uClRXlp`*SvB*is~2qtt}QpkmHJ zug>y7>+NcQ+oL;VL#3Wd5Kr6w9K4pP z!aAb9C!h6bq2&Ivy-!B{PKnTsif{Y!QA0^LUw z9-5YSH%nc#7m=js=72Tiw{P7)4o7iPLfmEckPLERo-s0K^sFyPNHYOb(#RyR-{+9SPp2Tk^8f{z))B(XsxcH%3p? znzB;KPhwyS5NZ_~VRf1$D2|k=M(Hrw8@7e+VSY%$*>pq|eT>p`g{?d;5!{4& z^nG=hAA6;+A`%w2S_nXDO$vQi={IO_HZj=~Tu?-I;Ax=%=B_NqWLB{}5LK@Roy$n3 zpzwyE=?|JFgp{>*nEH&bUtOC`csje))jw68x=cTCtOK{-{@Hz6-TrH=Ywg>rv%Rxp zaC=izlX|K7^XLJ~g9+hvBBM(Em$y|}yTk$%F$`VnNha#*N)rJrS^B7{Dcgtd?oOS9 zf~2OCpZF;}G8{sQr-sTK^B|Y^Zmg8n;yDD_>Q7(ED00^sAN>?GIeN$+c=v)R?m^3X z3Po_+xQuikuZx;6Qbwah@-6*I@sM&8**UhPgPqgM36A2-B@W$hvwM1;^U@VA%qQFrg^BA zCrKXLl}mCQcmSAP(_lgJzt-p*{gua1_~{MLcM}k=o}{T!XMoK7NsC({WV}(cV&anl zS9Xv@_H=vwHq{viUfGqJqnqdMflp47GhhRMDt}~Xt@+C?-!Ui}KVK8#UfrrFU#046 z+l5t3dxp|(S){~&pD3|(O*vGvQKqZm5hzX>+jZ;8)7;XyRbKH+8lRdN_!&?)#i;*& z!e?c3rP&>BI2izMBwM<^g!Q8NXcPRyksGG+pAHLUEVVYpWjz-j)<4{G3oiZq!GQ?3v~>+P&-|SL1Cgd~;*B$q?5HvA ztBZ3lQgy<{$@tGR(ncC%Eu=c-Z0*)ridrr9aN|iK3wuboz~1F5UDzgAafu2CCcmv( z5G-HJ!}uqDreTd^AY$LtB~eJGe3I0C{#tL5psIL{z0rLd%;f&*(n+b<1V+fDhkQ*M z)4BlN@_3@I@LQv_{($K57B%c>Z({s7lh-W33I@~h@9^3k-H~B%dlHwpv19D2kROb? za#dGf4J06pZqQ-VL_BdAf|ZuDZ}yn;F-m_!S6Q}=E%Skr{q7nDBc01|lEUeqq)&*a zc5=?Jv%4q1G?gbVRvK_TY|hJFm+D4ta7UEo_8E-)^ra5x!wq8(xjJ(I`;Fn1(-!<%-7s@H7O&s4*_co+n z+Q>O}NdKM0OLE^slT{axG52Wt^DV~C(gwYJI~@7 z!XfB1n!Tg+>CGrh<@Z>=LQ7L_SWo;;)5lZ|E5yTH%a9>e<|!&e+^3RB<93n#=;ksy z)zWd2T1~5*^dirwb z)6-&-Tq-#av_B>ph;+ijB4(Ahn0lm_Y1m{%;$Py#8yBBYwk<8>E_fb&i;7)v#$nl2 zs&%fk>~J6Z;PXs*2n$&T;9Qw&@4VY1+Z9f4uL z`0@Rhw;^|Qf;85K>ty1NViNwCt$Cj{bgeKOTX4-)qWIV3hyy%7abfIizC zVv?TpphlrytZKNOks=p)`GZ%F=TV_HLORKou7D z1kzR50Pt$X#q;p7*&k6utOiA$P-T|%))LT$6C#r3ypkz?(0oq9954?WM!+p5>Jz`6 zsj4r+jyXumit)Jvwo~_M#3J0aJ8OXrMSkzZ{4b|53DLb=)VeBF0mXg-JXbEyO|Hi- zzKgKWAOWUH?gVQ3PsBJE>m+z6XsP3Px7&$qu6owR-^X(2YebSQyYqUvp{1auX zF57{G?ky2WBk+CYc(485=4q_Y%y?+teeFD1zJBIwu=&er)t?PNZnll-Ry_D{Un<}g zEdeMyKR?lKBu0)gCQ#Ds;;7N_EB!TIP@)T7WFeS0Mc^m9=w{zfy%cnU`e`P`N4n^%B+i31=*$L$T(nAFrIhs0a(?~RD!P1PU8M0mxOr=w z35c_DNYKu~U`xtkbN4%uLynQ>rm%y`7p|;pzT3YReHm{%zRu4RUO7odjwbYv^0B@_&Z$`=$cH(y zRCKErodeUS6;4|azLKAlg;dTrGF9w9P;n_7(=WA%&b{ZbZLJwarBHLdVdjC7|4=HP z3?p+s)8ni!^%bMaDi>hnQ~HQ@=SqIT)@dv%ZXzdsRVcIO4{ivW8#Iu;RIsl&a-aOe z*iq1w8Wi%bm?9bxW9RJ5;a~70_i={=2cl!xkQ{A37#!*t1Pfk{e7(IQj0(xGnW+p;Tg3xMyq|ZOm4xAZOpEzxV$|IMC zLDiprHd~7cB;i>w_*6THr-@Cnw?%kSKRWarMG3shs5{zF9$e=-f2qosQuD*=^YSzg zJ>4EZbFiAHD9Xzb5nwt}pUa6Bdov-!X=E@R9$Tv6P`p-F%x1Z>8r#bRv>bs7e0^w< z0$M-&TM5F;WB8j;QC^-hgbrV|k$v^*bka!(ozsQcw8lYx z|Jw+ARDCE~ciLY%Pr?2w#v@%`W3kABn6CP`DjBQdXgIC)PtfC$YE!mdXh`hYD;5oH zqS5Ft(vh@OrHj)enenzHaLXa6rIN{SZB)(p?At?(1GOh7AyK%VLndAsyAh$6>2aa^ zvC5-lTYtv%DeD$7?YbVuiVcHLL@x%sOY7Z(jg4QRU0a2n_`G~vefxJ|#5l6g4f3iI z$G*s{m{}p+2ye1K4J?1`_3?XQoiu*X0! zPZ9xBz{qX}ITj+(pGHUOz2mb!f9*L8jNo@V-EcDa+t&AZ+kP|E*)PS<2dwQG=xOS+ zE~f4B8s*bOd`4B}a8U)x24q0q0&$J_7F)HPHrS$h8Krpkc9AcfA+ z#^)kG^-?Bj&@A|_n-a!YRWjgRD`X_-LJ7#Ojhvv8WK5j?v&y7z1iKW zsjBJ}jVrye^gw1SrVreK_taj0;8G8@fpAx_RR@;Isw6ztyG0Cs%7w?Rax(U_-AwvR zX(8}NP0RYh8T1=F^Gp2vZa)KKB*UZgmvp;KXq6Y zjrm+oTolB!EpKK64yU(m(omd5lX*uqTG2z>+RTPHSH0&`gsf?Y9?mDAXZINZi{iIk z7{17l1e-|@zG(EYnplt(vCxWXmbOZx*buzzd)8E{uplhEc)W#J%{8IyeV;Qe3K|1+ zUy6P@9ZKLS7gBcKbI5V>!w;QYKU&+c&1h|-8NsbB!L;Q*D9W*dw#>CNWY1KA_pQd; z{*b5JgSDE5uH41WV>|}YM4b6N7DhDXkKMn_judI+W8Rh*zA3KEwH#>C*^Sk9{frGv zl38vrF3zjqK>oC3q?eT_3e9y96&DY$o0w3QB+W>B%7dvejFltm|!L!7)X6^CJSOnEAg?)$1cK&R%8_=jZ>eER{O z!}r2Q8$)Ev9HaIQ?jp(s+a>F1;;-X;zI1a~wIq8BOvB-Z^k}F!qgawSWH0v0Vauk) zEMufJg_>YSS=o@mf-ZGAkrVcv>BLQg|CdMdAUe8#llUq>hp9kfOTKkWp~Y<)-uo(y zE-x_^D_H=cyYA*YY|BQ=v}d8*zKgJyE=G^WpEau~1}g+gAs^^Qr!+Om6Uf?8Bx<`> zZKqxnKaU8{29xj&vh-HXdRRcm((wkLINKq+6m+Vgj5i@&ZiG5{TgZUQV>crCD96{BzXy>ETi2mV?LWWDyIbLl9g z*As|H)hJz)8DK+JQV)A`mPgg%FSQiNjJ+*ARp|QV-CWVX50Y^reMfKfvqkJFG437C z<&v+mg|2>0n36cS{CZhh?28yD@G^Od@Wt3jk69-$Z_thD7TZQazvhSX(=P4Y$hJdU zN$u~1_H@u@fF#GvW-^ApFwfyryy#)joE-Mm8ucGz;SK`A&v^DCiih=6(Y>vi+MUg# zveLdPYx=KX+0pC@wko4rg-Yh2!rcWn0*_5$gdmmWn8FB3kCvSdeudak5E~vYO(O^= zsb<%R;6v>+epHQ@_^v3QNt)i(r&w-cZ!c?T&nLYsCMrCQ@OF{k5ZkS*?ve@yjZOF@4g zpO}E-ahV=@9{FXdF?*mOxm?jLtqSseuPji6OD03Y}5O7 z8VzWgc=u==bHK8FDVS^KDlv9?7YBqCkq1$C8vq8affo=FZ8$A|rB2*73EkKw5{0 zv4pdlctN-pZxj>}gMjamazI=Nh9Ggr7+GN4?#HkL`qu;d+U!Pxf*CKkoy&542A?x` z>CMJ{Ile$hAYUt$&XiKROCrq$axxW8L=%>Ir#dcDkxsRL?L9os#YbuvV9BdbLSKh8 z$Gn?6Llw%jZ2$ZT@}^Eu0MxbokmpLJaBSElnbv?*;7`37 ze5t9U8ZmFnb5qru7|;$wf8LwnPe6MZ_=)fPThZFDfBBl8V$i3wY;t0b4{B4i5dZAN z_POU*gYh7+&#{ps79M{oBd962cV4&sV(GNJc^;+?>ykM8!gRCu6mx?O8cd~2B6r^%!lG08}g z$=pqD1D1JE{?~FhoBpafr_APkGoD;2*Z#b-=(Z*_|Jn>|X=%x?bC2`1l!L8Z6Ul-& zg(AYvica2*B-Ua_;4M1K_9D#mu1AgaMtdc6`9p7p5-a7*%nS`2d60&g5+3dtZlU&B z^|Ngnumnv)Uv_A;ZHLa!f1R|6Jaz!w_ocvI+k0l0m*{7vya^)C?GhB{01l@$hsn7a z@&r%aZTV4KNu@LXu-MW^-k)|oawB5TxCdUoZLz@7o$4H{TTUgn+rLS{jIKnzmp)G{>t$3|&f_Y7_hO~X&2=Dv)30exr;79Y zyTk<*(b)z&Y{Dq#d)>+;KryQOr9WF@PL12g{JcC+{!fi$Twy3VvwQA`jC?y~Z#DB_ zz@xh4NZU}>EEz~YdL;H#+m?^^=xh}>1;1|@Yc}|Je~k5Z<70Tk;nC!RE7M~x3?O#g zjgP%t+vJnS#u(h|3lQ-lX;&~XcxfJ4yXw#gySZ0tQc13K8R_q4>un2i$XzR;(gWC< z&A)UurTe}+g0u3EejF_^HWAme$EVo2czf@ST;F%=Neh)i?EVQBoD4v_()Riuo4a?$ z0mkChnF@?_E)$da>ZLjb>+=f+=?VpE1sgQ?U1GmFctu6r5HEJ96Vv?`9(_>`J<`0_ zC3$61u#o?#YLMwab5v1w7Xc_p{57+ZWxAb<{i20HR#%KT`d#4R7qZNxkK7sC+?ACp zVWBlOH6b&xtMadp;9`4s4ltgI}y05CoW z`@tOw!u9(ML%-hlOnvJ*J&=pFk!Ph+m{!uMNnFytetF4vRi5%*z>=gRkW9F{7Nkog zqWVu-(>j<^z1i&V?^kpdx?V6gGRh4z-M9rAdN$LNFmZ`ZvTdQNch9d1Hb?>#;1Gt4 zSdF)Nr+qdRyOhL2%NYu`a1B)_B@vsF5?jWU0n&~A@bpiEA&2<)ZhJ8U-G)xca5hm2 z1~Y6q**Q4sQj<&{REo8H`RN{GZo0fSVJDdTbY`N#D5+{^|cIax_!UI z!=8pY3AvNV2a0fE_Pe6*q{0evB8#*o*LxMS8%RamfbH7N8@#Z#cx4Eq zD9%W1!*c&3mnURBU4Eg)n%0>+VNsdZ3+c3u8WOZA@!2zh{f9T7feCy?jhV!vupFZdzwnFMC&A!8fZIeADX z41x{AOj}sIzCFaTI0UQ0(it@f%xhnJ!{`R5t}M-hyPn1V3mz6C*{-nH;^pbM;F;?98L1L73fpg}r^oiQjc-tH+uTNG>{PRM<%it;D~QP$`{O1w?pqMx>7H5OYzO z_TF_xO9fDL1ZCjnKL0P$$I@V}&DZ0EAk5J;ey?|jX)rHW^-cy(vjr)H3 z5NudYHnsn&dLOn}U?Z^Tfw|QCi_#0cs)Y>8c>njufEXn)XIRmbt{M|nykY#DWb6Mt g{J#b&Oz;CdtW+BRDx*;R|KxsUc@4QL8S}9J0i$}NYybcN literal 0 HcmV?d00001 diff --git a/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h b/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h new file mode 100644 index 000000000..538550be8 --- /dev/null +++ b/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h @@ -0,0 +1,839 @@ + + +#ifndef _ofx_native_v1_5_aces_v1_3_ocio_v2_3_h_ +#define _ofx_native_v1_5_aces_v1_3_ocio_v2_3_h_ + +// Copyright OpenFX and contributors to the OpenFX project. +// SPDX-License-Identifier: BSD-3-Clause + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file ofx-native-v1.5_aces-v1.3_ocio-v2.3.h +Contains the list of supported colourspaces. +This file was auto-generated by scripts/genColour from ofx-native-v1.5_aces-v1.3_ocio-v2.3. +*/ + +// For use with kOfxImageEffectPropColourManagementAvailableConfigs +#define kOfxConfigIdentifier "ofx-native-v1.5_aces-v1.3_ocio-v2.3" + +// Basic Colourspaces +// These colourspaces are generic names for any colourspace with the correct attributes. + +/** @brief ofx_display_hdr +Any display-referred HDR video such as Rec. 2100 HLG or PQ. +*/ +#define kOfxColourspaceOfxDisplayHdr "ofx_display_hdr" +#define kOfxColourspaceOfxDisplayHdrLabel "OFX generic display HDR" +#define kOfxColourspaceOfxDisplayHdrEncoding "hdr-video" +#define kOfxColourspaceOfxDisplayHdrIsData false +#define kOfxColourspaceOfxDisplayHdrIsBasic true +#define kOfxColourspaceOfxDisplayHdrIsCore true +#define kOfxColourspaceOfxDisplayHdrIsDisplay true + +/** @brief ofx_display_sdr +Any display-referred SDR video such as Rec. 709. +*/ +#define kOfxColourspaceOfxDisplaySdr "ofx_display_sdr" +#define kOfxColourspaceOfxDisplaySdrLabel "OFX generic display SDR" +#define kOfxColourspaceOfxDisplaySdrEncoding "sdr-video" +#define kOfxColourspaceOfxDisplaySdrIsData false +#define kOfxColourspaceOfxDisplaySdrIsBasic true +#define kOfxColourspaceOfxDisplaySdrIsCore true +#define kOfxColourspaceOfxDisplaySdrIsDisplay true + +/** @brief ofx_raw +Image values should not be treated as colour, e.g. motion vectors or masks. +*/ +#define kOfxColourspaceOfxRaw "ofx_raw" +#define kOfxColourspaceOfxRawLabel "OFX generic raw" +#define kOfxColourspaceOfxRawEncoding "" +#define kOfxColourspaceOfxRawIsData true +#define kOfxColourspaceOfxRawIsBasic true +#define kOfxColourspaceOfxRawIsCore true +#define kOfxColourspaceOfxRawIsDisplay false + +/** @brief ofx_scene_linear +Any scene-referred linear colourspace. +*/ +#define kOfxColourspaceOfxSceneLinear "ofx_scene_linear" +#define kOfxColourspaceOfxSceneLinearLabel "OFX generic scene linear" +#define kOfxColourspaceOfxSceneLinearEncoding "scene-linear" +#define kOfxColourspaceOfxSceneLinearIsData false +#define kOfxColourspaceOfxSceneLinearIsBasic true +#define kOfxColourspaceOfxSceneLinearIsCore true +#define kOfxColourspaceOfxSceneLinearIsDisplay false + +/** @brief ofx_scene_log +Any scene-referred colourspace with a log transfer function. +*/ +#define kOfxColourspaceOfxSceneLog "ofx_scene_log" +#define kOfxColourspaceOfxSceneLogLabel "OFX generic scene log" +#define kOfxColourspaceOfxSceneLogEncoding "log" +#define kOfxColourspaceOfxSceneLogIsData false +#define kOfxColourspaceOfxSceneLogIsBasic true +#define kOfxColourspaceOfxSceneLogIsCore true +#define kOfxColourspaceOfxSceneLogIsDisplay false + +// Core Colourspaces + +// srgb_display +// Convert CIE XYZ (D65 white) to sRGB (piecewise EOTF) +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 +#define kOfxColourspaceSrgbDisplay "srgb_display" +#define kOfxColourspaceSrgbDisplayLabel "sRGB - Display" +#define kOfxColourspaceSrgbDisplayEncoding "sdr-video" +#define kOfxColourspaceSrgbDisplayIsData false +#define kOfxColourspaceSrgbDisplayIsBasic false +#define kOfxColourspaceSrgbDisplayIsCore true +#define kOfxColourspaceSrgbDisplayIsDisplay true + +// displayp3_display +// Convert CIE XYZ (D65 white) to Apple Display P3 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_dim.a1.0.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_dim.a1.0.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_D60sim_dim.a1.0.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_D60sim_dim.a1.0.0 +#define kOfxColourspaceDisplayp3Display "displayp3_display" +#define kOfxColourspaceDisplayp3DisplayLabel "Display P3 - Display" +#define kOfxColourspaceDisplayp3DisplayEncoding "sdr-video" +#define kOfxColourspaceDisplayp3DisplayIsData false +#define kOfxColourspaceDisplayp3DisplayIsBasic false +#define kOfxColourspaceDisplayp3DisplayIsCore true +#define kOfxColourspaceDisplayp3DisplayIsDisplay true + +// rec1886_rec709_display +// Convert CIE XYZ (D65 white) to Rec.1886/Rec.709 (HD video) +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 +#define kOfxColourspaceRec1886Rec709Display "rec1886_rec709_display" +#define kOfxColourspaceRec1886Rec709DisplayLabel "Rec.1886 Rec.709 - Display" +#define kOfxColourspaceRec1886Rec709DisplayEncoding "sdr-video" +#define kOfxColourspaceRec1886Rec709DisplayIsData false +#define kOfxColourspaceRec1886Rec709DisplayIsBasic false +#define kOfxColourspaceRec1886Rec709DisplayIsCore true +#define kOfxColourspaceRec1886Rec709DisplayIsDisplay true + +// rec1886_rec2020_display +// Convert CIE XYZ (D65 white) to Rec.1886/Rec.2020 (UHD video) +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec2020_100nits_dim.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_P3D65limited_100nits_dim.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_Rec709limited_100nits_dim.a1.1.0 +#define kOfxColourspaceRec1886Rec2020Display "rec1886_rec2020_display" +#define kOfxColourspaceRec1886Rec2020DisplayLabel "Rec.1886 Rec.2020 - Display" +#define kOfxColourspaceRec1886Rec2020DisplayEncoding "sdr-video" +#define kOfxColourspaceRec1886Rec2020DisplayIsData false +#define kOfxColourspaceRec1886Rec2020DisplayIsBasic false +#define kOfxColourspaceRec1886Rec2020DisplayIsCore true +#define kOfxColourspaceRec1886Rec2020DisplayIsDisplay true + +// rec2100_hlg_display +// Convert CIE XYZ (D65 white) to Rec.2100-HLG, 1000 nit +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 +#define kOfxColourspaceRec2100HlgDisplay "rec2100_hlg_display" +#define kOfxColourspaceRec2100HlgDisplayLabel "Rec.2100-HLG - Display" +#define kOfxColourspaceRec2100HlgDisplayEncoding "hdr-video" +#define kOfxColourspaceRec2100HlgDisplayIsData false +#define kOfxColourspaceRec2100HlgDisplayIsBasic false +#define kOfxColourspaceRec2100HlgDisplayIsCore true +#define kOfxColourspaceRec2100HlgDisplayIsDisplay true + +// rec2100_pq_display +// Convert CIE XYZ (D65 white) to Rec.2100-PQ +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 +#define kOfxColourspaceRec2100PqDisplay "rec2100_pq_display" +#define kOfxColourspaceRec2100PqDisplayLabel "Rec.2100-PQ - Display" +#define kOfxColourspaceRec2100PqDisplayEncoding "hdr-video" +#define kOfxColourspaceRec2100PqDisplayIsData false +#define kOfxColourspaceRec2100PqDisplayIsBasic false +#define kOfxColourspaceRec2100PqDisplayIsCore true +#define kOfxColourspaceRec2100PqDisplayIsDisplay true + +// st2084_p3d65_display +// Convert CIE XYZ (D65 white) to ST-2084 (PQ), P3-D65 primaries +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 +#define kOfxColourspaceSt2084P3d65Display "st2084_p3d65_display" +#define kOfxColourspaceSt2084P3d65DisplayLabel "ST2084-P3-D65 - Display" +#define kOfxColourspaceSt2084P3d65DisplayEncoding "hdr-video" +#define kOfxColourspaceSt2084P3d65DisplayIsData false +#define kOfxColourspaceSt2084P3d65DisplayIsBasic false +#define kOfxColourspaceSt2084P3d65DisplayIsCore true +#define kOfxColourspaceSt2084P3d65DisplayIsDisplay true + +// p3d65_display +// Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D65 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_48nits.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_48nits.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_Rec709limited_48nits.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_D60sim_48nits.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_D60sim_48nits.a1.1.0 +#define kOfxColourspaceP3d65Display "p3d65_display" +#define kOfxColourspaceP3d65DisplayLabel "P3-D65 - Display" +#define kOfxColourspaceP3d65DisplayEncoding "sdr-video" +#define kOfxColourspaceP3d65DisplayIsData false +#define kOfxColourspaceP3d65DisplayIsBasic false +#define kOfxColourspaceP3d65DisplayIsCore true +#define kOfxColourspaceP3d65DisplayIsDisplay true + +// ACES2065-1 +// The "Academy Color Encoding System" reference colorspace. +#define kOfxColourspaceACES20651 "ACES2065-1" +#define kOfxColourspaceACES20651Label "ACES2065-1" +#define kOfxColourspaceACES20651Encoding "scene-linear" +#define kOfxColourspaceACES20651IsData false +#define kOfxColourspaceACES20651IsBasic false +#define kOfxColourspaceACES20651IsCore true +#define kOfxColourspaceACES20651IsDisplay false + +// ACEScc +// Convert ACEScc to ACES2065-1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScc_to_ACES.a1.0.3 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScc.a1.0.3 +#define kOfxColourspaceACEScc "ACEScc" +#define kOfxColourspaceACESccLabel "ACEScc" +#define kOfxColourspaceACESccEncoding "log" +#define kOfxColourspaceACESccIsData false +#define kOfxColourspaceACESccIsBasic false +#define kOfxColourspaceACESccIsCore true +#define kOfxColourspaceACESccIsDisplay false + +// ACEScct +// Convert ACEScct to ACES2065-1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScct_to_ACES.a1.0.3 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScct.a1.0.3 +#define kOfxColourspaceACEScct "ACEScct" +#define kOfxColourspaceACEScctLabel "ACEScct" +#define kOfxColourspaceACEScctEncoding "log" +#define kOfxColourspaceACEScctIsData false +#define kOfxColourspaceACEScctIsBasic false +#define kOfxColourspaceACEScctIsCore true +#define kOfxColourspaceACEScctIsDisplay false + +// ACEScg +// Convert ACEScg to ACES2065-1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScg_to_ACES.a1.0.3 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScg.a1.0.3 +#define kOfxColourspaceACEScg "ACEScg" +#define kOfxColourspaceACEScgLabel "ACEScg" +#define kOfxColourspaceACEScgEncoding "scene-linear" +#define kOfxColourspaceACEScgIsData false +#define kOfxColourspaceACEScgIsBasic false +#define kOfxColourspaceACEScgIsCore true +#define kOfxColourspaceACEScgIsDisplay false + +// lin_p3d65 +// Convert ACES2065-1 to linear P3 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_P3-D65:1.0 +#define kOfxColourspaceLinP3d65 "lin_p3d65" +#define kOfxColourspaceLinP3d65Label "Linear P3-D65" +#define kOfxColourspaceLinP3d65Encoding "scene-linear" +#define kOfxColourspaceLinP3d65IsData false +#define kOfxColourspaceLinP3d65IsBasic false +#define kOfxColourspaceLinP3d65IsCore true +#define kOfxColourspaceLinP3d65IsDisplay false + +// lin_rec2020 +// Convert ACES2065-1 to linear Rec.2020 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_Rec2020:1.0 +#define kOfxColourspaceLinRec2020 "lin_rec2020" +#define kOfxColourspaceLinRec2020Label "Linear Rec.2020" +#define kOfxColourspaceLinRec2020Encoding "scene-linear" +#define kOfxColourspaceLinRec2020IsData false +#define kOfxColourspaceLinRec2020IsBasic false +#define kOfxColourspaceLinRec2020IsCore true +#define kOfxColourspaceLinRec2020IsDisplay false + +// lin_rec709_srgb +// Convert ACES2065-1 to linear Rec.709 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_Rec709:1.0 +#define kOfxColourspaceLinRec709Srgb "lin_rec709_srgb" +#define kOfxColourspaceLinRec709SrgbLabel "Linear Rec.709 (sRGB)" +#define kOfxColourspaceLinRec709SrgbEncoding "scene-linear" +#define kOfxColourspaceLinRec709SrgbIsData false +#define kOfxColourspaceLinRec709SrgbIsBasic false +#define kOfxColourspaceLinRec709SrgbIsCore true +#define kOfxColourspaceLinRec709SrgbIsDisplay false + +// g18_rec709_tx +// Convert ACES2065-1 to 1.8 gamma-corrected Rec.709 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma1.8_Rec709-Texture:1.0 +#define kOfxColourspaceG18Rec709Tx "g18_rec709_tx" +#define kOfxColourspaceG18Rec709TxLabel "Gamma 1.8 Rec.709 - Texture" +#define kOfxColourspaceG18Rec709TxEncoding "sdr-video" +#define kOfxColourspaceG18Rec709TxIsData false +#define kOfxColourspaceG18Rec709TxIsBasic false +#define kOfxColourspaceG18Rec709TxIsCore true +#define kOfxColourspaceG18Rec709TxIsDisplay false + +// g22_ap1_tx +// Convert ACES2065-1 to 2.2 gamma-corrected AP1 primaries, ACES ~=D60 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.2_AP1-Texture:1.0 +#define kOfxColourspaceG22Ap1Tx "g22_ap1_tx" +#define kOfxColourspaceG22Ap1TxLabel "Gamma 2.2 AP1 - Texture" +#define kOfxColourspaceG22Ap1TxEncoding "sdr-video" +#define kOfxColourspaceG22Ap1TxIsData false +#define kOfxColourspaceG22Ap1TxIsBasic false +#define kOfxColourspaceG22Ap1TxIsCore true +#define kOfxColourspaceG22Ap1TxIsDisplay false + +// g22_rec709_tx +// Convert ACES2065-1 to 2.2 gamma-corrected Rec.709 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.2_Rec709-Texture:1.0 +#define kOfxColourspaceG22Rec709Tx "g22_rec709_tx" +#define kOfxColourspaceG22Rec709TxLabel "Gamma 2.2 Rec.709 - Texture" +#define kOfxColourspaceG22Rec709TxEncoding "sdr-video" +#define kOfxColourspaceG22Rec709TxIsData false +#define kOfxColourspaceG22Rec709TxIsBasic false +#define kOfxColourspaceG22Rec709TxIsCore true +#define kOfxColourspaceG22Rec709TxIsDisplay false + +// g24_rec709_tx +// Convert ACES2065-1 to 2.4 gamma-corrected Rec.709 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.4_Rec709-Texture:1.0 +#define kOfxColourspaceG24Rec709Tx "g24_rec709_tx" +#define kOfxColourspaceG24Rec709TxLabel "Gamma 2.4 Rec.709 - Texture" +#define kOfxColourspaceG24Rec709TxEncoding "sdr-video" +#define kOfxColourspaceG24Rec709TxIsData false +#define kOfxColourspaceG24Rec709TxIsBasic false +#define kOfxColourspaceG24Rec709TxIsCore true +#define kOfxColourspaceG24Rec709TxIsDisplay false + +// srgb_encoded_ap1_tx +// Convert ACES2065-1 to sRGB Encoded AP1 primaries, ACES ~=D60 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB_Encoded_AP1-Texture:1.0 +#define kOfxColourspaceSrgbEncodedAp1Tx "srgb_encoded_ap1_tx" +#define kOfxColourspaceSrgbEncodedAp1TxLabel "sRGB Encoded AP1 - Texture" +#define kOfxColourspaceSrgbEncodedAp1TxEncoding "sdr-video" +#define kOfxColourspaceSrgbEncodedAp1TxIsData false +#define kOfxColourspaceSrgbEncodedAp1TxIsBasic false +#define kOfxColourspaceSrgbEncodedAp1TxIsCore true +#define kOfxColourspaceSrgbEncodedAp1TxIsDisplay false + +// srgb_encoded_p3d65_tx +// Convert ACES2065-1 to sRGB Encoded P3-D65 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB_Encoded_P3-D65-Texture:1.0 +#define kOfxColourspaceSrgbEncodedP3d65Tx "srgb_encoded_p3d65_tx" +#define kOfxColourspaceSrgbEncodedP3d65TxLabel "sRGB Encoded P3-D65 - Texture" +#define kOfxColourspaceSrgbEncodedP3d65TxEncoding "sdr-video" +#define kOfxColourspaceSrgbEncodedP3d65TxIsData false +#define kOfxColourspaceSrgbEncodedP3d65TxIsBasic false +#define kOfxColourspaceSrgbEncodedP3d65TxIsCore true +#define kOfxColourspaceSrgbEncodedP3d65TxIsDisplay false + +// srgb_tx +// Convert ACES2065-1 to sRGB +// CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB-Texture:1.0 +#define kOfxColourspaceSrgbTx "srgb_tx" +#define kOfxColourspaceSrgbTxLabel "sRGB - Texture" +#define kOfxColourspaceSrgbTxEncoding "sdr-video" +#define kOfxColourspaceSrgbTxIsData false +#define kOfxColourspaceSrgbTxIsBasic false +#define kOfxColourspaceSrgbTxIsCore true +#define kOfxColourspaceSrgbTxIsDisplay false + +// Raw +// The utility "Raw" colorspace. +#define kOfxColourspaceRaw "Raw" +#define kOfxColourspaceRawLabel "Raw" +#define kOfxColourspaceRawEncoding "" +#define kOfxColourspaceRawIsData true +#define kOfxColourspaceRawIsBasic false +#define kOfxColourspaceRawIsCore true +#define kOfxColourspaceRawIsDisplay false + +// Non-core Colourspaces + +// CIE-XYZ-D65 +// The "CIE XYZ (D65)" display connection colorspace. +#define kOfxColourspaceCIEXYZD65 "CIE-XYZ-D65" +#define kOfxColourspaceCIEXYZD65Label "CIE-XYZ-D65" +#define kOfxColourspaceCIEXYZD65Encoding "" +#define kOfxColourspaceCIEXYZD65IsData false +#define kOfxColourspaceCIEXYZD65IsBasic false +#define kOfxColourspaceCIEXYZD65IsCore false +#define kOfxColourspaceCIEXYZD65IsDisplay true + +// p3d60_display +// Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D60 (Bradford adaptation) +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D60_48nits.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D60_48nits.a1.0.3 +#define kOfxColourspaceP3d60Display "p3d60_display" +#define kOfxColourspaceP3d60DisplayLabel "P3-D60 - Display" +#define kOfxColourspaceP3d60DisplayEncoding "sdr-video" +#define kOfxColourspaceP3d60DisplayIsData false +#define kOfxColourspaceP3d60DisplayIsBasic false +#define kOfxColourspaceP3d60DisplayIsCore false +#define kOfxColourspaceP3d60DisplayIsDisplay true + +// p3_dci_display +// Convert CIE XYZ (D65 white) to Gamma 2.6, P3-DCI (DCI white with Bradford adaptation) +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_48nits.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_48nits.a1.0.3 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_D65sim_48nits.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_D65sim_48nits.a1.1.0 +#define kOfxColourspaceP3DciDisplay "p3_dci_display" +#define kOfxColourspaceP3DciDisplayLabel "P3-DCI - Display" +#define kOfxColourspaceP3DciDisplayEncoding "sdr-video" +#define kOfxColourspaceP3DciDisplayIsData false +#define kOfxColourspaceP3DciDisplayIsBasic false +#define kOfxColourspaceP3DciDisplayIsCore false +#define kOfxColourspaceP3DciDisplayIsDisplay true + +// ADX10 +// Convert ADX10 to ACES2065-1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ADX10_to_ACES.a1.0.3 +#define kOfxColourspaceADX10 "ADX10" +#define kOfxColourspaceADX10Label "ADX10" +#define kOfxColourspaceADX10Encoding "log" +#define kOfxColourspaceADX10IsData false +#define kOfxColourspaceADX10IsBasic false +#define kOfxColourspaceADX10IsCore false +#define kOfxColourspaceADX10IsDisplay false + +// ADX16 +// Convert ADX16 to ACES2065-1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ADX16_to_ACES.a1.0.3 +#define kOfxColourspaceADX16 "ADX16" +#define kOfxColourspaceADX16Label "ADX16" +#define kOfxColourspaceADX16Encoding "log" +#define kOfxColourspaceADX16IsData false +#define kOfxColourspaceADX16IsBasic false +#define kOfxColourspaceADX16IsCore false +#define kOfxColourspaceADX16IsDisplay false + +// lin_arri_wide_gamut_3 +// Convert Linear ARRI Wide Gamut 3 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:Linear_ARRI_Wide_Gamut_3_to_ACES2065-1:1.0 +#define kOfxColourspaceLinArriWideGamut3 "lin_arri_wide_gamut_3" +#define kOfxColourspaceLinArriWideGamut3Label "Linear ARRI Wide Gamut 3" +#define kOfxColourspaceLinArriWideGamut3Encoding "scene-linear" +#define kOfxColourspaceLinArriWideGamut3IsData false +#define kOfxColourspaceLinArriWideGamut3IsBasic false +#define kOfxColourspaceLinArriWideGamut3IsCore false +#define kOfxColourspaceLinArriWideGamut3IsDisplay false + +// arri_logc3_ei800 +// Convert ARRI LogC3 (EI800) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC3_EI800_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.ARRI.Alexa-v3-logC-EI800.a1.v2 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_LogC_EI800_AWG.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.LogC_EI800_AWG_to_ACES.a1.1.0 +#define kOfxColourspaceArriLogc3Ei800 "arri_logc3_ei800" +#define kOfxColourspaceArriLogc3Ei800Label "ARRI LogC3 (EI800)" +#define kOfxColourspaceArriLogc3Ei800Encoding "log" +#define kOfxColourspaceArriLogc3Ei800IsData false +#define kOfxColourspaceArriLogc3Ei800IsBasic false +#define kOfxColourspaceArriLogc3Ei800IsCore false +#define kOfxColourspaceArriLogc3Ei800IsDisplay false + +// lin_arri_wide_gamut_4 +// Convert Linear ARRI Wide Gamut 4 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:Linear_ARRI_Wide_Gamut_4_to_ACES2065-1:1.0 +#define kOfxColourspaceLinArriWideGamut4 "lin_arri_wide_gamut_4" +#define kOfxColourspaceLinArriWideGamut4Label "Linear ARRI Wide Gamut 4" +#define kOfxColourspaceLinArriWideGamut4Encoding "scene-linear" +#define kOfxColourspaceLinArriWideGamut4IsData false +#define kOfxColourspaceLinArriWideGamut4IsBasic false +#define kOfxColourspaceLinArriWideGamut4IsCore false +#define kOfxColourspaceLinArriWideGamut4IsDisplay false + +// arri_logc4 +// Convert ARRI LogC4 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC4_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.ARRI.ARRI-LogC4.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.LogC4_to_ACES.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_LogC4.a1.1.0 +#define kOfxColourspaceArriLogc4 "arri_logc4" +#define kOfxColourspaceArriLogc4Label "ARRI LogC4" +#define kOfxColourspaceArriLogc4Encoding "log" +#define kOfxColourspaceArriLogc4IsData false +#define kOfxColourspaceArriLogc4IsBasic false +#define kOfxColourspaceArriLogc4IsCore false +#define kOfxColourspaceArriLogc4IsDisplay false + +// bmdfilm_widegamut_gen5 +// Convert Blackmagic Film Wide Gamut (Gen 5) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:BMDFilm_WideGamut_Gen5_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.BlackmagicDesign.BMDFilm_WideGamut_Gen5.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_BMDFilm_WideGamut_Gen5.a1.v1 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.BMDFilm_WideGamut_Gen5_to_ACES.a1.v1 +#define kOfxColourspaceBmdfilmWidegamutGen5 "bmdfilm_widegamut_gen5" +#define kOfxColourspaceBmdfilmWidegamutGen5Label "BMDFilm WideGamut Gen5" +#define kOfxColourspaceBmdfilmWidegamutGen5Encoding "log" +#define kOfxColourspaceBmdfilmWidegamutGen5IsData false +#define kOfxColourspaceBmdfilmWidegamutGen5IsBasic false +#define kOfxColourspaceBmdfilmWidegamutGen5IsCore false +#define kOfxColourspaceBmdfilmWidegamutGen5IsDisplay false + +// davinci_intermediate_widegamut +// Convert DaVinci Intermediate Wide Gamut to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:DaVinci_Intermediate_WideGamut_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.DaVinci_Intermediate_WideGamut_to_ACES.a1.v1 +#define kOfxColourspaceDavinciIntermediateWidegamut "davinci_intermediate_widegamut" +#define kOfxColourspaceDavinciIntermediateWidegamutLabel "DaVinci Intermediate WideGamut" +#define kOfxColourspaceDavinciIntermediateWidegamutEncoding "log" +#define kOfxColourspaceDavinciIntermediateWidegamutIsData false +#define kOfxColourspaceDavinciIntermediateWidegamutIsBasic false +#define kOfxColourspaceDavinciIntermediateWidegamutIsCore false +#define kOfxColourspaceDavinciIntermediateWidegamutIsDisplay false + +// lin_bmd_widegamut_gen5 +// Convert Linear Blackmagic Wide Gamut (Gen 5) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:Linear_BMD_WideGamut_Gen5_to_ACES2065-1:1.0 +#define kOfxColourspaceLinBmdWidegamutGen5 "lin_bmd_widegamut_gen5" +#define kOfxColourspaceLinBmdWidegamutGen5Label "Linear BMD WideGamut Gen5" +#define kOfxColourspaceLinBmdWidegamutGen5Encoding "scene-linear" +#define kOfxColourspaceLinBmdWidegamutGen5IsData false +#define kOfxColourspaceLinBmdWidegamutGen5IsBasic false +#define kOfxColourspaceLinBmdWidegamutGen5IsCore false +#define kOfxColourspaceLinBmdWidegamutGen5IsDisplay false + +// lin_davinci_widegamut +// Convert Linear DaVinci Wide Gamut to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:Linear_DaVinci_WideGamut_to_ACES2065-1:1.0 +#define kOfxColourspaceLinDavinciWidegamut "lin_davinci_widegamut" +#define kOfxColourspaceLinDavinciWidegamutLabel "Linear DaVinci WideGamut" +#define kOfxColourspaceLinDavinciWidegamutEncoding "scene-linear" +#define kOfxColourspaceLinDavinciWidegamutIsData false +#define kOfxColourspaceLinDavinciWidegamutIsBasic false +#define kOfxColourspaceLinDavinciWidegamutIsCore false +#define kOfxColourspaceLinDavinciWidegamutIsDisplay false + +// canonlog2_cinemagamut_d55 +// Convert Canon Log 2 Cinema Gamut (Daylight) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CanonLog2_CinemaGamut-D55_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.CLog2_CGamut_to_ACES.a1.1.0 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_CLog2_CGamut.a1.1.0 +#define kOfxColourspaceCanonlog2CinemagamutD55 "canonlog2_cinemagamut_d55" +#define kOfxColourspaceCanonlog2CinemagamutD55Label "CanonLog2 CinemaGamut D55" +#define kOfxColourspaceCanonlog2CinemagamutD55Encoding "log" +#define kOfxColourspaceCanonlog2CinemagamutD55IsData false +#define kOfxColourspaceCanonlog2CinemagamutD55IsBasic false +#define kOfxColourspaceCanonlog2CinemagamutD55IsCore false +#define kOfxColourspaceCanonlog2CinemagamutD55IsDisplay false + +// canonlog3_cinemagamut_d55 +// Convert Canon Log 3 Cinema Gamut (Daylight) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CanonLog3_CinemaGamut-D55_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.CLog3_CGamut_to_ACES.a1.1.0 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_CLog3_CGamut.a1.1.0 +#define kOfxColourspaceCanonlog3CinemagamutD55 "canonlog3_cinemagamut_d55" +#define kOfxColourspaceCanonlog3CinemagamutD55Label "CanonLog3 CinemaGamut D55" +#define kOfxColourspaceCanonlog3CinemagamutD55Encoding "log" +#define kOfxColourspaceCanonlog3CinemagamutD55IsData false +#define kOfxColourspaceCanonlog3CinemagamutD55IsBasic false +#define kOfxColourspaceCanonlog3CinemagamutD55IsCore false +#define kOfxColourspaceCanonlog3CinemagamutD55IsDisplay false + +// lin_cinemagamut_d55 +// Convert Linear Canon Cinema Gamut (Daylight) to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:Linear-CinemaGamut-D55_to_ACES2065-1:1.0 +#define kOfxColourspaceLinCinemagamutD55 "lin_cinemagamut_d55" +#define kOfxColourspaceLinCinemagamutD55Label "Linear CinemaGamut D55" +#define kOfxColourspaceLinCinemagamutD55Encoding "scene-linear" +#define kOfxColourspaceLinCinemagamutD55IsData false +#define kOfxColourspaceLinCinemagamutD55IsBasic false +#define kOfxColourspaceLinCinemagamutD55IsCore false +#define kOfxColourspaceLinCinemagamutD55IsDisplay false + +// lin_vgamut +// Convert Linear Panasonic V-Gamut to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Panasonic:Input:Linear_VGamut_to_ACES2065-1:1.0 +#define kOfxColourspaceLinVgamut "lin_vgamut" +#define kOfxColourspaceLinVgamutLabel "Linear V-Gamut" +#define kOfxColourspaceLinVgamutEncoding "scene-linear" +#define kOfxColourspaceLinVgamutIsData false +#define kOfxColourspaceLinVgamutIsBasic false +#define kOfxColourspaceLinVgamutIsCore false +#define kOfxColourspaceLinVgamutIsDisplay false + +// vlog_vgamut +// Convert Panasonic V-Log - V-Gamut to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Panasonic:Input:VLog_VGamut_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.VLog_VGamut_to_ACES.a1.1.0 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_VLog_VGamut.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Panasonic.VLog_VGamut.a1.v1 +#define kOfxColourspaceVlogVgamut "vlog_vgamut" +#define kOfxColourspaceVlogVgamutLabel "V-Log V-Gamut" +#define kOfxColourspaceVlogVgamutEncoding "log" +#define kOfxColourspaceVlogVgamutIsData false +#define kOfxColourspaceVlogVgamutIsBasic false +#define kOfxColourspaceVlogVgamutIsCore false +#define kOfxColourspaceVlogVgamutIsDisplay false + +// lin_redwidegamutrgb +// Convert Linear REDWideGamutRGB to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:RED:Input:Linear_REDWideGamutRGB_to_ACES2065-1:1.0 +#define kOfxColourspaceLinRedwidegamutrgb "lin_redwidegamutrgb" +#define kOfxColourspaceLinRedwidegamutrgbLabel "Linear REDWideGamutRGB" +#define kOfxColourspaceLinRedwidegamutrgbEncoding "scene-linear" +#define kOfxColourspaceLinRedwidegamutrgbIsData false +#define kOfxColourspaceLinRedwidegamutrgbIsBasic false +#define kOfxColourspaceLinRedwidegamutrgbIsCore false +#define kOfxColourspaceLinRedwidegamutrgbIsDisplay false + +// log3g10_redwidegamutrgb +// Convert RED Log3G10 REDWideGamutRGB to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:RED:Input:Log3G10_REDWideGamutRGB_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.RED.Log3G10_REDWideGamutRGB.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_Log3G10_RWG.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.Log3G10_RWG_to_ACES.a1.1.0 +#define kOfxColourspaceLog3g10Redwidegamutrgb "log3g10_redwidegamutrgb" +#define kOfxColourspaceLog3g10RedwidegamutrgbLabel "Log3G10 REDWideGamutRGB" +#define kOfxColourspaceLog3g10RedwidegamutrgbEncoding "log" +#define kOfxColourspaceLog3g10RedwidegamutrgbIsData false +#define kOfxColourspaceLog3g10RedwidegamutrgbIsBasic false +#define kOfxColourspaceLog3g10RedwidegamutrgbIsCore false +#define kOfxColourspaceLog3g10RedwidegamutrgbIsDisplay false + +// lin_sgamut3 +// Convert Linear S-Gamut3 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_SGamut3_to_ACES2065-1:1.0 +#define kOfxColourspaceLinSgamut3 "lin_sgamut3" +#define kOfxColourspaceLinSgamut3Label "Linear S-Gamut3" +#define kOfxColourspaceLinSgamut3Encoding "scene-linear" +#define kOfxColourspaceLinSgamut3IsData false +#define kOfxColourspaceLinSgamut3IsBasic false +#define kOfxColourspaceLinSgamut3IsCore false +#define kOfxColourspaceLinSgamut3IsDisplay false + +// lin_sgamut3cine +// Convert Linear S-Gamut3.Cine to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_SGamut3Cine_to_ACES2065-1:1.0 +#define kOfxColourspaceLinSgamut3cine "lin_sgamut3cine" +#define kOfxColourspaceLinSgamut3cineLabel "Linear S-Gamut3.Cine" +#define kOfxColourspaceLinSgamut3cineEncoding "scene-linear" +#define kOfxColourspaceLinSgamut3cineIsData false +#define kOfxColourspaceLinSgamut3cineIsBasic false +#define kOfxColourspaceLinSgamut3cineIsCore false +#define kOfxColourspaceLinSgamut3cineIsDisplay false + +// lin_venice_sgamut3 +// Convert Linear Venice S-Gamut3 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_Venice_SGamut3_to_ACES2065-1:1.0 +#define kOfxColourspaceLinVeniceSgamut3 "lin_venice_sgamut3" +#define kOfxColourspaceLinVeniceSgamut3Label "Linear Venice S-Gamut3" +#define kOfxColourspaceLinVeniceSgamut3Encoding "scene-linear" +#define kOfxColourspaceLinVeniceSgamut3IsData false +#define kOfxColourspaceLinVeniceSgamut3IsBasic false +#define kOfxColourspaceLinVeniceSgamut3IsCore false +#define kOfxColourspaceLinVeniceSgamut3IsDisplay false + +// lin_venice_sgamut3cine +// Convert Linear Venice S-Gamut3.Cine to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_Venice_SGamut3Cine_to_ACES2065-1:1.0 +#define kOfxColourspaceLinVeniceSgamut3cine "lin_venice_sgamut3cine" +#define kOfxColourspaceLinVeniceSgamut3cineLabel "Linear Venice S-Gamut3.Cine" +#define kOfxColourspaceLinVeniceSgamut3cineEncoding "scene-linear" +#define kOfxColourspaceLinVeniceSgamut3cineIsData false +#define kOfxColourspaceLinVeniceSgamut3cineIsBasic false +#define kOfxColourspaceLinVeniceSgamut3cineIsCore false +#define kOfxColourspaceLinVeniceSgamut3cineIsDisplay false + +// slog3_sgamut3 +// Convert Sony S-Log3 S-Gamut3 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_SGamut3_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.SLog3_SGamut3.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_SGamut3.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_SGamut3_to_ACES.a1.1.0 +#define kOfxColourspaceSlog3Sgamut3 "slog3_sgamut3" +#define kOfxColourspaceSlog3Sgamut3Label "S-Log3 S-Gamut3" +#define kOfxColourspaceSlog3Sgamut3Encoding "log" +#define kOfxColourspaceSlog3Sgamut3IsData false +#define kOfxColourspaceSlog3Sgamut3IsBasic false +#define kOfxColourspaceSlog3Sgamut3IsCore false +#define kOfxColourspaceSlog3Sgamut3IsDisplay false + +// slog3_sgamut3cine +// Convert Sony S-Log3 S-Gamut3.Cine to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_SGamut3Cine_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.SLog3_SGamut3Cine.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_SGamut3Cine.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_SGamut3Cine_to_ACES.a1.1.0 +#define kOfxColourspaceSlog3Sgamut3cine "slog3_sgamut3cine" +#define kOfxColourspaceSlog3Sgamut3cineLabel "S-Log3 S-Gamut3.Cine" +#define kOfxColourspaceSlog3Sgamut3cineEncoding "log" +#define kOfxColourspaceSlog3Sgamut3cineIsData false +#define kOfxColourspaceSlog3Sgamut3cineIsBasic false +#define kOfxColourspaceSlog3Sgamut3cineIsCore false +#define kOfxColourspaceSlog3Sgamut3cineIsDisplay false + +// slog3_venice_sgamut3 +// Convert Sony S-Log3 Venice S-Gamut3 to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_Venice_SGamut3_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.Venice_SLog3_SGamut3.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_Venice_SGamut3.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_Venice_SGamut3_to_ACES.a1.1.0 +#define kOfxColourspaceSlog3VeniceSgamut3 "slog3_venice_sgamut3" +#define kOfxColourspaceSlog3VeniceSgamut3Label "S-Log3 Venice S-Gamut3" +#define kOfxColourspaceSlog3VeniceSgamut3Encoding "log" +#define kOfxColourspaceSlog3VeniceSgamut3IsData false +#define kOfxColourspaceSlog3VeniceSgamut3IsBasic false +#define kOfxColourspaceSlog3VeniceSgamut3IsCore false +#define kOfxColourspaceSlog3VeniceSgamut3IsDisplay false + +// slog3_venice_sgamut3cine +// Convert Sony S-Log3 Venice S-Gamut3.Cine to ACES2065-1 +// CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_Venice_SGamut3Cine_to_ACES2065-1:1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.Venice_SLog3_SGamut3Cine.a1.v1 +// AMF Components +// -------------- +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_Venice_SGamut3Cine.a1.1.0 +// ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_Venice_SGamut3Cine_to_ACES.a1.1.0 +#define kOfxColourspaceSlog3VeniceSgamut3cine "slog3_venice_sgamut3cine" +#define kOfxColourspaceSlog3VeniceSgamut3cineLabel "S-Log3 Venice S-Gamut3.Cine" +#define kOfxColourspaceSlog3VeniceSgamut3cineEncoding "log" +#define kOfxColourspaceSlog3VeniceSgamut3cineIsData false +#define kOfxColourspaceSlog3VeniceSgamut3cineIsBasic false +#define kOfxColourspaceSlog3VeniceSgamut3cineIsCore false +#define kOfxColourspaceSlog3VeniceSgamut3cineIsDisplay false + +// camera_rec709 +// Convert ACES2065-1 to Rec.709 camera OETF Rec.709 primaries, D65 white point +// CLFtransformID: urn:aswf:ocio:transformId:1.0:ITU:Utility:AP0_to_Camera_Rec709:1.0 +#define kOfxColourspaceCameraRec709 "camera_rec709" +#define kOfxColourspaceCameraRec709Label "Camera Rec.709" +#define kOfxColourspaceCameraRec709Encoding "sdr-video" +#define kOfxColourspaceCameraRec709IsData false +#define kOfxColourspaceCameraRec709IsBasic false +#define kOfxColourspaceCameraRec709IsCore false +#define kOfxColourspaceCameraRec709IsDisplay false + +/** @brief Roles - standard names used for compatibility with common OCIO configs. +*/ + +/** @brief aces_interchange +Guaranteed to be ACES2065-1. +*/ +#define kOfxColourspaceRoleAcesInterchange "aces_interchange" +#define kOfxColourspaceRoleAcesInterchangeIsBasic false +#define kOfxColourspaceRoleAcesInterchangeIsCore true + +/** @brief cie_xyz_d65_interchange +CIE XYZ colorimetry with the neutral axis at D65. +*/ +#define kOfxColourspaceRoleCieXyzD65Interchange "cie_xyz_d65_interchange" +#define kOfxColourspaceRoleCieXyzD65InterchangeIsBasic false +#define kOfxColourspaceRoleCieXyzD65InterchangeIsCore true + +/** @brief color_picking +The colourspace to use for colour pickers, typically a display colourspace. +*/ +#define kOfxColourspaceRoleColorPicking "color_picking" +#define kOfxColourspaceRoleColorPickingIsBasic false +#define kOfxColourspaceRoleColorPickingIsCore true + +/** @brief color_timing +A colourspace suitable for colour grading, typically a log colourspace. +*/ +#define kOfxColourspaceRoleColorTiming "color_timing" +#define kOfxColourspaceRoleColorTimingIsBasic false +#define kOfxColourspaceRoleColorTimingIsCore true + +/** @brief compositing_log +Any scene-referred colourspace with a log transfer function. +*/ +#define kOfxColourspaceRoleCompositingLog "compositing_log" +#define kOfxColourspaceRoleCompositingLogIsBasic false +#define kOfxColourspaceRoleCompositingLogIsCore true + +/** @brief data +Image values should not be treated as colour, e.g. motion vectors or masks. Mapped to the raw colourspace. +*/ +#define kOfxColourspaceRoleData "data" +#define kOfxColourspaceRoleDataIsBasic false +#define kOfxColourspaceRoleDataIsCore true + +/** @brief matte_paint +A colourspace suitable for matte painting. +*/ +#define kOfxColourspaceRoleMattePaint "matte_paint" +#define kOfxColourspaceRoleMattePaintIsBasic false +#define kOfxColourspaceRoleMattePaintIsCore true + +/** @brief scene_linear +Any scene-referred linear colourspace. +*/ +#define kOfxColourspaceRoleSceneLinear "scene_linear" +#define kOfxColourspaceRoleSceneLinearIsBasic false +#define kOfxColourspaceRoleSceneLinearIsCore true + +/** @brief texture_paint +A colourspace suitable for texture painting, typically sRGB. +*/ +#define kOfxColourspaceRoleTexturePaint "texture_paint" +#define kOfxColourspaceRoleTexturePaintIsBasic false +#define kOfxColourspaceRoleTexturePaintIsCore true + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio b/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio new file mode 100644 index 000000000..d071cf665 --- /dev/null +++ b/third_party/openfx/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio @@ -0,0 +1,1549 @@ +ocio_profile_version: 2.3 + +environment: + {} +search_path: "" +strictparsing: true +luma: [0.2126, 0.7152, 0.0722] +name: ofx-native-v1.5_aces-v1.3_ocio-v2.3 +description: | + OpenFX 1.5 Native Mode Config + Based on: Academy Color Encoding System - Studio Config [COLORSPACES v2.1.0] [ACES v1.3] [OCIO v2.3] + ------------------------------------------------------------------------------------------ + + This "OpenColorIO" config is geared toward studios requiring a config that includes a wide variety of camera colorspaces, displays and looks. + +roles: + aces_interchange: ACES2065-1 + cie_xyz_d65_interchange: CIE-XYZ-D65 + color_picking: sRGB - Texture + color_timing: ACEScct + compositing_log: ACEScct + data: Raw + matte_paint: ACEScct + scene_linear: ACEScg + texture_paint: sRGB - Texture + +file_rules: + - ! {name: Default, colorspace: ACES2065-1} + +shared_views: + - ! {name: ACES 1.0 - SDR Video, view_transform: ACES 1.0 - SDR Video, display_colorspace: } + - ! {name: ACES 1.0 - SDR Video (D60 sim on D65), view_transform: ACES 1.0 - SDR Video (D60 sim on D65), display_colorspace: } + - ! {name: ACES 1.1 - SDR Video (P3 lim), view_transform: ACES 1.1 - SDR Video (P3 lim), display_colorspace: } + - ! {name: ACES 1.1 - SDR Video (Rec.709 lim), view_transform: ACES 1.1 - SDR Video (Rec.709 lim), display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)", view_transform: "ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)", display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (2000 nits & Rec.2020 lim)", view_transform: "ACES 1.1 - HDR Video (2000 nits & Rec.2020 lim)", display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (4000 nits & Rec.2020 lim)", view_transform: "ACES 1.1 - HDR Video (4000 nits & Rec.2020 lim)", display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (1000 nits & P3 lim)", view_transform: "ACES 1.1 - HDR Video (1000 nits & P3 lim)", display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (2000 nits & P3 lim)", view_transform: "ACES 1.1 - HDR Video (2000 nits & P3 lim)", display_colorspace: } + - ! {name: "ACES 1.1 - HDR Video (4000 nits & P3 lim)", view_transform: "ACES 1.1 - HDR Video (4000 nits & P3 lim)", display_colorspace: } + - ! {name: ACES 1.0 - SDR Cinema, view_transform: ACES 1.0 - SDR Cinema, display_colorspace: } + - ! {name: ACES 1.1 - SDR Cinema (Rec.709 lim), view_transform: ACES 1.1 - SDR Cinema (Rec.709 lim), display_colorspace: } + - ! {name: ACES 1.0 - SDR Cinema (D60 sim on DCI), view_transform: ACES 1.0 - SDR Cinema (D60 sim on DCI), display_colorspace: } + - ! {name: ACES 1.1 - SDR Cinema (D60 sim on D65), view_transform: ACES 1.1 - SDR Cinema (D60 sim on D65), display_colorspace: } + - ! {name: ACES 1.1 - SDR Cinema (D65 sim on DCI), view_transform: ACES 1.1 - SDR Cinema (D65 sim on DCI), display_colorspace: } + - ! {name: "ACES 1.1 - HDR Cinema (108 nits & P3 lim)", view_transform: "ACES 1.1 - HDR Cinema (108 nits & P3 lim)", display_colorspace: } + - ! {name: Un-tone-mapped, view_transform: Un-tone-mapped, display_colorspace: } + +displays: + sRGB - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Video, ACES 1.0 - SDR Video (D60 sim on D65), Un-tone-mapped] + Display P3 - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Video, ACES 1.0 - SDR Video (D60 sim on D65), Un-tone-mapped] + Rec.1886 Rec.709 - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Video, ACES 1.0 - SDR Video (D60 sim on D65), Un-tone-mapped] + Rec.1886 Rec.2020 - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Video, ACES 1.1 - SDR Video (P3 lim), ACES 1.1 - SDR Video (Rec.709 lim), Un-tone-mapped] + Rec.2100-HLG - Display: + - ! {name: Raw, colorspace: Raw} + - ! ["ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)", Un-tone-mapped] + Rec.2100-PQ - Display: + - ! {name: Raw, colorspace: Raw} + - ! ["ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)", "ACES 1.1 - HDR Video (2000 nits & Rec.2020 lim)", "ACES 1.1 - HDR Video (4000 nits & Rec.2020 lim)", Un-tone-mapped] + ST2084-P3-D65 - Display: + - ! {name: Raw, colorspace: Raw} + - ! ["ACES 1.1 - HDR Video (1000 nits & P3 lim)", "ACES 1.1 - HDR Video (2000 nits & P3 lim)", "ACES 1.1 - HDR Video (4000 nits & P3 lim)", "ACES 1.1 - HDR Cinema (108 nits & P3 lim)", Un-tone-mapped] + P3-D60 - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Cinema, Un-tone-mapped] + P3-D65 - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Cinema, ACES 1.1 - SDR Cinema (Rec.709 lim), ACES 1.1 - SDR Cinema (D60 sim on D65), Un-tone-mapped] + P3-DCI - Display: + - ! {name: Raw, colorspace: Raw} + - ! [ACES 1.0 - SDR Cinema (D60 sim on DCI), ACES 1.1 - SDR Cinema (D65 sim on DCI), Un-tone-mapped] + +active_displays: [sRGB - Display, Display P3 - Display, Rec.1886 Rec.709 - Display, Rec.1886 Rec.2020 - Display, Rec.2100-HLG - Display, Rec.2100-PQ - Display, ST2084-P3-D65 - Display, P3-D60 - Display, P3-D65 - Display, P3-DCI - Display] +active_views: [ACES 1.0 - SDR Video, ACES 1.0 - SDR Video (D60 sim on D65), ACES 1.1 - SDR Video (P3 lim), ACES 1.1 - SDR Video (Rec.709 lim), "ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)", "ACES 1.1 - HDR Video (2000 nits & Rec.2020 lim)", "ACES 1.1 - HDR Video (4000 nits & Rec.2020 lim)", "ACES 1.1 - HDR Video (1000 nits & P3 lim)", "ACES 1.1 - HDR Video (2000 nits & P3 lim)", "ACES 1.1 - HDR Video (4000 nits & P3 lim)", ACES 1.0 - SDR Cinema, ACES 1.1 - SDR Cinema (Rec.709 lim), ACES 1.0 - SDR Cinema (D60 sim on DCI), ACES 1.1 - SDR Cinema (D60 sim on D65), ACES 1.1 - SDR Cinema (D65 sim on DCI), "ACES 1.1 - HDR Cinema (108 nits & P3 lim)", Un-tone-mapped, Raw] + +looks: + - ! + name: ACES 1.3 Reference Gamut Compression + process_space: ACES2065-1 + description: | + LMT (applied in ACES2065-1) to compress scene-referred values from common cameras into the AP1 gamut + + ACEStransformID: urn:ampas:aces:transformId:v1.5:LMT.Academy.ReferenceGamutCompress.a1.v1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvLMT.Academy.ReferenceGamutCompress.a1.v1.0 + transform: ! {style: ACES-LMT - ACES 1.3 Reference Gamut Compression} + + +default_view_transform: Un-tone-mapped + +view_transforms: + - ! + name: ACES 1.0 - SDR Video + description: | + Component of ACES Output Transforms for SDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_100nits_dim.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec2020_100nits_dim.a1.0.3 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-VIDEO_1.0} + + - ! + name: ACES 1.0 - SDR Video (D60 sim on D65) + description: | + Component of ACES Output Transforms for SDR D65 video simulating D60 white + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_D60sim_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_D60sim_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-VIDEO-D60sim-D65_1.0} + + - ! + name: ACES 1.1 - SDR Video (P3 lim) + description: | + Component of ACES Output Transforms for SDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_P3D65limited_100nits_dim.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-VIDEO-P3lim_1.1} + + - ! + name: ACES 1.1 - SDR Video (Rec.709 lim) + description: | + Component of ACES Output Transforms for SDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_Rec709limited_100nits_dim.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-VIDEO-REC709lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (1000 nits & Rec.2020 lim)" + description: | + Component of ACES Output Transforms for 1000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-1000nit-15nit-REC2020lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (2000 nits & Rec.2020 lim)" + description: | + Component of ACES Output Transforms for 2000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-2000nit-15nit-REC2020lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (4000 nits & Rec.2020 lim)" + description: | + Component of ACES Output Transforms for 4000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-4000nit-15nit-REC2020lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (1000 nits & P3 lim)" + description: | + Component of ACES Output Transforms for 1000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-1000nit-15nit-P3lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (2000 nits & P3 lim)" + description: | + Component of ACES Output Transforms for 2000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-2000nit-15nit-P3lim_1.1} + + - ! + name: "ACES 1.1 - HDR Video (4000 nits & P3 lim)" + description: | + Component of ACES Output Transforms for 4000 nit HDR D65 video + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-VIDEO-4000nit-15nit-P3lim_1.1} + + - ! + name: ACES 1.0 - SDR Cinema + description: | + Component of ACES Output Transforms for SDR cinema + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D60_48nits.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_48nits.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D60_48nits.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_48nits.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-CINEMA_1.0} + + - ! + name: ACES 1.1 - SDR Cinema (Rec.709 lim) + description: | + Component of ACES Output Transforms for SDR cinema + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_Rec709limited_48nits.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-CINEMA-REC709lim_1.1} + + - ! + name: ACES 1.0 - SDR Cinema (D60 sim on DCI) + description: | + Component of ACES Output Transforms for SDR DCI cinema simulating D60 white + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_48nits.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_48nits.a1.0.3 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-CINEMA-D60sim-DCI_1.0} + + - ! + name: ACES 1.1 - SDR Cinema (D60 sim on D65) + description: | + Component of ACES Output Transforms for SDR D65 cinema simulating D60 white + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_D60sim_48nits.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_D60sim_48nits.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-CINEMA-D60sim-D65_1.1} + + - ! + name: ACES 1.1 - SDR Cinema (D65 sim on DCI) + description: | + Component of ACES Output Transforms for SDR DCI cinema simulating D65 white + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_D65sim_48nits.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_D65sim_48nits.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - SDR-CINEMA-D65sim-DCI_1.1} + + - ! + name: "ACES 1.1 - HDR Cinema (108 nits & P3 lim)" + description: | + Component of ACES Output Transforms for 108 nit HDR D65 cinema + + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 + from_scene_reference: ! {style: ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-CINEMA-108nit-7.2nit-P3lim_1.1} + + - ! + name: Un-tone-mapped + from_scene_reference: ! {style: UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD} + +display_colorspaces: + - ! + name: CIE-XYZ-D65 + aliases: [cie_xyz_d65] + family: "" + equalitygroup: "" + bitdepth: 32f + description: The "CIE XYZ (D65)" display connection colorspace. + isdata: false + allocation: uniform + + - ! + name: sRGB - Display + aliases: [srgb_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to sRGB (piecewise EOTF) + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.RGBmonitor_D60sim_100nits_dim.a1.0.3 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_sRGB} + + - ! + name: Display P3 - Display + aliases: [displayp3_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Apple Display P3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.DisplayP3_D60sim_dim.a1.0.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.DisplayP3_D60sim_dim.a1.0.0 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_DisplayP3} + + - ! + name: Rec.1886 Rec.709 - Display + aliases: [rec1886_rec709_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Rec.1886/Rec.709 (HD video) + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec709_D60sim_100nits_dim.a1.0.3 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.709} + + - ! + name: Rec.1886 Rec.2020 - Display + aliases: [rec1886_rec2020_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Rec.1886/Rec.2020 (UHD video) + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.Rec2020_100nits_dim.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_P3D65limited_100nits_dim.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.Rec2020_Rec709limited_100nits_dim.a1.1.0 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.2020} + + - ! + name: Rec.2100-HLG - Display + aliases: [rec2100_hlg_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Rec.2100-HLG, 1000 nit + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_HLG.a1.1.0 + isdata: false + categories: [file-io] + encoding: hdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_REC.2100-HLG-1000nit} + + - ! + name: Rec.2100-PQ - Display + aliases: [rec2100_pq_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Rec.2100-PQ + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_1000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_2000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.Rec2020_4000nits_15nits_ST2084.a1.1.0 + isdata: false + categories: [file-io] + encoding: hdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_REC.2100-PQ} + + - ! + name: ST2084-P3-D65 - Display + aliases: [st2084_p3d65_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to ST-2084 (PQ), P3-D65 primaries + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_1000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_2000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_4000nits_15nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:RRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvRRTODT.Academy.P3D65_108nits_7point2nits_ST2084.a1.1.0 + isdata: false + categories: [file-io] + encoding: hdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_ST2084-P3-D65} + + - ! + name: P3-D60 - Display + aliases: [p3d60_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D60 (Bradford adaptation) + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D60_48nits.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D60_48nits.a1.0.3 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D60-BFD} + + - ! + name: P3-D65 - Display + aliases: [p3d65_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D65 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_48nits.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_48nits.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_Rec709limited_48nits.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3D65_D60sim_48nits.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3D65_D60sim_48nits.a1.1.0 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D65} + + - ! + name: P3-DCI - Display + aliases: [p3_dci_display] + family: Display + equalitygroup: "" + bitdepth: 32f + description: | + Convert CIE XYZ (D65 white) to Gamma 2.6, P3-DCI (DCI white with Bradford adaptation) + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_48nits.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_48nits.a1.0.3 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ODT.Academy.P3DCI_D65sim_48nits.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:InvODT.Academy.P3DCI_D65sim_48nits.a1.1.0 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_G2.6-P3-DCI-BFD} + +colorspaces: + - ! + name: ACES2065-1 + aliases: [aces2065_1, ACES - ACES2065-1, lin_ap0] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: The "Academy Color Encoding System" reference colorspace. + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + + - ! + name: ACEScc + aliases: [ACES - ACEScc, acescc_ap1] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACEScc to ACES2065-1 + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScc_to_ACES.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScc.a1.0.3 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! {style: ACEScc_to_ACES2065-1} + + - ! + name: ACEScct + aliases: [ACES - ACEScct, acescct_ap1] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACEScct to ACES2065-1 + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScct_to_ACES.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScct.a1.0.3 + isdata: false + categories: [file-io, working-space] + encoding: log + allocation: uniform + to_scene_reference: ! {style: ACEScct_to_ACES2065-1} + + - ! + name: ACEScg + aliases: [ACES - ACEScg, lin_ap1] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACEScg to ACES2065-1 + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACEScg_to_ACES.a1.0.3 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_ACEScg.a1.0.3 + isdata: false + categories: [file-io, working-space, texture] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! {style: ACEScg_to_ACES2065-1} + + - ! + name: ADX10 + aliases: [Input - ADX - ADX10] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: | + Convert ADX10 to ACES2065-1 + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ADX10_to_ACES.a1.0.3 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! {style: ADX10_to_ACES2065-1} + + - ! + name: ADX16 + aliases: [Input - ADX - ADX16] + family: ACES + equalitygroup: "" + bitdepth: 32f + description: | + Convert ADX16 to ACES2065-1 + + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ADX16_to_ACES.a1.0.3 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! {style: ADX16_to_ACES2065-1} + + - ! + name: Linear ARRI Wide Gamut 3 + aliases: [lin_arri_wide_gamut_3, Input - ARRI - Linear - ALEXA Wide Gamut, lin_alexawide] + family: Input/ARRI + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear ARRI Wide Gamut 3 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:Linear_ARRI_Wide_Gamut_3_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear ARRI Wide Gamut 3 to ACES2065-1 + children: + - ! {matrix: [0.680205505106279, 0.236136601606481, 0.0836578932872398, 0, 0.0854149797421404, 1.01747087860704, -0.102885858349182, 0, 0.00205652166929683, -0.0625625003847921, 1.06050597871549, 0, 0, 0, 0, 1]} + + - ! + name: ARRI LogC3 (EI800) + aliases: [arri_logc3_ei800, Input - ARRI - V3 LogC (EI800) - Wide Gamut, logc3ei800_alexawide] + family: Input/ARRI + equalitygroup: "" + bitdepth: 32f + description: | + Convert ARRI LogC3 (EI800) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC3_EI800_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.ARRI.Alexa-v3-logC-EI800.a1.v2 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_LogC_EI800_AWG.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.LogC_EI800_AWG_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: ARRI LogC3 (EI800) to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.247189638318671, log_side_offset: 0.385536998692443, lin_side_slope: 5.55555555555556, lin_side_offset: 0.0522722750251688, lin_side_break: 0.0105909904954696, direction: inverse} + - ! {matrix: [0.680205505106279, 0.236136601606481, 0.0836578932872398, 0, 0.0854149797421404, 1.01747087860704, -0.102885858349182, 0, 0.00205652166929683, -0.0625625003847921, 1.06050597871549, 0, 0, 0, 0, 1]} + + - ! + name: Linear ARRI Wide Gamut 4 + aliases: [lin_arri_wide_gamut_4, lin_awg4] + family: Input/ARRI + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear ARRI Wide Gamut 4 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:Linear_ARRI_Wide_Gamut_4_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear ARRI Wide Gamut 4 to ACES2065-1 + children: + - ! {matrix: [0.750957362824734, 0.144422786709757, 0.104619850465509, 0, 0.000821837079380207, 1.007397584885, -0.00821942196438358, 0, -0.000499952143533471, -0.000854177231436971, 1.00135412937497, 0, 0, 0, 0, 1]} + + - ! + name: ARRI LogC4 + aliases: [arri_logc4] + family: Input/ARRI + equalitygroup: "" + bitdepth: 32f + description: | + Convert ARRI LogC4 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC4_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.ARRI.ARRI-LogC4.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.LogC4_to_ACES.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_LogC4.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: ARRI LogC4 to ACES2065-1 + children: + - ! {log_side_slope: 0.0647954196341293, log_side_offset: -0.295908392682586, lin_side_slope: 2231.82630906769, lin_side_offset: 64, lin_side_break: -0.0180569961199113, direction: inverse} + - ! {matrix: [0.750957362824734, 0.144422786709757, 0.104619850465509, 0, 0.000821837079380207, 1.007397584885, -0.00821942196438358, 0, -0.000499952143533471, -0.000854177231436971, 1.00135412937497, 0, 0, 0, 0, 1]} + + - ! + name: BMDFilm WideGamut Gen5 + aliases: [bmdfilm_widegamut_gen5] + family: Input/BlackmagicDesign + equalitygroup: "" + bitdepth: 32f + description: | + Convert Blackmagic Film Wide Gamut (Gen 5) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:BMDFilm_WideGamut_Gen5_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.BlackmagicDesign.BMDFilm_WideGamut_Gen5.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_BMDFilm_WideGamut_Gen5.a1.v1 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.BMDFilm_WideGamut_Gen5_to_ACES.a1.v1 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Blackmagic Film Wide Gamut (Gen 5) to ACES2065-1 + children: + - ! {base: 2.71828182845905, log_side_slope: 0.0869287606549122, log_side_offset: 0.530013339229194, lin_side_offset: 0.00549407243225781, lin_side_break: 0.005, direction: inverse} + - ! {matrix: [0.647091325580708, 0.242595385134207, 0.110313289285085, 0, 0.0651915997328519, 1.02504756760476, -0.0902391673376125, 0, -0.0275570729194699, -0.0805887097177784, 1.10814578263725, 0, 0, 0, 0, 1]} + + - ! + name: DaVinci Intermediate WideGamut + aliases: [davinci_intermediate_widegamut] + family: Input/BlackmagicDesign + equalitygroup: "" + bitdepth: 32f + description: | + Convert DaVinci Intermediate Wide Gamut to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:DaVinci_Intermediate_WideGamut_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.DaVinci_Intermediate_WideGamut_to_ACES.a1.v1 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: DaVinci Intermediate Wide Gamut to ACES2065-1 + children: + - ! {log_side_slope: 0.07329248, log_side_offset: 0.51304736, lin_side_offset: 0.0075, lin_side_break: 0.00262409, linear_slope: 10.44426855, direction: inverse} + - ! {matrix: [0.748270290272981, 0.167694659554328, 0.0840350501726906, 0, 0.0208421234689102, 1.11190474268894, -0.132746866157851, 0, -0.0915122574225729, -0.127746712807307, 1.21925897022988, 0, 0, 0, 0, 1]} + + - ! + name: Linear BMD WideGamut Gen5 + aliases: [lin_bmd_widegamut_gen5] + family: Input/BlackmagicDesign + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear Blackmagic Wide Gamut (Gen 5) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:Linear_BMD_WideGamut_Gen5_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear Blackmagic Wide Gamut (Gen 5) to ACES2065-1 + children: + - ! {matrix: [0.647091325580708, 0.242595385134207, 0.110313289285085, 0, 0.0651915997328519, 1.02504756760476, -0.0902391673376125, 0, -0.0275570729194699, -0.0805887097177784, 1.10814578263725, 0, 0, 0, 0, 1]} + + - ! + name: Linear DaVinci WideGamut + aliases: [lin_davinci_widegamut] + family: Input/BlackmagicDesign + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear DaVinci Wide Gamut to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:Linear_DaVinci_WideGamut_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear DaVinci Wide Gamut to ACES2065-1 + children: + - ! {matrix: [0.748270290272981, 0.167694659554328, 0.0840350501726906, 0, 0.0208421234689102, 1.11190474268894, -0.132746866157851, 0, -0.0915122574225729, -0.127746712807307, 1.21925897022988, 0, 0, 0, 0, 1]} + + - ! + name: CanonLog2 CinemaGamut D55 + aliases: [canonlog2_cinemagamut_d55, Input - Canon - Canon-Log2 - Cinema Gamut Daylight, canonlog2_cgamutday] + family: Input/Canon + equalitygroup: "" + bitdepth: 32f + description: | + Convert Canon Log 2 Cinema Gamut (Daylight) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CanonLog2_CinemaGamut-D55_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.CLog2_CGamut_to_ACES.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_CLog2_CGamut.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! {style: CANON_CLOG2-CGAMUT_to_ACES2065-1} + + - ! + name: CanonLog3 CinemaGamut D55 + aliases: [canonlog3_cinemagamut_d55, Input - Canon - Canon-Log3 - Cinema Gamut Daylight, canonlog3_cgamutday] + family: Input/Canon + equalitygroup: "" + bitdepth: 32f + description: | + Convert Canon Log 3 Cinema Gamut (Daylight) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CanonLog3_CinemaGamut-D55_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.CLog3_CGamut_to_ACES.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_CLog3_CGamut.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! {style: CANON_CLOG3-CGAMUT_to_ACES2065-1} + + - ! + name: Linear CinemaGamut D55 + aliases: [lin_cinemagamut_d55, Input - Canon - Linear - Canon Cinema Gamut Daylight, lin_canoncgamutday] + family: Input/Canon + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear Canon Cinema Gamut (Daylight) to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:Linear-CinemaGamut-D55_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear Canon Cinema Gamut (Daylight) to ACES2065-1 + children: + - ! {matrix: [0.763064454775734, 0.14902116113706, 0.0879143840872056, 0, 0.00365745670512393, 1.10696038037622, -0.110617837081339, 0, -0.0094077940457189, -0.218383304989987, 1.22779109903571, 0, 0, 0, 0, 1]} + + - ! + name: Linear V-Gamut + aliases: [lin_vgamut, Input - Panasonic - Linear - V-Gamut] + family: Input/Panasonic + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear Panasonic V-Gamut to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Panasonic:Input:Linear_VGamut_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear Panasonic V-Gamut to ACES2065-1 + children: + - ! {matrix: [0.72461670413153, 0.166915288193706, 0.108468007674764, 0, 0.021390245413146, 0.984908155703054, -0.00629840111620089, 0, -0.00923556287076561, -0.00105690563900513, 1.01029246850977, 0, 0, 0, 0, 1]} + + - ! + name: V-Log V-Gamut + aliases: [vlog_vgamut, Input - Panasonic - V-Log - V-Gamut] + family: Input/Panasonic + equalitygroup: "" + bitdepth: 32f + description: | + Convert Panasonic V-Log - V-Gamut to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Panasonic:Input:VLog_VGamut_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.VLog_VGamut_to_ACES.a1.1.0 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_VLog_VGamut.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Panasonic.VLog_VGamut.a1.v1 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Panasonic V-Log - V-Gamut to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.241514, log_side_offset: 0.598206, lin_side_offset: 0.00873, lin_side_break: 0.01, direction: inverse} + - ! {matrix: [0.72461670413153, 0.166915288193706, 0.108468007674764, 0, 0.021390245413146, 0.984908155703054, -0.00629840111620089, 0, -0.00923556287076561, -0.00105690563900513, 1.01029246850977, 0, 0, 0, 0, 1]} + + - ! + name: Linear REDWideGamutRGB + aliases: [lin_redwidegamutrgb, Input - RED - Linear - REDWideGamutRGB, lin_rwg] + family: Input/RED + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear REDWideGamutRGB to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:RED:Input:Linear_REDWideGamutRGB_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear REDWideGamutRGB to ACES2065-1 + children: + - ! {matrix: [0.785058804068092, 0.0838587565440846, 0.131082439387823, 0, 0.0231738348454756, 1.08789754919233, -0.111071384037806, 0, -0.0737604353682082, -0.314590072290208, 1.38835050765842, 0, 0, 0, 0, 1]} + + - ! + name: Log3G10 REDWideGamutRGB + aliases: [log3g10_redwidegamutrgb, Input - RED - REDLog3G10 - REDWideGamutRGB, rl3g10_rwg] + family: Input/RED + equalitygroup: "" + bitdepth: 32f + description: | + Convert RED Log3G10 REDWideGamutRGB to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:RED:Input:Log3G10_REDWideGamutRGB_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.RED.Log3G10_REDWideGamutRGB.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_Log3G10_RWG.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.Log3G10_RWG_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: RED Log3G10 REDWideGamutRGB to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.224282, lin_side_slope: 155.975327, lin_side_offset: 2.55975327, lin_side_break: -0.01, direction: inverse} + - ! {matrix: [0.785058804068092, 0.0838587565440846, 0.131082439387823, 0, 0.0231738348454756, 1.08789754919233, -0.111071384037806, 0, -0.0737604353682082, -0.314590072290208, 1.38835050765842, 0, 0, 0, 0, 1]} + + - ! + name: Linear S-Gamut3 + aliases: [lin_sgamut3, Input - Sony - Linear - S-Gamut3] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear S-Gamut3 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_SGamut3_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear S-Gamut3 to ACES2065-1 + children: + - ! {matrix: [0.75298259539984, 0.143370216235557, 0.103647188364603, 0, 0.0217076974414429, 1.01531883550528, -0.0370265329467195, 0, -0.00941605274963355, 0.00337041785882367, 1.00604563489081, 0, 0, 0, 0, 1]} + + - ! + name: Linear S-Gamut3.Cine + aliases: [lin_sgamut3cine, Input - Sony - Linear - S-Gamut3.Cine] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear S-Gamut3.Cine to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_SGamut3Cine_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear S-Gamut3.Cine to ACES2065-1 + children: + - ! {matrix: [0.638788667185978, 0.272351433711262, 0.0888598991027595, 0, -0.00391590602528224, 1.0880732308974, -0.0841573248721177, 0, -0.0299072021239151, -0.0264325799101947, 1.05633978203411, 0, 0, 0, 0, 1]} + + - ! + name: Linear Venice S-Gamut3 + aliases: [lin_venice_sgamut3, Input - Sony - Linear - Venice S-Gamut3] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear Venice S-Gamut3 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_Venice_SGamut3_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear Venice S-Gamut3 to ACES2065-1 + children: + - ! {matrix: [0.793329741146434, 0.0890786256206771, 0.117591633232888, 0, 0.0155810585252582, 1.03271230692988, -0.0482933654551394, 0, -0.0188647477991488, 0.0127694120973433, 1.0060953357018, 0, 0, 0, 0, 1]} + + - ! + name: Linear Venice S-Gamut3.Cine + aliases: [lin_venice_sgamut3cine, Input - Sony - Linear - Venice S-Gamut3.Cine] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Linear Venice S-Gamut3.Cine to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:Linear_Venice_SGamut3Cine_to_ACES2065-1:1.0 + isdata: false + categories: [file-io] + encoding: scene-linear + allocation: uniform + to_scene_reference: ! + name: Linear Venice S-Gamut3.Cine to ACES2065-1 + children: + - ! {matrix: [0.674257092126512, 0.220571735923397, 0.10517117195009, 0, -0.00931360607857167, 1.10595886142466, -0.0966452553460855, 0, -0.0382090673002312, -0.017938376600236, 1.05614744390047, 0, 0, 0, 0, 1]} + + - ! + name: S-Log3 S-Gamut3 + aliases: [slog3_sgamut3, Input - Sony - S-Log3 - S-Gamut3] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Sony S-Log3 S-Gamut3 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_SGamut3_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.SLog3_SGamut3.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_SGamut3.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_SGamut3_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Sony S-Log3 S-Gamut3 to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.255620723362659, log_side_offset: 0.410557184750733, lin_side_slope: 5.26315789473684, lin_side_offset: 0.0526315789473684, lin_side_break: 0.01125, linear_slope: 6.62194371177582, direction: inverse} + - ! {matrix: [0.75298259539984, 0.143370216235557, 0.103647188364603, 0, 0.0217076974414429, 1.01531883550528, -0.0370265329467195, 0, -0.00941605274963355, 0.00337041785882367, 1.00604563489081, 0, 0, 0, 0, 1]} + + - ! + name: S-Log3 S-Gamut3.Cine + aliases: [slog3_sgamut3cine, Input - Sony - S-Log3 - S-Gamut3.Cine, slog3_sgamutcine] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Sony S-Log3 S-Gamut3.Cine to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_SGamut3Cine_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.SLog3_SGamut3Cine.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_SGamut3Cine.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_SGamut3Cine_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Sony S-Log3 S-Gamut3.Cine to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.255620723362659, log_side_offset: 0.410557184750733, lin_side_slope: 5.26315789473684, lin_side_offset: 0.0526315789473684, lin_side_break: 0.01125, linear_slope: 6.62194371177582, direction: inverse} + - ! {matrix: [0.638788667185978, 0.272351433711262, 0.0888598991027595, 0, -0.00391590602528224, 1.0880732308974, -0.0841573248721177, 0, -0.0299072021239151, -0.0264325799101947, 1.05633978203411, 0, 0, 0, 0, 1]} + + - ! + name: S-Log3 Venice S-Gamut3 + aliases: [slog3_venice_sgamut3, Input - Sony - S-Log3 - Venice S-Gamut3] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Sony S-Log3 Venice S-Gamut3 to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_Venice_SGamut3_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.Venice_SLog3_SGamut3.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_Venice_SGamut3.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_Venice_SGamut3_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Sony S-Log3 Venice S-Gamut3 to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.255620723362659, log_side_offset: 0.410557184750733, lin_side_slope: 5.26315789473684, lin_side_offset: 0.0526315789473684, lin_side_break: 0.01125, linear_slope: 6.62194371177582, direction: inverse} + - ! {matrix: [0.793329741146434, 0.089078625620677, 0.117591633232888, 0, 0.0155810585252582, 1.03271230692988, -0.0482933654551394, 0, -0.0188647477991488, 0.0127694120973433, 1.00609533570181, 0, 0, 0, 0, 1]} + + - ! + name: S-Log3 Venice S-Gamut3.Cine + aliases: [slog3_venice_sgamut3cine, Input - Sony - S-Log3 - Venice S-Gamut3.Cine, slog3_venice_sgamutcine] + family: Input/Sony + equalitygroup: "" + bitdepth: 32f + description: | + Convert Sony S-Log3 Venice S-Gamut3.Cine to ACES2065-1 + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3_Venice_SGamut3Cine_to_ACES2065-1:1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:IDT.Sony.Venice_SLog3_SGamut3Cine.a1.v1 + + AMF Components + -------------- + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.ACES_to_SLog3_Venice_SGamut3Cine.a1.1.0 + ACEStransformID: urn:ampas:aces:transformId:v1.5:ACEScsc.Academy.SLog3_Venice_SGamut3Cine_to_ACES.a1.1.0 + isdata: false + categories: [file-io] + encoding: log + allocation: uniform + to_scene_reference: ! + name: Sony S-Log3 Venice S-Gamut3.Cine to ACES2065-1 + children: + - ! {base: 10, log_side_slope: 0.255620723362659, log_side_offset: 0.410557184750733, lin_side_slope: 5.26315789473684, lin_side_offset: 0.0526315789473684, lin_side_break: 0.01125, linear_slope: 6.62194371177582, direction: inverse} + - ! {matrix: [0.674257092126512, 0.220571735923397, 0.10517117195009, 0, -0.00931360607857167, 1.10595886142466, -0.0966452553460855, 0, -0.0382090673002312, -0.017938376600236, 1.05614744390047, 0, 0, 0, 0, 1]} + + - ! + name: Camera Rec.709 + aliases: [camera_rec709, Utility - Rec.709 - Camera, rec709_camera] + family: Utility/ITU + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to Rec.709 camera OETF Rec.709 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ITU:Utility:AP0_to_Camera_Rec709:1.0 + isdata: false + categories: [file-io] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to Camera Rec.709 + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + - ! {gamma: 2.22222222222222, offset: 0.099, direction: inverse} + + - ! + name: Linear P3-D65 + aliases: [lin_p3d65, Utility - Linear - P3-D65, lin_displayp3, Linear Display P3] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to linear P3 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_P3-D65:1.0 + isdata: false + categories: [file-io, working-space, texture] + encoding: scene-linear + allocation: uniform + from_scene_reference: ! + name: AP0 to Linear P3-D65 + children: + - ! {matrix: [2.02490528596679, -0.689069761034766, -0.335835524932019, 0, -0.183597032256178, 1.28950620775902, -0.105909175502841, 0, 0.00905856112234766, -0.0592796840575522, 1.0502211229352, 0, 0, 0, 0, 1]} + + - ! + name: Linear Rec.2020 + aliases: [lin_rec2020, Utility - Linear - Rec.2020] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to linear Rec.2020 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_Rec2020:1.0 + isdata: false + categories: [file-io, texture] + encoding: scene-linear + allocation: uniform + from_scene_reference: ! + name: AP0 to Linear Rec.2020 + children: + - ! {matrix: [1.49040952054172, -0.26617091926613, -0.224238601275593, 0, -0.0801674998722558, 1.18216712109757, -0.10199962122531, 0, 0.00322763119162216, -0.0347764757450576, 1.03154884455344, 0, 0, 0, 0, 1]} + + - ! + name: Linear Rec.709 (sRGB) + aliases: [lin_rec709_srgb, Utility - Linear - Rec.709, lin_rec709, lin_srgb, Utility - Linear - sRGB] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to linear Rec.709 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Linear_Rec709:1.0 + isdata: false + categories: [file-io, working-space, texture] + encoding: scene-linear + allocation: uniform + from_scene_reference: ! + name: AP0 to Linear Rec.709 (sRGB) + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + + - ! + name: Gamma 1.8 Rec.709 - Texture + aliases: [g18_rec709_tx, Utility - Gamma 1.8 - Rec.709 - Texture, g18_rec709] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to 1.8 gamma-corrected Rec.709 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma1.8_Rec709-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to Gamma 1.8 Rec.709 - Texture + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + - ! {value: 1.8, style: pass_thru, direction: inverse} + + - ! + name: Gamma 2.2 AP1 - Texture + aliases: [g22_ap1_tx, g22_ap1] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to 2.2 gamma-corrected AP1 primaries, ACES ~=D60 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.2_AP1-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to Gamma 2.2 AP1 - Texture + children: + - ! {matrix: [1.45143931614567, -0.23651074689374, -0.214928569251925, 0, -0.0765537733960206, 1.17622969983357, -0.0996759264375522, 0, 0.00831614842569772, -0.00603244979102102, 0.997716301365323, 0, 0, 0, 0, 1]} + - ! {value: 2.2, style: pass_thru, direction: inverse} + + - ! + name: Gamma 2.2 Rec.709 - Texture + aliases: [g22_rec709_tx, Utility - Gamma 2.2 - Rec.709 - Texture, g22_rec709] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to 2.2 gamma-corrected Rec.709 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.2_Rec709-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to Gamma 2.2 Rec.709 - Texture + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + - ! {value: 2.2, style: pass_thru, direction: inverse} + + - ! + name: Gamma 2.4 Rec.709 - Texture + aliases: [g24_rec709_tx, g24_rec709, rec709_display, Utility - Rec.709 - Display] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to 2.4 gamma-corrected Rec.709 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_Gamma2.4_Rec709-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to Gamma 2.4 Rec.709 - Texture + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + - ! {value: 2.4, style: pass_thru, direction: inverse} + + - ! + name: sRGB Encoded AP1 - Texture + aliases: [srgb_encoded_ap1_tx, srgb_ap1] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to sRGB Encoded AP1 primaries, ACES ~=D60 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB_Encoded_AP1-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to sRGB Encoded AP1 - Texture + children: + - ! {matrix: [1.45143931614567, -0.23651074689374, -0.214928569251925, 0, -0.0765537733960206, 1.17622969983357, -0.0996759264375522, 0, 0.00831614842569772, -0.00603244979102102, 0.997716301365323, 0, 0, 0, 0, 1]} + - ! {gamma: 2.4, offset: 0.055, direction: inverse} + + - ! + name: sRGB Encoded P3-D65 - Texture + aliases: [srgb_encoded_p3d65_tx, srgb_p3d65, srgb_displayp3] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to sRGB Encoded P3-D65 primaries, D65 white point + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB_Encoded_P3-D65-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to sRGB Encoded P3-D65 - Texture + children: + - ! {matrix: [2.02490528596679, -0.689069761034766, -0.335835524932019, 0, -0.183597032256178, 1.28950620775902, -0.105909175502841, 0, 0.00905856112234766, -0.0592796840575522, 1.0502211229352, 0, 0, 0, 0, 1]} + - ! {gamma: 2.4, offset: 0.055, direction: inverse} + + - ! + name: sRGB - Texture + aliases: [srgb_tx, Utility - sRGB - Texture, srgb_texture, Input - Generic - sRGB - Texture] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: | + Convert ACES2065-1 to sRGB + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:AP0_to_sRGB-Texture:1.0 + isdata: false + categories: [file-io, texture] + encoding: sdr-video + allocation: uniform + from_scene_reference: ! + name: AP0 to sRGB Rec.709 + children: + - ! {matrix: [2.52168618674388, -1.13413098823972, -0.387555198504164, 0, -0.276479914229922, 1.37271908766826, -0.096239173438334, 0, -0.0153780649660342, -0.152975335867399, 1.16835340083343, 0, 0, 0, 0, 1]} + - ! {gamma: 2.4, offset: 0.055, direction: inverse} + + - ! + name: Raw + aliases: [Utility - Raw] + family: Utility + equalitygroup: "" + bitdepth: 32f + description: The utility "Raw" colorspace. + isdata: true + categories: [file-io, texture] + allocation: uniform + +named_transforms: + - ! + name: ARRI LogC3 - Curve (EI800) + aliases: [arri_logc3_crv_ei800, Input - ARRI - Curve - V3 LogC (EI800), crv_logc3ei800] + description: | + Convert ARRI LogC3 Curve (EI800) to Relative Scene Linear + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC3_Curve_EI800_to_Linear:1.0 + family: Input/ARRI + categories: [file-io] + encoding: log + transform: ! + name: ARRI LogC3 Curve (EI800) to Relative Scene Linear + children: + - ! {base: 10, log_side_slope: 0.247189638318671, log_side_offset: 0.385536998692443, lin_side_slope: 5.55555555555556, lin_side_offset: 0.0522722750251688, lin_side_break: 0.0105909904954696, direction: inverse} + + - ! + name: ARRI LogC4 - Curve + aliases: [arri_logc4_crv] + description: | + Convert ARRI LogC4 Curve to Relative Scene Linear + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ARRI:Input:ARRI_LogC4_Curve_to_Linear:1.0 + family: Input/ARRI + categories: [file-io] + encoding: log + transform: ! + name: ARRI LogC4 Curve to Relative Scene Linear + children: + - ! {log_side_slope: 0.0647954196341293, log_side_offset: -0.295908392682586, lin_side_slope: 2231.82630906769, lin_side_offset: 64, lin_side_break: -0.0180569961199113, direction: inverse} + + - ! + name: BMDFilm Gen5 Log - Curve + aliases: [bmdfilm_gen5_log_crv] + description: | + Convert Blackmagic Film (Gen 5) Log to Blackmagic Film (Gen 5) Linear + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:BMDFilm_Gen5_Log-Curve_to_Linear:1.0 + family: Input/BlackmagicDesign + categories: [file-io] + encoding: log + transform: ! + name: Blackmagic Film (Gen 5) Log to Linear Curve + children: + - ! {base: 2.71828182845905, log_side_slope: 0.0869287606549122, log_side_offset: 0.530013339229194, lin_side_offset: 0.00549407243225781, lin_side_break: 0.005, direction: inverse} + + - ! + name: DaVinci Intermediate Log - Curve + aliases: [davinci_intermediate_log_crv] + description: | + Convert DaVinci Intermediate Log to DaVinci Intermediate Linear + + CLFtransformID: urn:aswf:ocio:transformId:1.0:BlackmagicDesign:Input:DaVinci_Intermediate_Log-Curve_to_Linear:1.0 + family: Input/BlackmagicDesign + categories: [file-io] + encoding: log + transform: ! + name: DaVinci Intermediate Log to Linear Curve + children: + - ! {log_side_slope: 0.07329248, log_side_offset: 0.51304736, lin_side_offset: 0.0075, lin_side_break: 0.00262409, linear_slope: 10.44426855, direction: inverse} + + - ! + name: C-Log2 - Curve + aliases: [clog2_crv, Input - Canon - Curve - Canon-Log2, crv_canonlog2] + description: | + Convert CLog2 Log (arbitrary primaries) to CLog2 Linear (arbitrary primaries) + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CLog2-Curve_to_Linear:1.0 + family: Input/Canon + categories: [file-io] + encoding: log + transform: ! {style: CURVE - CANON_CLOG2_to_LINEAR} + + - ! + name: C-Log3 - Curve + aliases: [clog3_crv, Input - Canon - Curve - Canon-Log3, crv_canonlog3] + description: | + Convert CLog3 Log (arbitrary primaries) to CLog3 Linear (arbitrary primaries) + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Canon:Input:CLog3-Curve_to_Linear:1.0 + family: Input/Canon + categories: [file-io] + encoding: log + transform: ! {style: CURVE - CANON_CLOG3_to_LINEAR} + + - ! + name: V-Log - Curve + aliases: [vlog_crv, Input - Panasonic - Curve - V-Log, crv_vlog] + description: | + Convert Panasonic V-Log Log (arbitrary primaries) to Panasonic V-Log Linear (arbitrary primaries) + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Panasonic:Input:VLog-Curve_to_Linear:1.0 + family: Input/Panasonic + categories: [file-io] + encoding: log + transform: ! + name: Panasonic V-Log Log to Linear Curve + children: + - ! {base: 10, log_side_slope: 0.241514, log_side_offset: 0.598206, lin_side_offset: 0.00873, lin_side_break: 0.01, direction: inverse} + + - ! + name: Log3G10 - Curve + aliases: [log3g10_crv, Input - RED - Curve - REDLog3G10, crv_rl3g10] + description: | + Convert RED Log3G10 Log (arbitrary primaries) to RED Log3G10 Linear (arbitrary primaries) + + CLFtransformID: urn:aswf:ocio:transformId:1.0:RED:Input:Log3G10-Curve_to_Linear:1.0 + family: Input/RED + categories: [file-io] + encoding: log + transform: ! + name: RED Log3G10 Log to Linear Curve + children: + - ! {base: 10, log_side_slope: 0.224282, lin_side_slope: 155.975327, lin_side_offset: 2.55975327, lin_side_break: -0.01, direction: inverse} + + - ! + name: S-Log3 - Curve + aliases: [slog3_crv, Input - Sony - Curve - S-Log3, crv_slog3] + description: | + Convert S-Log3 Log (arbitrary primaries) to S-Log3 Linear (arbitrary primaries) + + CLFtransformID: urn:aswf:ocio:transformId:1.0:Sony:Input:SLog3-Curve_to_Linear:1.0 + family: Input/Sony + categories: [file-io] + encoding: log + transform: ! + name: S-Log3 Log to Linear Curve + children: + - ! {base: 10, log_side_slope: 0.255620723362659, log_side_offset: 0.410557184750733, lin_side_slope: 5.26315789473684, lin_side_offset: 0.0526315789473684, lin_side_break: 0.01125, linear_slope: 6.62194371177582, direction: inverse} + + - ! + name: Rec.1886 - Curve + aliases: [rec1886_crv, Utility - Curve - Rec.1886, crv_rec1886] + description: | + Convert generic linear RGB to Rec.1886 encoded RGB + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:Linear_to_Rec1886-Curve:1.0 + family: Utility + categories: [file-io] + encoding: sdr-video + inverse_transform: ! + name: Linear to Rec.1886 + children: + - ! {value: 2.4, style: pass_thru, direction: inverse} + + - ! + name: Rec.709 - Curve + aliases: [rec709_crv, Utility - Curve - Rec.709, crv_rec709] + description: | + Convert generic linear RGB to generic gamma-corrected RGB + + CLFtransformID: urn:aswf:ocio:transformId:1.0:ITU:Utility:Linear_to_Rec709-Curve:1.0 + family: Utility/ITU + categories: [file-io] + encoding: sdr-video + inverse_transform: ! + name: Linear to Rec.709 + children: + - ! {gamma: 2.22222222222222, offset: 0.099, direction: inverse} + + - ! + name: sRGB - Curve + aliases: [srgb_crv, Utility - Curve - sRGB, crv_srgb] + description: | + Convert generic linear RGB to sRGB encoded RGB + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:Linear_to_sRGB-Curve:1.0 + family: Utility + categories: [file-io] + encoding: sdr-video + inverse_transform: ! + name: Linear to sRGB + children: + - ! {gamma: 2.4, offset: 0.055, direction: inverse} + + - ! + name: ST-2084 - Curve + aliases: [st_2084_crv] + description: | + Convert generic linear RGB to generic ST.2084 (PQ) encoded RGB mapping 1.0 to 100nits + + CLFtransformID: urn:aswf:ocio:transformId:1.0:OCIO:Utility:Linear_to_ST2084-Curve:1.0 + family: Utility + categories: [file-io] + encoding: hdr-video + inverse_transform: ! {style: CURVE - LINEAR_to_ST-2084} + diff --git a/third_party/openfx/include/ofx.doxy b/third_party/openfx/include/ofx.doxy new file mode 100644 index 000000000..7b145ce2a --- /dev/null +++ b/third_party/openfx/include/ofx.doxy @@ -0,0 +1,2379 @@ +# Doxyfile 1.8.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "OFX" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = "1.4+" + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Open Effects API" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ../Documentation/doxygen_build + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = YES + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.h + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = NO + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = ./DocSrc/ofx_header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = ./DocSrc/ofx_footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = ./DocSrc/ofx_style.css + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /