openfx-sys 0.1.0

Rust bindings for OpenFX
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

/*
Software License :

Copyright (c) 2007-2009, The Open Effects Association Ltd.  All Rights Reserved.

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.
*/

#ifndef OFX_IMAGE_EFFECT_H
#define OFX_IMAGE_EFFECT_H

#include "ofxCore.h"
#include "ofxImageEffect.h"

#include "ofxhHost.h"
#include "ofxhClip.h"
#include "ofxhProgress.h"
#include "ofxhTimeLine.h"
#include "ofxhParam.h"
#include "ofxhMemory.h"
#include "ofxhInteract.h"

#ifdef _MSC_VER
//Use visual studio extension
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif

namespace OFX {

  namespace Host {

    // forward declare    
    class Plugin;

    namespace Memory {
      class Instance;
    }

    namespace ImageEffect {

      // forward declare
      class ImageEffectPlugin;
      class OverlayInstance;
      class Instance;
      class Descriptor;

      /// An image effect host, passed to the setHost function of all image effect plugins
      class Host : public OFX::Host::Host {
      public :
        Host();

        /// fetch a suite
        virtual const void *fetchSuite(const char *suiteName, int suiteVersion);

        /// Create a new instance of an image effect plug-in.
        ///
        /// It is called by ImageEffectPlugin::createInstance which the
        /// client code calls when it wants to make a new instance.
        /// 
        ///   \arg clientData - the clientData passed into the ImageEffectPlugin::createInstance
        ///   \arg plugin - the plugin being created
        ///   \arg desc - the descriptor for that plugin
        ///   \arg context - the context to be created in
        virtual Instance* newInstance(void* clientData,
                                      ImageEffectPlugin* plugin,
                                      Descriptor& desc,
                                      const std::string& context) = 0;

        /// Function called as each plugin binary is found and loaded from disk
        ///
        /// Use this in any dialogue etc... showing progress
        virtual void loadingStatus(const std::string &);
        
        /// Override this to filter out plugins which the host can't support for whatever reason
        ///
        ///   \arg plugin - the plugin to examine
        ///   \arg reason - set this to report the reason the plugin was not loaded
        virtual bool pluginSupported(ImageEffectPlugin *plugin, std::string &reason) const;

        /// Override this to create a descriptor, this makes the 'root' descriptor
        virtual Descriptor *makeDescriptor(ImageEffectPlugin* plugin) = 0;

        /// used to construct a context description, rootContext is the main context
        virtual Descriptor *makeDescriptor(const Descriptor &rootContext, ImageEffectPlugin *plug) = 0;        

        /// used to construct populate the cache
        virtual Descriptor *makeDescriptor(const std::string &bundlePath, ImageEffectPlugin *plug) = 0;

        /// Override this to initialise an image effect descriptor after it has been
        /// created.
        virtual void initDescriptor(Descriptor* desc);

#ifdef OFX_SUPPORTS_MULTITHREAD
        // these functions must be implemented if the host supports OfxMultiThreadSuiteV1
        // all the following functions are described in ofxMultiThread.h
        //

        /// @see OfxMultiThreadSuiteV1.multiThread()
        virtual OfxStatus multiThread(OfxThreadFunctionV1 func,unsigned int nThreads, void *customArg) = 0;
          
        /// @see OfxMultiThreadSuiteV1.multiThreadNumCPUS()
        virtual OfxStatus multiThreadNumCPUS(unsigned int *nCPUs) const = 0;

        /// @see OfxMultiThreadSuiteV1.multiThreadIndex()
        virtual OfxStatus multiThreadIndex(unsigned int *threadIndex) const = 0;
          
        /// @see OfxMultiThreadSuiteV1.multiThreadIsSpawnedThread()
        virtual int multiThreadIsSpawnedThread() const = 0;
          
        /// @see OfxMultiThreadSuiteV1.mutexCreate()
        virtual OfxStatus mutexCreate(OfxMutexHandle *mutex, int lockCount) = 0;
          
        /// @see OfxMultiThreadSuiteV1.mutexDestroy()
        virtual OfxStatus mutexDestroy(const OfxMutexHandle mutex) = 0;

