1 /*
2  * This file is part of openfx-arena <https://github.com/olear/openfx-arena>,
3  * Copyright (C) 2016 INRIA
4  *
5  * openfx-arena is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as published
7  * by the Free Software Foundation.
8  *
9  * openfx-arena is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with openfx-arena.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
16 */
17 
18 #include "MagickPlugin.h"
19 #include <cmath>
20 
21 using namespace OFX;
22 OFXS_NAMESPACE_ANONYMOUS_ENTER
23 
24 #define kPluginName "RollOFX"
25 #define kPluginGrouping "Extra/Transform"
26 #define kPluginIdentifier "net.fxarena.openfx.Roll"
27 #define kPluginDescription "Roll effect using ImageMagick."
28 #define kPluginVersionMajor 2
29 #define kPluginVersionMinor 9
30 
31 #define kSupportsTiles 0
32 #define kSupportsMultiResolution 1
33 #define kSupportsRenderScale 1
34 #define kRenderThreadSafety eRenderFullySafe
35 #define kHostFrameThreading false
36 #define kHostMasking true
37 #define kHostMixing true
38 
39 #define kParamRollX "x"
40 #define kParamRollXLabel "X"
41 #define kParamRollXHint "Adjust roll X"
42 #define kParamRollXDefault 0
43 
44 #define kParamRollY "y"
45 #define kParamRollYLabel "Y"
46 #define kParamRollYHint "Adjust roll Y"
47 #define kParamRollYDefault 0
48 
49 class RollPlugin
50     : public MagickPluginHelper<kSupportsRenderScale>
51 {
52 public:
RollPlugin(OfxImageEffectHandle handle)53     RollPlugin(OfxImageEffectHandle handle)
54         : MagickPluginHelper<kSupportsRenderScale>(handle)
55         , _x(NULL)
56         , _y(NULL)
57     {
58         _x = fetchDoubleParam(kParamRollX);
59         _y = fetchDoubleParam(kParamRollY);
60         assert(_x && _y);
61     }
62 
render(const OFX::RenderArguments & args,Magick::Image & image)63     virtual void render(const OFX::RenderArguments &args, Magick::Image &image) OVERRIDE FINAL
64     {
65         double x,y;
66         _x->getValueAtTime(args.time, x);
67         _y->getValueAtTime(args.time, y);
68         image.roll(std::floor(x * args.renderScale.x + 0.5), std::floor(y * args.renderScale.x + 0.5));
69     }
70 private:
71     DoubleParam *_x;
72     DoubleParam *_y;
73 };
74 
75 mDeclarePluginFactory(RollPluginFactory, {}, {});
76 
describe(ImageEffectDescriptor & desc)77 void RollPluginFactory::describe(ImageEffectDescriptor &desc)
78 {
79     desc.setLabel(kPluginName);
80     desc.setPluginGrouping(kPluginGrouping);
81     desc.setPluginDescription(kPluginDescription);
82     desc.addSupportedContext(eContextGeneral);
83     desc.addSupportedContext(eContextFilter);
84     desc.addSupportedBitDepth(eBitDepthFloat);
85     desc.setSupportsTiles(kSupportsTiles);
86     desc.setSupportsMultiResolution(kSupportsMultiResolution);
87     desc.setRenderThreadSafety(kRenderThreadSafety);
88     desc.setHostFrameThreading(kHostFrameThreading);
89     desc.setHostMaskingEnabled(kHostMasking);
90     desc.setHostMixingEnabled(kHostMixing);
91 }
92 
describeInContext(ImageEffectDescriptor & desc,ContextEnum context)93 void RollPluginFactory::describeInContext(ImageEffectDescriptor &desc, ContextEnum context)
94 {
95     OFX::PageParamDescriptor *page = RollPlugin::describeInContextBegin(desc, context);
96     {
97         DoubleParamDescriptor *param = desc.defineDoubleParam(kParamRollX);
98         param->setLabel(kParamRollXLabel);
99         param->setHint(kParamRollXHint);
100         param->setRange(-100000, 100000);
101         param->setDisplayRange(-2000, 2000);
102         param->setDefault(kParamRollXDefault);
103         if (page) {
104             page->addChild(*param);
105         }
106     }
107     {
108         DoubleParamDescriptor *param = desc.defineDoubleParam(kParamRollY);
109         param->setLabel(kParamRollYLabel);
110         param->setHint(kParamRollYHint);
111         param->setRange(-100000, 100000);
112         param->setDisplayRange(-2000, 2000);
113         param->setDefault(kParamRollYDefault);
114         param->setLayoutHint(OFX::eLayoutHintDivider);
115         if (page) {
116             page->addChild(*param);
117         }
118     }
119     RollPlugin::describeInContextEnd(desc, context, page);
120 }
121 
122 OFX::ImageEffect*
createInstance(OfxImageEffectHandle handle,ContextEnum)123 RollPluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
124 {
125     return new RollPlugin(handle);
126 }
127 
128 static RollPluginFactory p(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor);
129 mRegisterPluginFactoryInstance(p)
130 
131 OFXS_NAMESPACE_ANONYMOUS_EXIT
132