1 /*
2 Software License :
3 
4 Copyright (c) 2003, The Open Effects Association Ltd. All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9     * Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright notice,
12       this list of conditions and the following disclaimer in the documentation
13       and/or other materials provided with the distribution.
14     * Neither the name The Open Effects Association Ltd, nor the names of its
15       contributors may be used to endorse or promote products derived from this
16       software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 /*
31   Ofx Example plugin that shows how a custom parameters are managed.
32 
33   It is meant to illustrate certain features of the API, as opposed to being a perfectly
34   crafted piece of image processing software.
35  */
36 
37 #ifdef WIN32
38 #include <windows.h>
39 #endif
40 
41 #include <cstring>
42 #include <cstdio>
43 #ifdef __APPLE__
44 #include <OpenGL/gl.h>
45 #else
46 #include <GL/gl.h>
47 #endif
48 #include <cmath>
49 #include <stdexcept>
50 #include <new>
51 #include "ofxImageEffect.h"
52 #include "ofxMemory.h"
53 #include "ofxMultiThread.h"
54 
55 #include "../include/ofxUtilities.H" // example support utils
56 
57 #if defined __APPLE__ || defined linux || defined __DragonFly__
58 #  define EXPORT __attribute__((visibility("default")))
59 #elif defined _WIN32
60 #  define EXPORT OfxExport
61 #else
62 #  error Not building on your operating system quite yet
63 #endif
64 
65 #define kPointParam "point"
66 
67 // pointers to various bits of the host
68 OfxHost                 *gHost;
69 OfxImageEffectSuiteV1 *gEffectHost = 0;
70 OfxPropertySuiteV1    *gPropHost = 0;
71 OfxParameterSuiteV1   *gParamHost = 0;
72 OfxMemorySuiteV1      *gMemoryHost = 0;
73 OfxMultiThreadSuiteV1 *gThreadHost = 0;
74 OfxMessageSuiteV1     *gMessageSuite = 0;
75 OfxInteractSuiteV1    *gInteractHost = 0;
76 
77 // decode a custom param from a string
78 static OfxStatus
parseCustomParam(const char * str,double & x,double & y)79 parseCustomParam(const char *str, double &x, double &y)
80 {
81   if(str && *str) {
82     int nRead = sscanf(str, "%lg %lg", &x, &y);
83     if(nRead != 2)
84       return kOfxStatErrFormat; // HACK need better error codes
85   }
86   else
87     return kOfxStatErrFormat; // HACK need better error codes
88   return kOfxStatOK;
89 }
90 
91 // encode a custom param into a string
92 void
writeCustomParam(char * str,int strlen,double x,double y)93 writeCustomParam(char *str, int strlen, double x, double y)
94 {
95 #ifdef WIN32
96   _snprintf(str, strlen, "%lg %lg", x, y);
97 #else
98   snprintf(str, strlen, "%lg %lg", x, y);
99 #endif
100 }
101 
102 // set the current value of my custom parameter
103 static OfxStatus
getCustomParam(OfxImageEffectHandle pluginInstance,double & x,double & y)104 getCustomParam(OfxImageEffectHandle pluginInstance, double &x, double &y)
105 {
106   // get the parameter set from the effect
107   OfxParamSetHandle paramSet;
108   gEffectHost->getParamSet(pluginInstance, &paramSet);
109 
110   // get the parameter from the parameter set
111   OfxParamHandle param;
112   gParamHost->paramGetHandle(paramSet, kPointParam, &param, NULL);
113 
114   // get my custom param's raw value
115   char *str = 0;
116   gParamHost->paramGetValue(param, &str);
117 
118   return parseCustomParam(str, x, y);
119 }
120 
121 // get the current value of my custom parameter
122 static OfxStatus
setCustomParam(OfxImageEffectHandle pluginInstance,double x,double y)123 setCustomParam(OfxImageEffectHandle pluginInstance, double x, double y)
124 {
125   // encode the custom parameter
126   char str[1024];
127   writeCustomParam(str, 1024, x, y);
128 
129   // get the parameter set from the effect
130   OfxParamSetHandle paramSet;
131   gEffectHost->getParamSet(pluginInstance, &paramSet);
132 
133   // get the parameter from the parameter set
134   OfxParamHandle param;
135   gParamHost->paramGetHandle(paramSet, kPointParam, &param, NULL);
136 
137   // set it's value
138   return gParamHost->paramSetValue(param, str);
139 }
140 
141 // The callback passed across the API do do custom parameter animation
142 static OfxStatus
customParamInterpFunction(OfxImageEffectHandle,OfxPropertySetHandle inArgs,OfxPropertySetHandle outArgs)143 customParamInterpFunction(OfxImageEffectHandle /*instance*/,
144 			     OfxPropertySetHandle inArgs,
145 			     OfxPropertySetHandle outArgs)
146 {
147   double x0, y0, x1, y1;
148   OfxStatus err;
149 
150   const char *fromValue = NULL, *toValue = NULL;
151 
152   // parse the custom param at the from value
153   gPropHost->propGetString(inArgs, kOfxParamPropCustomValue, 0, &fromValue);
154   if((err = parseCustomParam(fromValue, x0, y0)) != kOfxStatOK)
155     return err;
156 
157   // parse the custom param at the to value
158   gPropHost->propGetString(inArgs, kOfxParamPropCustomValue, 1, &toValue);
159   if((err = parseCustomParam(toValue, x1, y1)) != kOfxStatOK)
160     return err;
161 
162   // get the interp amount
163   double interp;
164   gPropHost->propGetDouble(inArgs, kOfxParamPropInterpolationAmount, 0, &interp);
165 
166   // and lerp the values
167   double x = x0 + (x1 - x0) * interp;
168   double y = y0 + (y1 - y0) * interp;
169 
170   // now encode the value and set it
171   char str[1024];
172   writeCustomParam(str, 1024, x, y);
173   gPropHost->propSetString(outArgs, kOfxParamPropCustomValue, 0, str);
174 
175   return kOfxStatOK;
176 }
177 
178 // plugin instance construction
179 static OfxStatus
createInstance(OfxImageEffectHandle)180 createInstance(OfxImageEffectHandle  /*instance*/)
181 {
182   return kOfxStatOK;
183 }
184 
185 // plugin instance destruction
186 static OfxStatus
destroyInstance(OfxImageEffectHandle)187 destroyInstance(OfxImageEffectHandle  /*instance*/)
188 {
189   return kOfxStatOK;
190 }
191 
192 static OfxStatus
isIdentity(OfxImageEffectHandle,OfxPropertySetHandle,OfxPropertySetHandle outArgs)193 isIdentity(OfxImageEffectHandle /*pluginInstance*/,
194 	   OfxPropertySetHandle /*inArgs*/,
195 	   OfxPropertySetHandle outArgs)
196 {
197   // set the property in the out args indicating which is the identity clip
198   gPropHost->propSetString(outArgs, kOfxPropName, 0, kOfxImageEffectSimpleSourceClipName);
199   return kOfxStatOK;
200 }
201 
202 // the process code  that the host sees
render(OfxImageEffectHandle,OfxPropertySetHandle,OfxPropertySetHandle)203 static OfxStatus render(OfxImageEffectHandle  /*instance*/,
204 			OfxPropertySetHandle /*inArgs*/,
205 			OfxPropertySetHandle /*outArg*/)
206 {
207   // do nothing as this should never be called as isIdentity should always be trapped
208   return kOfxStatOK;
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 // the interaction routines
213 struct MyInteractData {
214   bool selected;
215   OfxParamHandle pointParam;
216 
MyInteractDataMyInteractData217   explicit MyInteractData(OfxParamHandle pParam)
218     : selected(false)
219     , pointParam(pParam)
220   {
221   }
222 };
223 
224 // get the interact data from an interact instance
225 static MyInteractData *
getInteractData(OfxInteractHandle interactInstance)226 getInteractData(OfxInteractHandle interactInstance)
227 {
228   void *dataV = ofxuGetInteractInstanceData(interactInstance);
229   return (MyInteractData *) dataV;
230 }
231 
232 // creation of an interact instance
233 static OfxStatus
interactDescribe(OfxInteractHandle)234 interactDescribe(OfxInteractHandle /*interactDescriptor*/)
235 {
236   // and we are good
237   return kOfxStatOK;
238 }
239 
240 // creation of an interact instance
241 static OfxStatus
interactCreateInstance(OfxImageEffectHandle pluginInstance,OfxInteractHandle interactInstance)242 interactCreateInstance(OfxImageEffectHandle pluginInstance,
243 		       OfxInteractHandle interactInstance)
244 {
245   // get the parameter set for this effect
246   OfxParamSetHandle paramSet;
247   gEffectHost->getParamSet(pluginInstance, &paramSet);
248 
249   // fetch a handle to the point param from the parameter set
250   OfxParamHandle pointParam;
251   gParamHost->paramGetHandle(paramSet, kPointParam, &pointParam, 0);
252 
253   // make my interact's instance data
254   MyInteractData *data = new MyInteractData(pointParam);
255 
256   // and set the interact's data pointer
257   ofxuSetInteractInstanceData(interactInstance, (void *) data);
258 
259   OfxPropertySetHandle interactProps;
260   gInteractHost->interactGetPropertySet(interactInstance, &interactProps);
261 
262   // slave this interact to the point param so redraws are triggered cleanly
263   gPropHost->propSetString(interactProps, kOfxInteractPropSlaveToParam, 0, kPointParam);
264 
265   return kOfxStatOK;
266 }
267 
268 // destruction of an interact instance
269 static OfxStatus
interactDestroyInstance(OfxImageEffectHandle,OfxInteractHandle interactInstance)270 interactDestroyInstance(OfxImageEffectHandle /*pluginInstance*/,
271 			OfxInteractHandle interactInstance)
272 {
273   MyInteractData *data = getInteractData(interactInstance);
274   delete data;
275   return kOfxStatOK;
276 }
277 
278 // size of the cross hair in screen pixels
279 #define kXHairSize 10
280 
281 // draw an interact instance
282 static OfxStatus
interactDraw(OfxImageEffectHandle pluginInstance,OfxInteractHandle interactInstance,OfxPropertySetHandle drawArgs)283 interactDraw(OfxImageEffectHandle pluginInstance,
284 	     OfxInteractHandle interactInstance,
285 	     OfxPropertySetHandle drawArgs)
286 {
287   OfxStatus err;
288   // get my private interact data
289   MyInteractData *data = getInteractData(interactInstance);
290 
291   // get the project size
292   OfxPointD projSize = {1., 1.}, projOffset = {0., 0.};
293   ofxuGetProjectSetup(pluginInstance, projSize, projOffset);
294 
295   // get the size of a pixel in the current projection
296   double pixelScale[2];
297   ofxuGetInteractPixelScale(drawArgs, pixelScale);
298 
299   // get my param's value
300   double x, y;
301   if((err = getCustomParam(pluginInstance, x, y)) != kOfxStatOK)
302     return err;
303 
304   // scale it up to the project size as it is normalised
305   x = projOffset.x + x * projSize.x;
306   y = projOffset.y + y * projSize.y;
307 
308   // make the xhair a constant size on screen by scaling by the pixel scale
309   float dx = kXHairSize * pixelScale[0];
310   float dy = kXHairSize * pixelScale[1];
311 
312   // if the we have selected the Xhair, draw it highlit
313   if(data->selected)
314     glColor3f(1, 1, 1);
315   else
316     glColor3f(1, 0, 0);
317 
318   // Draw a cross hair, the current coordinate system aligns with the image plane.
319   glPushMatrix();
320 
321   glTranslated(x, y, 0);
322 
323   glBegin(GL_LINES);
324 
325   glVertex2f(-dx, 0);
326   glVertex2f(dx, 0);
327 
328   glVertex2f(0, -dy);
329   glVertex2f(0, dy);
330 
331   glEnd();
332 
333 
334   glPopMatrix();
335 
336   return kOfxStatOK;
337 }
338 
339 // function reacting to pen motion
340 static OfxStatus
interactPenMotion(OfxImageEffectHandle pluginInstance,OfxInteractHandle interactInstance,OfxPropertySetHandle inArgs)341 interactPenMotion(OfxImageEffectHandle pluginInstance,
342 		  OfxInteractHandle interactInstance,
343 		  OfxPropertySetHandle inArgs)
344 {
345   // get my data handle
346   MyInteractData *data = getInteractData(interactInstance);
347 
348   // Have we grabbed on a pen down already?
349   if(data->selected) {
350     // get the project size as we are normalising to this
351     OfxPointD projSize = {1., 1.}, projOffset = {0., 0.};
352     ofxuGetProjectSetup(pluginInstance, projSize, projOffset);
353 
354     // get the pen position and normalise that
355     OfxPointD penPos = {0., 0.};
356     gPropHost->propGetDoubleN(inArgs, kOfxInteractPropPenPosition, 2, &penPos.x);
357     penPos.x = (penPos.x - projOffset.x)/projSize.x;
358     penPos.y = (penPos.y - projOffset.y)/projSize.y;
359 
360     // set the value of the 'point' param
361     setCustomParam(pluginInstance, penPos.x, penPos.y);
362     return kOfxStatOK;
363   }
364   return kOfxStatReplyDefault;
365 }
366 
367 static OfxStatus
interactPenDown(OfxImageEffectHandle pluginInstance,OfxInteractHandle interactInstance,OfxPropertySetHandle inArgs)368 interactPenDown(OfxImageEffectHandle pluginInstance,
369 		OfxInteractHandle interactInstance,
370 		OfxPropertySetHandle inArgs)
371 {
372   // get my data handle
373   MyInteractData *data = getInteractData(interactInstance);
374 
375   // get the project size as we are normalising to this
376   OfxPointD projSize = {1., 1.}, projOffset = {0., 0.};
377   ofxuGetProjectSetup(pluginInstance, projSize, projOffset);
378 
379   // get the point param's value
380   double x, y;
381   OfxStatus stat = getCustomParam(pluginInstance, x, y);
382   if (stat != kOfxStatOK) {
383     return stat;
384   }
385 
386   // scale it up to the project size as it is a normalised spatial parameter
387   x = projOffset.x + x * projSize.x;
388   y = projOffset.y + y * projSize.y;
389 
390   // get the size of a pixel on screen
391   double pixelScale[2];
392   ofxuGetInteractPixelScale(inArgs, pixelScale);
393 
394   // see if the pen is within 5 screen pixels of the point, in which case, select it
395   double penPos[2];
396   gPropHost->propGetDoubleN(inArgs, kOfxInteractPropPenPosition, 2, penPos);
397   if(fabs(x - penPos[0]) < 5 * pixelScale[0] && fabs(y - penPos[1]) < 5 * pixelScale[1]) {
398     data->selected = true;
399     return kOfxStatOK;
400   }
401   return kOfxStatReplyDefault;
402 }
403 
404 static OfxStatus
interactPenUp(OfxImageEffectHandle,OfxInteractHandle interactInstance,OfxPropertySetHandle)405 interactPenUp(OfxImageEffectHandle /*pluginInstance*/,
406 	      OfxInteractHandle interactInstance,
407 	      OfxPropertySetHandle /*inArgs*/)
408 {
409   // get my data handle
410   MyInteractData *data = getInteractData(interactInstance);
411 
412   if(data->selected) {
413     // pen's gone up, deselect
414     data->selected = false;
415     return kOfxStatOK;
416   }
417   return kOfxStatReplyDefault;
418 }
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 // the entry point for the overlay
422 static OfxStatus
overlayMain(const char * action,const void * handle,OfxPropertySetHandle inArgs,OfxPropertySetHandle)423 overlayMain(const char *action,  const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle /*outArgs*/)
424 {
425   OfxInteractHandle interact = (OfxInteractHandle ) handle;
426 
427   OfxPropertySetHandle props;
428   gInteractHost->interactGetPropertySet(interact, &props);
429 
430   if(strcmp(action, kOfxActionDescribe) == 0) {
431     return interactDescribe(interact);
432   }
433   else {
434     // in which case handle is the interact instance
435 
436     // fetch the effect instance from the interact
437     OfxImageEffectHandle pluginInstance;
438     gPropHost->propGetPointer(props, kOfxPropEffectInstance, 0, (void **) &pluginInstance);
439 
440     if(strcmp(action, kOfxActionCreateInstance) == 0) {
441       return interactCreateInstance(pluginInstance, interact);
442     }
443     else if(strcmp(action, kOfxActionDestroyInstance) == 0) {
444       return interactDestroyInstance(pluginInstance, interact);
445     }
446     else if(strcmp(action, kOfxInteractActionDraw) == 0) {
447       return interactDraw(pluginInstance, interact, inArgs);
448     }
449     else if(strcmp(action, kOfxInteractActionPenMotion) == 0) {
450       return interactPenMotion(pluginInstance, interact, inArgs);
451     }
452     else if(strcmp(action, kOfxInteractActionPenDown) == 0) {
453       return interactPenDown(pluginInstance, interact, inArgs);
454     }
455     else if(strcmp(action, kOfxInteractActionPenUp) == 0) {
456       return interactPenUp(pluginInstance, interact, inArgs);
457     }
458       return kOfxStatReplyDefault;
459   }
460 }
461 
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 // the plugin's description routine
465 static OfxStatus
describe(OfxImageEffectHandle effect)466 describe(OfxImageEffectHandle effect)
467 {
468   // fetch the host APIs
469   OfxStatus stat;
470   if((stat = ofxuFetchHostSuites()) != kOfxStatOK)
471     return stat;
472 
473   // see if the host supports overlays and custom params and custom param animation
474   int supportsOverlays;
475   gPropHost->propGetInt(gHost->host, kOfxImageEffectPropSupportsOverlays, 0, &supportsOverlays);
476   if(supportsOverlays == 0)
477     return kOfxStatErrMissingHostFeature;
478 
479   // get the property handle for the plugin
480   OfxPropertySetHandle effectProps;
481   gEffectHost->getPropertySet(effect, &effectProps);
482 
483   // set the bit depths the plugin can handle
484   gPropHost->propSetString(effectProps, kOfxImageEffectPropSupportedPixelDepths, 0, kOfxBitDepthByte);
485   gPropHost->propSetString(effectProps, kOfxImageEffectPropSupportedPixelDepths, 1, kOfxBitDepthShort);
486   gPropHost->propSetString(effectProps, kOfxImageEffectPropSupportedPixelDepths, 2, kOfxBitDepthFloat);
487 
488   // define the plugin to the host
489   gPropHost->propSetString(effectProps, kOfxPropLabel, 0, "OFX Custom Param Example");
490   gPropHost->propSetString(effectProps, kOfxImageEffectPluginPropGrouping, 0, "OFX Example");
491 
492   // define the contexts we can be used in
493   gPropHost->propSetString(effectProps, kOfxImageEffectPropSupportedContexts, 0, kOfxImageEffectContextFilter);
494 
495   // set the property that is the overlay's main entry point for the plugin
496   gPropHost->propSetPointer(effectProps, kOfxImageEffectPluginPropOverlayInteractV1, 0,  (void *) overlayMain);
497 
498   return kOfxStatOK;
499 }
500 
501 static OfxStatus
describeInContext(OfxImageEffectHandle effect,OfxPropertySetHandle)502 describeInContext(OfxImageEffectHandle effect, OfxPropertySetHandle /*inArgs*/)
503 {
504   // define the mandated single source clip
505   OfxPropertySetHandle props;
506   gEffectHost->clipDefine(effect, kOfxImageEffectSimpleSourceClipName, &props);
507   gPropHost->propSetString(props, kOfxImageEffectPropSupportedComponents, 0, kOfxImageComponentRGBA);
508   gPropHost->propSetString(props, kOfxImageEffectPropSupportedComponents, 1, kOfxImageComponentAlpha);
509 
510   // define the output clip
511   gEffectHost->clipDefine(effect, kOfxImageEffectOutputClipName, &props);
512   gPropHost->propSetString(props, kOfxImageEffectPropSupportedComponents, 0, kOfxImageComponentRGBA);
513   gPropHost->propSetString(props, kOfxImageEffectPropSupportedComponents, 1, kOfxImageComponentAlpha);
514 
515   // fetch the parameter set from the effect
516   OfxParamSetHandle paramSet;
517   gEffectHost->getParamSet(effect, &paramSet);
518 
519   // Make a custom parameter
520   gParamHost->paramDefine(paramSet, kOfxParamTypeCustom, kPointParam, &props);
521   gPropHost->propSetString(props, kOfxParamPropDefault, 0, "0.5 0.5");
522   gPropHost->propSetString(props, kOfxParamPropScriptName, 0, "point");
523   gPropHost->propSetString(props, kOfxParamPropHint, 0, "Custom point attached to overlay crosshair");
524   gPropHost->propSetString(props, kOfxPropLabel, 0, "Point");
525 
526   // set the custom anim callback of the host supports custom animation
527   int supportsCustomAnim;
528   gPropHost->propGetInt(gHost->host, kOfxParamHostPropSupportsCustomAnimation, 0, &supportsCustomAnim);
529   if(supportsCustomAnim) {
530     gPropHost->propSetInt(props, kOfxParamPropAnimates, 0, true);
531     gPropHost->propSetPointer(props, kOfxParamPropCustomInterpCallbackV1, 0, (void *) customParamInterpFunction);
532   }
533   else {
534     gPropHost->propSetInt(props, kOfxParamPropAnimates, 0, false);
535   }
536 
537   return kOfxStatOK;
538 }
539 
540 ////////////////////////////////////////////////////////////////////////////////
541 // The main function
542 static OfxStatus
pluginMain(const char * action,const void * handle,OfxPropertySetHandle inArgs,OfxPropertySetHandle outArgs)543 pluginMain(const char *action,  const void *handle,  OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs)
544 {
545   try {
546   // cast to appropriate type
547   OfxImageEffectHandle effect = (OfxImageEffectHandle) handle;
548 
549   if(strcmp(action, kOfxActionDescribe) == 0) {
550     return describe(effect);
551   }
552   else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) {
553     return describeInContext(effect, inArgs);
554   }
555   else if(strcmp(action, kOfxActionCreateInstance) == 0) {
556     return createInstance(effect);
557   }
558   else if(strcmp(action, kOfxActionDestroyInstance) == 0) {
559     return destroyInstance(effect);
560   }
561   else if(strcmp(action, kOfxImageEffectActionIsIdentity) == 0) {
562     return isIdentity(effect, inArgs, outArgs);
563   }
564   else if(strcmp(action, kOfxImageEffectActionRender) == 0) {
565     return render(effect, inArgs, outArgs);
566   }
567   } catch (std::bad_alloc) {
568     // catch memory
569     //std::cout << "OFX Plugin Memory error." << std::endl;
570     return kOfxStatErrMemory;
571   } catch ( const std::exception& e ) {
572     // standard exceptions
573     //std::cout << "OFX Plugin error: " << e.what() << std::endl;
574     return kOfxStatErrUnknown;
575   } catch (int err) {
576       // ho hum, gone wrong somehow
577       return err;
578   } catch ( ... ) {
579     // everything else
580     //std::cout << "OFX Plugin error" << std::endl;
581     return kOfxStatErrUnknown;
582   }
583 
584   // other actions to take the default value
585   return kOfxStatReplyDefault;
586 }
587 
588 // function to set the host structure
589 static void
setHostFunc(OfxHost * hostStruct)590 setHostFunc(OfxHost *hostStruct)
591 {
592   gHost         = hostStruct;
593 }
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 // the plugin struct
597 static OfxPlugin basicPlugin =
598 {
599   kOfxImageEffectPluginApi,
600   1,
601   "uk.co.thefoundry.CustomParamPlugin",
602   1,
603   0,
604   setHostFunc,
605   pluginMain
606 };
607 
608 // the two mandated functions
609 EXPORT OfxPlugin *
OfxGetPlugin(int nth)610 OfxGetPlugin(int nth)
611 {
612   if(nth == 0)
613     return &basicPlugin;
614   return 0;
615 }
616 
617 EXPORT int
OfxGetNumberOfPlugins(void)618 OfxGetNumberOfPlugins(void)
619 {
620   return 1;
621 }
622