        /// @see OfxMultiThreadSuiteV1.mutexLock()
        virtual OfxStatus mutexLock(const OfxMutexHandle mutex) = 0;
          
        /// @see OfxMultiThreadSuiteV1.mutexUnLock()
        virtual OfxStatus mutexUnLock(const OfxMutexHandle mutex) = 0;
          
        /// @see OfxMultiThreadSuiteV1.mutexTryLock()
        virtual OfxStatus mutexTryLock(const OfxMutexHandle mutex) = 0;
#endif // OFX_SUPPORTS_MULTITHREAD

#     ifdef OFX_SUPPORTS_OPENGLRENDER
        /// @see OfxImageEffectOpenGLRenderSuiteV1.flushResources()
        virtual OfxStatus flushOpenGLResources() const = 0;
#     endif

        /// override this to use your own memory instance - must inherrit from memory::instance
        virtual Memory::Instance* newMemoryInstance(size_t nBytes);

        // return an memory::instance calls makeMemoryInstance that can be overriden
        Memory::Instance* imageMemoryAlloc(size_t nBytes);
      };

      /// our global host object, set when the plugin cache is created
      extern Host *gImageEffectHost;

      ////////////////////////////////////////////////////////////////////////////////
      /// base class to both effect descriptors and instances
      class Base {
      protected:        
        Property::Set   _properties;

      public:
        Base(const Property::Set &set);
        Base(const Property::PropSpec * propSpec);
        virtual ~Base();

        /// is my magic number valid?
        virtual bool verifyMagic() { return true; }

        /// obtain a handle on this for passing to the C api
        OfxImageEffectHandle getHandle() const;

        /// get the properties set
        Property::Set &getProps();

        /// get the properties set, const version
        const Property::Set &getProps() const;

        /// name of the clip
        const std::string &getShortLabel() const;
        
        /// name of the clip
        const std::string &getLabel() const;
        
        /// name of the clip
        const std::string &getLongLabel() const;

        /// is the given context supported
        bool isContextSupported(const std::string &s) const;

        /// what is the name of the group the plug-in belongs to
        const std::string &getPluginGrouping() const;

        /// is the effect single instance
        bool isSingleInstance() const;

        /// what is the thread safety on this effect
        const std::string &getRenderThreadSafety() const;

        /// should the host attempt to managed multi-threaded rendering if it can
        /// via tiling or some such
        bool getHostFrameThreading() const;

        /// get the overlay interact main entry if it exists
        OfxPluginEntryPoint *getOverlayInteractMainEntry() const;

        /// does the effect support images of differing sizes
        bool supportsMultiResolution() const;

        /// does the effect support tiled rendering
        bool supportsTiles() const;

        /// does this effect need random temporal access
        bool temporalAccess() const;

        /// is the given RGBA/A pixel depth supported by the effect
        bool isPixelDepthSupported(const std::string &s) const;

        /// when field rendering, does the effect need to be called
        /// twice to render a frame in all circumstances (with different fields)
        bool fieldRenderTwiceAlways() const;
        
        /// does the effect support multiple clip depths
        bool supportsMultipleClipDepths() const;
        
        /// does the effect support multiple clip pixel aspect ratios
        bool supportsMultipleClipPARs() const;
        
        /// does changing the named param re-tigger a clip preferences action
        bool isClipPreferencesSlaveParam(const std::string &s) const;

      };

