1 #ifndef _ofxsCore_H_ 2 #define _ofxsCore_H_ 3 /* 4 OFX Support Library, a library that skins the OFX plug-in API with C++ classes. 5 Copyright (C) 2004-2005 The Open Effects Association Ltd 6 Author Bruno Nicoletti bruno@thefoundry.co.uk 7 8 Redistribution and use in source and binary forms, with or without 9 modification, are permitted provided that the following conditions are met: 10 11 * Redistributions of source code must retain the above copyright notice, 12 this list of conditions and the following disclaimer. 13 * Redistributions in binary form must reproduce the above copyright notice, 14 this list of conditions and the following disclaimer in the documentation 15 and/or other materials provided with the distribution. 16 * Neither the name The Open Effects Association Ltd, nor the names of its 17 contributors may be used to endorse or promote products derived from this 18 software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 The Open Effects Association Ltd 32 1 Wardour St 33 London W1D 6PA 34 England 35 36 37 38 */ 39 40 41 /** @mainpage OFX Support Library 42 43 @section mainpageIntro Introduction 44 45 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. 46 47 <HR> 48 49 @section fifteenLineGuide Fifteen Line Plugin Writing Guide 50 51 - work from the examples 52 - you need to write the following functions.... 53 - void OFX::Plugin::getPluginID(OFX::PluginID &id) 54 - gives the unique name and version numbers of the plug-in 55 - void OFX::Plugin::loadAction(void) 56 - called after the plug-in is first loaded, and before any instance has been made, 57 - void OFX::Plugin::unloadAction(void) 58 - called before the plug-in is unloaded, and all instances have been destroyed, 59 - void OFX::Plugin::describe(OFX::ImageEffectDescriptor &desc) 60 - called to describe the plugin to the host 61 - void OFX::Plugin::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context) 62 - called to describe the plugin to the host for a context reported in OFX::Plugin::describe 63 - OFX::ImageEffect * OFX::Plugin::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context) 64 - 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. 65 66 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. 67 68 <HR> 69 70 @section license Copyright and License 71 72 The library is copyright 2004-2005, The Open Effects Association Ltd, and was 73 written by Bruno Nicoletti (bruno@thefoundry.co.uk). 74 75 It has been released under the GNU Lesser General Public License, see the 76 top of any source file for details. 77 78 */ 79 80 /** @file This file contains core code that wraps OFX 'objects' with C++ classes. 81 82 This file only holds code that is visible to a plugin implementation, and so hides much 83 of the direct OFX objects and any library side only functions. 84 */ 85 86 #ifdef _MSC_VER 87 #pragma warning( disable : 4290 ) 88 #endif 89 90 #include "ofxCore.h" 91 #include "ofxImageEffect.h" 92 #include "ofxInteract.h" 93 #include "ofxKeySyms.h" 94 #include "ofxMemory.h" 95 #include "ofxMessage.h" 96 #include "ofxMultiThread.h" 97 #include "ofxParam.h" 98 #include "ofxProperty.h" 99 #include "ofxPixels.h" 100 #ifdef OFX_SUPPORTS_DIALOG 101 #include "ofxDialog.h" 102 #endif 103 104 #include <assert.h> 105 #include <vector> 106 #include <list> 107 #include <string> 108 #include <map> 109 #include <exception> 110 #include <stdexcept> 111 #include <sstream> 112 #include <memory> 113 #if defined(_MSC_VER) 114 #include <float.h> // _isnan 115 #endif 116 #include <cmath> // isnan, std::isnan 117 118 #ifdef OFX_CLIENT_EXCEPTION_HEADER 119 #include OFX_CLIENT_EXCEPTION_HEADER 120 #endif 121 122 #if __cplusplus >= 201103L 123 # define OFX_THROW(x) noexcept(false) 124 # define OFX_THROW2(x,y) noexcept(false) 125 # define OFX_THROW3(x,y,z) noexcept(false) 126 # define OFX_THROW4(x,y,z,w) noexcept(false) 127 #else 128 # define OFX_THROW(x) throw(x) 129 # define OFX_THROW2(x,y) throw(x,y) 130 # define OFX_THROW3(x,y,z) throw(x,y,z) 131 # define OFX_THROW4(x,y,z,w) throw(x,y,z,w) 132 #endif 133 134 // Is noexcept supported? 135 // "noexcept" is only supported since the Visual Studio 2015, as stated here: https://msdn.microsoft.com/en-us/library/wfa0edys.aspx 136 #if defined(__clang__) 137 #if __has_feature(cxx_noexcept) 138 #define OFX_NOTHROW noexcept(true) 139 #else 140 #define OFX_NOTHROW throw() 141 #endif 142 #else 143 #if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \ 144 defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 145 #define OFX_NOTHROW noexcept(true) 146 #else 147 #if defined(_NOEXCEPT) 148 #define OFX_NOTHROW _NOEXCEPT 149 #else 150 #define OFX_NOTHROW throw() 151 #endif 152 #endif 153 #endif 154 155 /** @brief Defines an integer 3D point 156 157 Should migrate this to the ofxCore.h in a v1.1 158 */ 159 struct Ofx3DPointI { 160 int x, y, z; 161 }; 162 163 /** @brief Defines a double precision 3D point 164 165 Should migrate this to the ofxCore.h in a v1.1 166 */ 167 struct Ofx3DPointD { 168 double x, y, z; 169 }; 170 171 /** @brief Nasty macro used to define empty protected copy ctors and assign ops */ 172 #define mDeclareProtectedAssignAndCC(CLASS) \ 173 CLASS &operator=(const CLASS &) {assert(false); return *this;} \ 174 CLASS(const CLASS &) {assert(false); } 175 176 /** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. 177 */ 178 namespace OFX { 179 #if __cplusplus >= 201103L 180 template <typename T> 181 using auto_ptr = std::unique_ptr<T>; 182 #else 183 using std::auto_ptr; 184 #endif 185 186 // can be defined by Magick++.h 187 #undef IsNaN 188 #if defined(_MSC_VER) IsInfinite(double x)189 inline bool IsInfinite(double x) { return _finite(x) == 0 && _isnan(x) == 0; } IsNaN(double x)190 inline bool IsNaN (double x) { return _isnan(x) != 0; } 191 #else 192 # if __cplusplus >= 201103L || _GLIBCXX_USE_C99_MATH 193 // These definitions are for the normal Unix suspects. IsInfinite(double x)194 inline bool IsInfinite(double x) { return (std::isinf)(x); } IsNaN(double x)195 inline bool IsNaN (double x) { return (std::isnan)(x); } 196 # else 197 # ifdef isnan // isnan is defined as a macro IsInfinite(double x)198 inline bool IsInfinite(double x) { return isinf(x); } IsNaN(double x)199 inline bool IsNaN (double x) { return isnan(x); } 200 # else IsInfinite(double x)201 inline bool IsInfinite(double x) { return ::isinf(x); } IsNaN(double x)202 inline bool IsNaN (double x) { return ::isnan(x); } 203 # endif 204 # endif 205 #endif 206 207 /** forward class declarations */ 208 class PropertySet; 209 210 /** @brief Enumerates the different types a property can be */ 211 enum PropertyTypeEnum { 212 ePointer, 213 eInt, 214 eString, 215 eDouble 216 }; 217 218 /** @brief Enumerates the reasons a plug-in instance may have had one of its values changed */ 219 enum InstanceChangeReason { 220 eChangeUserEdit, /**< @brief A user actively editted something in the plugin, eg: changed the value of an integer param on an interface */ 221 eChangePluginEdit, /**< @brief The plugin's own code changed something in the instance, eg: a callback on on param settting the value of another */ 222 eChangeTime /**< @brief The current value of a parameter has changed because the param animates and the current time has changed */ 223 }; 224 225 /** @brief maps a status to a string for debugging purposes, note a c-str for printf */ 226 const char * mapStatusToString(OfxStatus stat); 227 228 /** @brief namespace for OFX support lib exceptions, all derive from std::exception, calling it */ 229 namespace Exception { 230 231 /** @brief thrown when a suite returns a dud status code 232 */ 233 class Suite : public std::exception { 234 protected : 235 OfxStatus _status; 236 public : Suite(OfxStatus s)237 Suite(OfxStatus s) : _status(s) {} status(void)238 OfxStatus status(void) const {return _status;} OfxStatus()239 operator OfxStatus() const {return _status;} 240 241 /** @brief reimplemented from std::exception */ what()242 virtual const char * what () const OFX_NOTHROW {return mapStatusToString(_status);} 243 244 }; 245 246 /** @brief Exception indicating that a host doesn't know about a property that is should do */ 247 class PropertyUnknownToHost : public std::exception { 248 protected : 249 std::string _what; 250 public : PropertyUnknownToHost(const char * what)251 PropertyUnknownToHost(const char *what) : _what(what) {} ~PropertyUnknownToHost()252 virtual ~PropertyUnknownToHost() OFX_NOTHROW {} 253 254 /** @brief reimplemented from std::exception */ what()255 virtual const char * what () const OFX_NOTHROW 256 { 257 return _what.c_str(); 258 } 259 }; 260 261 /** @brief exception indicating that the host thinks a property has an illegal value */ 262 class PropertyValueIllegalToHost : public std::exception { 263 protected : 264 std::string _what; 265 public : PropertyValueIllegalToHost(const char * what)266 PropertyValueIllegalToHost(const char *what) : _what(what) {} ~PropertyValueIllegalToHost()267 virtual ~PropertyValueIllegalToHost() OFX_NOTHROW {} 268 269 /** @brief reimplemented from std::exception */ what()270 virtual const char * what () const OFX_NOTHROW 271 { 272 return _what.c_str(); 273 } 274 }; 275 276 /** @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 277 indicates a logical error in the code. Asserts are raised in debug code in these situations. 278 */ 279 class TypeRequest : public std::exception { 280 protected : 281 std::string _what; 282 public : TypeRequest(const char * what)283 TypeRequest(const char *what) : _what(what) {} ~TypeRequest()284 virtual ~TypeRequest() OFX_NOTHROW {} 285 286 /** @brief reimplemented from std::exception */ what()287 virtual const char * what () const OFX_NOTHROW 288 { 289 return _what.c_str(); 290 } 291 }; 292 293 //////////////////////////////////////////////////////////////////////////////// 294 // These exceptions are to be thrown by the plugin if it hits a problem, the 295 // code managing the main entry will trap the exception and return a suitable 296 // status code to the host. 297 298 /** @brief exception indicating a required host feature is missing */ 299 class HostInadequate : public std::exception { 300 protected : 301 std::string _what; 302 public : HostInadequate(const char * what)303 HostInadequate(const char *what) : _what(what) {} ~HostInadequate()304 virtual ~HostInadequate() OFX_NOTHROW {} 305 306 /** @brief reimplemented from std::exception */ what()307 virtual const char * what () const OFX_NOTHROW 308 { 309 return _what.c_str(); 310 } 311 }; 312 313 }; // end of Exception namespace 314 315 /** @brief Throws an @ref OFX::Exception::Suite depending on the status flag passed in */ 316 void 317 throwSuiteStatusException(OfxStatus stat) 318 OFX_THROW2(OFX::Exception::Suite, std::bad_alloc); 319 320 void 321 throwHostMissingSuiteException(const std::string& name) 322 OFX_THROW(OFX::Exception::Suite); 323 324 /** @brief This struct is used to return an identifier for the plugin by the function @ref OFX:Plugin::getPlugin. 325 The members correspond to those in the OfxPlugin struct defined in ofxCore.h. 326 */ 327 328 class ImageEffectDescriptor; 329 class ImageEffect; 330 331 /** @brief This class wraps up an OFX property set */ 332 class PropertySet { 333 protected : 334 /** @brief The raw property handle */ 335 OfxPropertySetHandle _propHandle; 336 337 /** @brief Class static, whether we are logging each property action */ 338 static int _gPropLogging; 339 340 /** @brief Do not throw an exception if a host returns 'unsupported' when setting a property */ 341 static bool _gThrowOnUnsupported; 342 343 public : 344 /** @brief turns on logging of property access functions */ propEnableLogging(void)345 static void propEnableLogging(void) {++_gPropLogging;} 346 347 /** @brief turns off logging of property access functions */ propDisableLogging(void)348 static void propDisableLogging(void) {--_gPropLogging;} 349 350 /** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */ setThrowOnUnsupportedProperties(bool v)351 static void setThrowOnUnsupportedProperties(bool v) {_gThrowOnUnsupported = v;} 352 353 /** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */ getThrowOnUnsupportedProperties(void)354 static bool getThrowOnUnsupportedProperties(void) {return _gThrowOnUnsupported;} 355 356 /** @brief construct a property set */ _propHandle(h)357 PropertySet(OfxPropertySetHandle h = NULL) : _propHandle(h) {} 358 virtual ~PropertySet(); 359 360 /** @brief copy constructor */ PropertySet(const PropertySet & p)361 PropertySet(const PropertySet& p) { _propHandle = p.propSetHandle(); } 362 PropertySet& operator=(const PropertySet& p) { _propHandle = p.propSetHandle(); return *this; } 363 364 public: 365 /** @brief set the handle to use for this set */ propSetHandle(OfxPropertySetHandle h)366 void propSetHandle(OfxPropertySetHandle h) { _propHandle = h;} 367 368 /** @brief return the handle for this property set */ propSetHandle(void)369 OfxPropertySetHandle propSetHandle(void) const {return _propHandle;} 370 371 bool propExists(const char* property, bool throwOnFailure = true) const OFX_THROW3(std::bad_alloc, 372 OFX::Exception::PropertyValueIllegalToHost, 373 OFX::Exception::Suite); 374 int propGetDimension(const char* property, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 375 OFX::Exception::PropertyUnknownToHost, 376 OFX::Exception::PropertyValueIllegalToHost, 377 OFX::Exception::Suite); 378 void propReset(const char* property) OFX_THROW4(std::bad_alloc, 379 OFX::Exception::PropertyUnknownToHost, 380 OFX::Exception::PropertyValueIllegalToHost, 381 OFX::Exception::Suite); 382 383 // set single values 384 void propSetPointer(const char* property, void *value, int idx, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 385 OFX::Exception::PropertyUnknownToHost, 386 OFX::Exception::PropertyValueIllegalToHost, 387 OFX::Exception::Suite); 388 void propSetString(const char* property, const std::string &value, int idx, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 389 OFX::Exception::PropertyUnknownToHost, 390 OFX::Exception::PropertyValueIllegalToHost, 391 OFX::Exception::Suite); 392 void propSetDouble(const char* property, double value, int idx, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 393 OFX::Exception::PropertyUnknownToHost, 394 OFX::Exception::PropertyValueIllegalToHost, 395 OFX::Exception::Suite); 396 void propSetInt(const char* property, int value, int idx, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 397 OFX::Exception::PropertyUnknownToHost, 398 OFX::Exception::PropertyValueIllegalToHost, 399 OFX::Exception::Suite); 400 401 // set multiple values 402 void propSetStringN(const char* property, const std::vector<std::string> &values, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 403 OFX::Exception::PropertyUnknownToHost, 404 OFX::Exception::PropertyValueIllegalToHost, 405 OFX::Exception::Suite); 406 407 void propSetDoubleN(const char* property, const std::vector<double> &values, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 408 OFX::Exception::PropertyUnknownToHost, 409 OFX::Exception::PropertyValueIllegalToHost, 410 OFX::Exception::Suite); 411 412 void propSetDoubleN(const char* property, const double *values, int count, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 413 OFX::Exception::PropertyUnknownToHost, 414 OFX::Exception::PropertyValueIllegalToHost, 415 OFX::Exception::Suite); 416 417 void propSetIntN(const char* property, const std::vector<int> &values, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 418 OFX::Exception::PropertyUnknownToHost, 419 OFX::Exception::PropertyValueIllegalToHost, 420 OFX::Exception::Suite); 421 422 // values is before count to avoid an easy confusion with propSetInt, whet the pointer to values would be cast to bool 423 void propSetIntN(const char* property, const int *values, int count, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 424 OFX::Exception::PropertyUnknownToHost, 425 OFX::Exception::PropertyValueIllegalToHost, 426 OFX::Exception::Suite); 427 428 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)429 void propSetPointer(const char* property, void *value, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 430 OFX::Exception::PropertyUnknownToHost, 431 OFX::Exception::PropertyValueIllegalToHost, 432 OFX::Exception::Suite) 433 {propSetPointer(property, value, 0, throwOnFailure);} 434 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)435 void propSetString(const char* property, const std::string &value, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 436 OFX::Exception::PropertyUnknownToHost, 437 OFX::Exception::PropertyValueIllegalToHost, 438 OFX::Exception::Suite) 439 {propSetString(property, value, 0, throwOnFailure);} 440 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)441 void propSetDouble(const char* property, double value, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 442 OFX::Exception::PropertyUnknownToHost, 443 OFX::Exception::PropertyValueIllegalToHost, 444 OFX::Exception::Suite) 445 {propSetDouble(property, value, 0, throwOnFailure);} 446 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)447 void propSetInt(const char* property, int value, bool throwOnFailure = true) OFX_THROW4(std::bad_alloc, 448 OFX::Exception::PropertyUnknownToHost, 449 OFX::Exception::PropertyValueIllegalToHost, 450 OFX::Exception::Suite) 451 {propSetInt(property, value, 0, throwOnFailure);} 452 453 454 /// get a pointer property 455 void *propGetPointer(const char* property, int idx, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 456 OFX::Exception::PropertyUnknownToHost, 457 OFX::Exception::PropertyValueIllegalToHost, 458 OFX::Exception::Suite); 459 460 /// get a string property 461 std::string propGetString(const char* property, int idx, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 462 OFX::Exception::PropertyUnknownToHost, 463 OFX::Exception::PropertyValueIllegalToHost, 464 OFX::Exception::Suite); 465 466 /// get a double property 467 double propGetDouble(const char* property, int idx, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 468 OFX::Exception::PropertyUnknownToHost, 469 OFX::Exception::PropertyValueIllegalToHost, 470 OFX::Exception::Suite); 471 472 /// get an int property 473 int propGetInt(const char* property, int idx, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 474 OFX::Exception::PropertyUnknownToHost, 475 OFX::Exception::PropertyValueIllegalToHost, 476 OFX::Exception::Suite); 477 478 /// get a pointer property with index 0 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)479 void* propGetPointer(const char* property, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 480 OFX::Exception::PropertyUnknownToHost, 481 OFX::Exception::PropertyValueIllegalToHost, 482 OFX::Exception::Suite) 483 { 484 return propGetPointer(property, 0, throwOnFailure); 485 } 486 487 /// get a string property with index 0 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)488 std::string propGetString(const char* property, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 489 OFX::Exception::PropertyUnknownToHost, 490 OFX::Exception::PropertyValueIllegalToHost, 491 OFX::Exception::Suite) 492 { 493 return propGetString(property, 0, throwOnFailure); 494 } 495 496 /// get a double property with index 0 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)497 double propGetDouble(const char* property, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 498 OFX::Exception::PropertyUnknownToHost, 499 OFX::Exception::PropertyValueIllegalToHost, 500 OFX::Exception::Suite) 501 { 502 return propGetDouble(property, 0, throwOnFailure); 503 } 504 505 /// get an int property with index 0 OFX_THROW4(std::bad_alloc,OFX::Exception::PropertyUnknownToHost,OFX::Exception::PropertyValueIllegalToHost,OFX::Exception::Suite)506 int propGetInt(const char* property, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 507 OFX::Exception::PropertyUnknownToHost, 508 OFX::Exception::PropertyValueIllegalToHost, 509 OFX::Exception::Suite) 510 { 511 return propGetInt(property, 0, throwOnFailure); 512 } 513 514 void propGetStringN(const char* property, std::vector<std::string>* values, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 515 OFX::Exception::PropertyUnknownToHost, 516 OFX::Exception::PropertyValueIllegalToHost, 517 OFX::Exception::Suite); 518 519 void propGetDoubleN(const char* property, std::vector<double>* values, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 520 OFX::Exception::PropertyUnknownToHost, 521 OFX::Exception::PropertyValueIllegalToHost, 522 OFX::Exception::Suite); 523 524 // values is before count to avoid an easy confusion with propGetDouble, whet the pointer to values would be cast to bool 525 void propGetDoubleN(const char* property, double* values, int count, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 526 OFX::Exception::PropertyUnknownToHost, 527 OFX::Exception::PropertyValueIllegalToHost, 528 OFX::Exception::Suite); 529 530 void propGetIntN(const char* property, std::vector<int>* values, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 531 OFX::Exception::PropertyUnknownToHost, 532 OFX::Exception::PropertyValueIllegalToHost, 533 OFX::Exception::Suite); 534 535 void propGetIntN(const char* property, int* values, int count, bool throwOnFailure = true) const OFX_THROW4(std::bad_alloc, 536 OFX::Exception::PropertyUnknownToHost, 537 OFX::Exception::PropertyValueIllegalToHost, 538 OFX::Exception::Suite); 539 540 }; 541 542 // forward decl of the image effect 543 class ImageEffect; 544 }; 545 546 // undeclare the protected assign and CC macro 547 #undef mDeclareProtectedAssignAndCC 548 549 #endif 550