1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * This file is part of openfx-supportext <https://github.com/devernay/openfx-supportext>,
4  * Copyright (C) 2013-2018 INRIA
5  *
6  * openfx-supportext is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * openfx-supportext is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with openfx-supportext.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
18  * ***** END LICENSE BLOCK ***** */
19 
20 /*
21  * OFX Transform3x3 plugin: a base plugin for 2D homographic transform,
22  * represented by a 3x3 matrix.
23  */
24 
25 #ifndef openfx_supportext_ofxsTransform3x3_h
26 #define openfx_supportext_ofxsTransform3x3_h
27 
28 #include <memory>
29 
30 #include "ofxsImageEffect.h"
31 #include "ofxsTransform3x3Processor.h"
32 #include "ofxsShutter.h"
33 #include "ofxsMacros.h"
34 
35 #define kParamTransform3x3Invert "invert"
36 #define kParamTransform3x3InvertLabel "Invert"
37 #define kParamTransform3x3InvertHint "Invert the transform."
38 
39 #define kParamTransform3x3MotionBlur "motionBlur"
40 #define kParamTransform3x3MotionBlurLabel "Motion Blur"
41 #define kParamTransform3x3MotionBlurHint "Quality of motion blur rendering. 0 disables motion blur, 1 is a good value. Increasing this slows down rendering."
42 
43 // extra parameters for DirBlur:
44 
45 #define kParamTransform3x3DirBlurAmount "amount"
46 #define kParamTransform3x3DirBlurAmountLabel "Amount"
47 #define kParamTransform3x3DirBlurAmountHint "Amount of blur transform to apply. A value of 1 means to apply the full transform range. A value of 0 means to apply no blur at all. Default is 1."
48 
49 #define kParamTransform3x3DirBlurCentered "centered"
50 #define kParamTransform3x3DirBlurCenteredLabel "Centered"
51 #define kParamTransform3x3DirBlurCenteredHint "When checked, apply directional blur symmetrically arount the neutral position."
52 
53 #define kParamTransform3x3DirBlurFading "fading"
54 #define kParamTransform3x3DirBlurFadingLabel "Fading"
55 #define kParamTransform3x3DirBlurFadingHint "Controls the fading function. A value of 1 corresponds to linear fading. A value of 0 disables fading. Default is 0."
56 
57 // extra parameters for non-DirBlur
58 
59 #define kParamTransform3x3DirectionalBlur "directionalBlur"
60 #define kParamTransform3x3DirectionalBlurLabel "Directional Blur Mode"
61 #define kParamTransform3x3DirectionalBlurHint "Motion blur is computed from the original image to the transformed image, each parameter being interpolated linearly. The motionBlur parameter must be set to a nonzero value, and the blackOutside parameter may have an important effect on the result."
62 
63 namespace OFX {
64 ////////////////////////////////////////////////////////////////////////////////
65 /** @brief The plugin that does our work */
66 class Transform3x3Plugin
67     : public OFX::ImageEffect
68 {
69 protected:
70     // do not need to delete these, the ImageEffect is managing them for us
71     OFX::Clip *_dstClip;
72     OFX::Clip *_srcClip;
73     OFX::Clip *_maskClip;
74 
75 public:
76 
77     enum Transform3x3ParamsTypeEnum
78     {
79         eTransform3x3ParamsTypeNone = 0,
80         eTransform3x3ParamsTypeDirBlur,
81         eTransform3x3ParamsTypeMotionBlur
82     };
83 
84     /** @brief ctor */
85     Transform3x3Plugin(OfxImageEffectHandle handle,
86                        bool masked,
87                        Transform3x3ParamsTypeEnum paramsType);
88 
89     /** @brief destructor */
90     virtual ~Transform3x3Plugin();
91 
92     // a default implementation of isIdentity is provided, which may be overridden by the derived class
isIdentity(double)93     virtual bool isIdentity(double /*time*/)
94     {
95         return false;
96     };
97 
98     /** @brief recover a transform matrix from an effect */
99     virtual bool getInverseTransformCanonical(double time, int view, double amount, bool invert, OFX::Matrix3x3* invtransform) const = 0;
100 
101 
102     // The following functions override those is OFX::ImageEffect
103 
104     // override the rod call (not final, since overriden by Reformat)
105     virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod) OVERRIDE;
106 
107     // override the roi call
108     virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois) OVERRIDE FINAL;
109 
110     /* Override the render */
111     virtual void render(const OFX::RenderArguments &args) OVERRIDE;
112 
113     // override isIdentity
114     virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime
115 #ifdef OFX_EXTENSIONS_NUKE
116                             , int& view
117                             , std::string& plane
118 #endif
119                             ) OVERRIDE FINAL;
120 
121 #ifdef OFX_EXTENSIONS_NUKE
122     /** @brief recover a transform matrix from an effect */
123     virtual bool getTransform(const OFX::TransformArguments & args, OFX::Clip * &transformClip, double transformMatrix[9]) OVERRIDE;
124 #endif
125 
126     // override changedParam. note that the derived class MUST explicitely call this method after handling its own parameter changes
127     virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string &paramName) OVERRIDE;
128 
129     // this method must be called by the derived class when the transform was changed
130     void changedTransform(const OFX::InstanceChangedArgs &args);
131 
132 protected:
133     size_t getInverseTransforms(double time,
134                                 int view,
135                                 OfxPointD renderscale,
136                                 bool fielded,
137                                 double srcpixelAspectRatio,
138                                 double dstpixelAspectRatio,
139                                 bool invert,
140                                 double shutter,
141                                 ShutterOffsetEnum shutteroffset,
142                                 double shuttercustomoffset,
143                                 OFX::Matrix3x3* invtransform,
144                                 size_t invtransformsizealloc) const;
145 
146     size_t getInverseTransformsBlur(double time,
147                                     int view,
148                                     OfxPointD renderscale,
149                                     bool fielded,
150                                     double srcpixelAspectRatio,
151                                     double dstpixelAspectRatio,
152                                     bool invert,
153                                     double amountFrom,
154                                     double amountTo,
155                                     OFX::Matrix3x3* invtransform,
156                                     double* amount,
157                                     size_t invtransformsizealloc) const;
158 
159 private:
160     /* internal render function */
161     template <class PIX, int nComponents, int maxValue, bool masked>
162     void renderInternalForBitDepth(const OFX::RenderArguments &args);
163 
164     template <int nComponents, bool masked>
165     void renderInternal(const OFX::RenderArguments &args, OFX::BitDepthEnum dstBitDepth);
166 
167     /* set up and run a processor */
168     void setupAndProcess(Transform3x3ProcessorBase &, const OFX::RenderArguments &args);
169 
170     bool isIdentity(double time, OFX::Clip * &identityClip, double &identityTime);
171 
172     void transformRegion(const OfxRectD &rectFrom,
173                          double time,
174                          int view,
175                          bool invert,
176                          double motionblur,
177                          bool directionalBlur,
178                          double amountFrom,
179                          double amountTo,
180                          double shutter,
181                          ShutterOffsetEnum shutteroffset,
182                          double shuttercustomoffset,
183                          bool isIdentity,
184                          OfxRectD *rectTo);
185 
186 protected:
187     // Transform3x3-GENERIC
188     Transform3x3ParamsTypeEnum _paramsType;
189     OFX::BooleanParam* _invert;
190     // GENERIC
191     OFX::ChoiceParam* _filter;
192     OFX::BooleanParam* _clamp;
193     OFX::BooleanParam* _blackOutside;
194     OFX::DoubleParam* _motionblur;
195     OFX::DoubleParam* _dirBlurAmount; // DirBlur only
196     OFX::BooleanParam* _dirBlurCentered; // DirBlur only
197     OFX::DoubleParam* _dirBlurFading; // DirBlur only
198     OFX::BooleanParam* _directionalBlur; // non-DirBlur
199     OFX::DoubleParam* _shutter; // non-DirBlur
200     OFX::ChoiceParam* _shutteroffset; // non-DirBlur
201     OFX::DoubleParam* _shuttercustomoffset; // non-DirBlur
202     bool _masked;
203     OFX::DoubleParam* _mix;
204     OFX::BooleanParam* _maskApply;
205     OFX::BooleanParam* _maskInvert;
206 };
207 
208 void Transform3x3Describe(OFX::ImageEffectDescriptor &desc, bool masked);
209 
210 OFX::PageParamDescriptor * Transform3x3DescribeInContextBegin(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context, bool masked);
211 
212 void Transform3x3DescribeInContextEnd(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context, OFX::PageParamDescriptor* page, bool masked, OFX::Transform3x3Plugin::Transform3x3ParamsTypeEnum paramsType);
213 } // namespace OFX
214 #endif /* defined(openfx_supportext_ofxsTransform3x3_h) */
215