      /// an image effect plugin descriptor
      class Descriptor 
        : public Base
        , public Param::SetDescriptor {
      private :
        // private CC
        Descriptor(const Descriptor &other)
          : Base(other._properties)
          , Param::SetDescriptor()
          , _plugin(other._plugin)
        {}

      protected:
        Plugin                                 *_plugin;       ///< the plugin I belong to
        std::map<std::string, ClipDescriptor*>  _clips;        ///< clips descriptors by name
        std::vector<ClipDescriptor*>            _clipsByOrder; ///< clip descriptors in order of declaration
        mutable Interact::Descriptor            _overlayDescriptor; ///< descriptor to use for overlays, it has delayed description

      public:
        /// used to construct the global description
        Descriptor(Plugin *plug);        
        
        /// used to construct a context description, 'other' is the main context
        Descriptor(const Descriptor &rootContext, Plugin *plug);        
        
        /// used to construct populate the cache
        Descriptor(const std::string &bundlePath, Plugin *plug);

        /// dtor
        virtual ~Descriptor();

        /// implemented for Param::SetDescriptor
        virtual Property::Set &getParamSetProps();

        /// get the plugin I belong to
        Plugin *getPlugin() const {return _plugin;}

        /// create a new clip and add this to the clip map
        virtual ClipDescriptor *defineClip(const std::string &name);

        /// get the clips
        const std::map<std::string, ClipDescriptor*> &getClips() const;

        /// add a new clip
        void addClip(const std::string &name, ClipDescriptor *clip);

        /// get the clips in order of construction
        const std::vector<ClipDescriptor*> &getClipsByOrder() const
        {
          return _clipsByOrder;
        }

        /// Get the interact description, this will also call describe on the interact
        /// This will return NULL if there is not main entry point or if the description failed
        /// otherwise it will return the described overlay
        Interact::Descriptor &getOverlayDescriptor(int bitDepthPerComponent = 8, bool hasAlpha = false);
      };      

      /// a map used to specify needed frame ranges on set of clips
      typedef std::map<ClipInstance *, std::vector<OfxRangeD> > RangeMap;

      /// an image effect plugin instance.
      ///
      /// Client code needs to filling the pure virtuals in this.
      class Instance : public Base,
                       public Param::SetInstance,
                       public Progress::ProgressI,
                       public TimeLine::TimeLineI,
                       private Property::NotifyHook, 
                       private Property::GetHook
      {
      protected:
        OFX::Host::ImageEffect::ImageEffectPlugin    *_plugin;
        std::string                                   _context;
        Descriptor                                   *_descriptor;
        std::map<std::string, ClipInstance*>          _clips;
        bool                                          _interactive;
        bool                                          _created;

        bool                                          _clipPrefsDirty; ///< do we need to re-run the clip prefs action
        bool                                          _continuousSamples; ///< set by clip prefs
        bool                                          _frameVarying; ///< set by clip prefs
        std::string                                   _outputPreMultiplication;  ///< set by clip prefs
        std::string                                   _outputFielding;  ///< set by clip prefs
        double                                        _outputFrameRate; ///< set by clip prefs

      public:        
        /// constructor based on clip descriptor
        Instance(ImageEffectPlugin* plugin,
                 Descriptor         &other, 
                 const std::string  &context,
                 bool               interactive);

        virtual ~Instance();

        /// implemented for Param::SetInstance
        virtual Property::Set &getParamSetProps();

        /// implemented for Param::SetInstance
        virtual void paramChangedByPlugin(Param::Instance *param);

        /// get the descriptor for this instance
        const Descriptor &getDescriptor() const {return *_descriptor;}

        /// return the plugin this instance was created with
        OFX::Host::ImageEffect::ImageEffectPlugin*getPlugin() const { return _plugin; }

        /// return the context this instance was created with
        const std::string &getContext() const { return _context; }

        /// get the descriptor for this instance
        Descriptor &getDescriptor() {return *_descriptor;}

        /// get default output fielding. This is passed into the clip prefs action
        /// and  might be mapped (if the host allows such a thing)
        virtual const std::string &getDefaultOutputFielding() const = 0;

        /// get output fielding as set in the clip preferences action.
        const std::string &getOutputFielding() const {return _outputFielding; }

        /// get output fielding as set in the clip preferences action.
        const std::string &getOutputPreMultiplication() const {return _outputPreMultiplication; }

        /// get the output frame rate, as set in the clip prefences action.
        double getOutputFrameRate() const {return _outputFrameRate;}


        /// called after construction to populate the various members
        /// ideally should be called in the ctor, but it relies on 
        /// virtuals so has to be delayed until after the effect is
        /// constructed
        OfxStatus populate();

        /// get the nth clip, in order of declaration
        ClipInstance* getNthClip(int index);

        /// get the nth clip, in order of declaration
        int getNClips() const
        {
          return int(_clips.size());
        }

        /// are the clip preferences currently dirty
        bool areClipPrefsDirty() const {return _clipPrefsDirty;}

        /// are all the non optional clips connected
        bool checkClipConnectionStatus() const;

        /// can this this instance render images at arbitrary times, not just frame boundaries
        /// set by getClipPreferenceAction()
        bool continuousSamples() const {return _continuousSamples;}

        /// does this instance generate a different picture on a frame change, even if the
        /// params and input images are exactly the same. eg: random noise generator
        bool isFrameVarying() const {return _frameVarying;}

        /// pure virtuals that must  be overriden
        virtual ClipInstance* getClip(const std::string& name) const;

        /// override this to make processing abort, return 1 to abort processing
        virtual int abort();

        /// override this to use your own memory instance - must inherrit from memory::instance
        virtual Memory::Instance* newMemoryInstance(size_t nBytes);

        // return an memory::instance calls makeMemoryInstance that can be overriden
        Memory::Instance* imageMemoryAlloc(size_t nBytes);

        /// make a clip
        virtual ClipInstance* newClipInstance(ImageEffect::Instance* plugin,
                                              ClipDescriptor* descriptor, 
                                              int index) = 0;

        /// message suite
        virtual OfxStatus vmessage(const char* type,
                                   const char* id,
                                   const char* format,	
                                   va_list args) = 0;  

        virtual OfxStatus setPersistentMessage(const char* type,
                                               const char* id,
                                               const char* format,
                                               va_list args) = 0;

        virtual OfxStatus clearPersistentMessage() = 0;  


        /// call the effect entry point
        virtual OfxStatus mainEntry(const char *action, 
                                    const void *handle, 
                                    Property::Set *inArgs,
                                    Property::Set *outArgs);

        int upperGetDimension(const std::string &name);

        /// overridden from Property::Notify
        virtual void notify(const std::string &name, bool singleValue, int indexOrN) OFX_EXCEPTION_SPEC;

        /// overridden from gethook,  get the virutals for viewport size, pixel scale, background colour
        virtual double getDoubleProperty(const std::string &name, int index) const OFX_EXCEPTION_SPEC;

        /// 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 OFX_EXCEPTION_SPEC;
        
        /// overridden from gethook, don't know what to do
        virtual void reset(const std::string &name) OFX_EXCEPTION_SPEC;

        //// overridden from gethook
        virtual int getDimension(const std::string &name)  const OFX_EXCEPTION_SPEC;

        //
        // 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 &paramName,
                                                     const std::string & why,
                                                     OfxTime     time,
                                                     OfxPointD   renderScale);

        virtual OfxStatus clipInstanceChangedAction(const std::string &clipName,
                                                     const std::string & why,
                                                    OfxTime     time,
                                                    OfxPointD   renderScale);

        virtual OfxStatus endInstanceChangedAction(const std::string &why);

        // purge your caches
        virtual OfxStatus purgeCachesAction();

        // sync your private data
        virtual OfxStatus syncPrivateDataAction();

        // begin/end edit instance
        virtual OfxStatus beginInstanceEditAction();
        virtual OfxStatus endInstanceEditAction();

#     ifdef OFX_SUPPORTS_OPENGLRENDER
        // attach/detach OpenGL context
        virtual OfxStatus contextAttachedAction();
        virtual OfxStatus contextDetachedAction();
#     endif
          
        // render action
        virtual OfxStatus beginRenderAction(OfxTime  startFrame,
                                            OfxTime  endFrame,
                                            OfxTime  step,
                                            bool     interactive,
                                            OfxPointD   renderScale,
                                            bool     sequentialRender,
                                            bool     interactiveRender
                                            );

        virtual OfxStatus renderAction(OfxTime      time,
                                       const std::string &  field,
                                       const OfxRectI &renderRoI,
                                       OfxPointD   renderScale,
                                       bool     sequentialRender,
                                       bool     interactiveRender,
                                       bool     draftRender
                                       );

        virtual OfxStatus endRenderAction(OfxTime  startFrame,
                                          OfxTime  endFrame,
                                          OfxTime  step,
                                          bool     interactive,
                                          OfxPointD   renderScale,
                                          bool     sequentialRender,
                                          bool     interactiveRender
                                          );

        /// Call the region of definition action the plugin at the given time
        /// and with the given render scales. The value is returned in rod.
        /// Note that if the plugin does not trap the action the default
        /// RoD is calculated and returned. 
        virtual OfxStatus getRegionOfDefinitionAction(OfxTime  time,
                                                      OfxPointD   renderScale,
                                                      OfxRectD &rod);
        
        /// call the get region of interest action on the plugin for the 
        /// given frame and renderscale. The render RoI is passed in in
        /// roi, the std::map will contain the requested rois. Note
        /// That this call will check for tiling support and for
        /// default replies and set up the correct rois in these cases
        /// as well
        virtual OfxStatus getRegionOfInterestAction(OfxTime  time,
                                                    OfxPointD   renderScale,
                                                    const OfxRectD &roi,
                                                    std::map<ClipInstance *, OfxRectD> &rois);

        // get frames needed to render the given frame
        virtual OfxStatus getFrameNeededAction(OfxTime time, 
                                               RangeMap &rangeMap);
 
        // is identity
        virtual OfxStatus isIdentityAction(OfxTime     &time,
                                           const std::string &  field,
                                           const OfxRectI  &renderRoI,
                                           OfxPointD   renderScale,
                                           std::string &clip);

        // time domain
        virtual OfxStatus getTimeDomainAction(OfxRangeD& range);

        /// Get the interact description, this will also call describe on the interact
        /// This will return NULL if there is not main entry point or if the description failed
        /// otherwise it will return the described overlay
        /// This is called by the CTOR of OverlayInteract to get the descriptor to do things with
        Interact::Descriptor &getOverlayDescriptor(int bitDepthPerComponent = 8, bool hasAlpha = false);
       
        /// Setup the default clip preferences on the clips
        virtual void setDefaultClipPreferences();

        /// Initialise the clip preferences arguments, override this to do
        /// stuff with wierd components etc... Calls setDefaultClipPreferences
        virtual void setupClipPreferencesArgs(Property::Set &args);

        /// Run the clip preferences action from the effect.
        /// 
        /// This will look into the input clips and output clip
        /// and set the following properties that the effect should 
        /// fetch the image at.
        ///     - pixel depth
        ///     - components
        ///     - pixel aspect ratio
        /// It will also set on the effect itselff
        ///     - whether it is continuously samplable
        ///     - the premult state of the output
        ///     - whether the effect is frame varying
        ///     - the fielding of the output clip
        ///
        /// This will be run automatically by the effect in the following situations...
        ///     - an input clip is changed
        ///     - a clip preferences slave param is changed
        /// 
        /// The host still needs to call this explicitly just after the effect is wired
        /// up.
        virtual bool getClipPreferences();

        /// calls getClipPreferences only if the prefs are dirty
        ///
        /// returns whether the clips prefs were dirty or not
        bool runGetClipPrefsConditionally()
        {
          if(areClipPrefsDirty()) {
            getClipPreferences();
            return true;
          }
          return false;
        }
        
        /// find the best supported bit depth for the given one. Override this if you define
        /// more depths
        virtual const std::string &bestSupportedDepth(const std::string &depth) const;

        /// find the most chromatic components out of the two. Override this if you define
        /// more chromatic components
        virtual const std::string &findMostChromaticComponents(const std::string &a, const std::string &b) const;
      };

      ////////////////////////////////////////////////////////////////////////////////
      /// An overlay interact for image effects, derived from one of these to
      /// be an overlay interact
      class OverlayInteract : public Interact::Instance {
      protected :
        /// our image effect instance
        ImageEffect::Instance &_instance;

      public    :
        /// ctor this calls Instance->getOverlayDescriptor to get the descriptor
        OverlayInteract(ImageEffect::Instance &v, int bitDepthPerComponent = 8, bool hasAlpha = false);
      };


    } // namespace ImageEffect

  } // namespace Host

} // namespace OFX

#endif // OFX_IMAGE_EFFECT_H