From 9f0533bbf7a959af4678cc15641469d418085a85 Mon Sep 17 00:00:00 2001 From: John-Paul Smith Date: Thu, 11 Jul 2024 16:48:52 +0100 Subject: [PATCH] Support versioning native styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the API should remain stable, colourspaces will change over time, and it’s likely hosts and plug-ins will support multiple versions of the spec for backwards compatibility. To address this, new properties have been introduced to allow negotiation of the config to use for native mode. This is somewhat similar to the use of built-in configs in OCIO. Now that the native mode config negotiation is handled separately, the OCIO config property is reserved for use only in the OCIO style. Hosts are now responsible for selecting the colour management style and config, and must set these in image effect properties. Anticipating support for multiple versions, ofxColourspaceList.h has been renamed to a versioned name and is referred to as “the config header”. For now, it could be used as a drop-in replacement for ofxColourspaceList.h, but as soon as a second version is added, developers will need a strategy to manage these. Additionally, the basic colourspaces have been renamed to include whether they are scene or display referred, and a descriptive label has been added. Signed-off-by: John-Paul Smith --- ... => ofx-native-v1.5_aces-v1.3_ocio-v2.3.h} | 88 +++++++------- ... ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio} | 2 +- include/ofxColour.h | 109 ++++++++++-------- scripts/genColour | 43 ++++--- scripts/genOCIOConfig | 2 +- 5 files changed, 138 insertions(+), 106 deletions(-) rename include/{ofxColourspaceList.h => ofx-native-v1.5_aces-v1.3_ocio-v2.3.h} (94%) rename include/{openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio => ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio} (99%) diff --git a/include/ofxColourspaceList.h b/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h similarity index 94% rename from include/ofxColourspaceList.h rename to include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h index 014fee8e..c4cb01d6 100644 --- a/include/ofxColourspaceList.h +++ b/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.h @@ -1,5 +1,5 @@ -#ifndef _ofxColourspaceList_h_ -#define _ofxColourspaceList_h_ +#ifndef _ofx_native_v1_5_aces_v1_3_ocio_v2_3_h_ +#define _ofx_native_v1_5_aces_v1_3_ocio_v2_3_h_ // Copyright OpenFX and contributors to the OpenFX project. // SPDX-License-Identifier: BSD-3-Clause @@ -10,67 +10,69 @@ extern "C" { /** @file ofxColourspaceList.h Contains the list of supported colourspaces. -This file was auto-generated by scripts/genColour from openfx-native-v1.5_aces-v1.3_ocio-v2.3. +This file was auto-generated by scripts/genColour from ofx-native-v1.5_aces-v1.3_ocio-v2.3. */ +// For use with kOfxImageEffectPropColourManagementAvailableConfigs +#define kOfxConfigIdentifier "ofx-native-v1.5_aces-v1.3_ocio-v2.3" // Basic Colourspaces // These colourspaces are generic names for any colourspace with the correct attributes. -/** @brief ofx_hdr -Any display-referred HDR video such as Rec. 2020 HLG or PQ. +/** @brief ofx_display_hdr +Any display-referred HDR video such as Rec. 2100 HLG or PQ. */ -#define kOfxColourspaceOfxHdr "ofx_hdr" -#define kOfxColourspaceOfxHdrLabel "ofx_hdr" -#define kOfxColourspaceOfxHdrEncoding "hdr-video" -#define kOfxColourspaceOfxHdrIsData false -#define kOfxColourspaceOfxHdrIsBasic true -#define kOfxColourspaceOfxHdrIsCore true -#define kOfxColourspaceOfxHdrIsDisplay true - -/** @brief ofx_linear -Any scene-referred linear colourspace. -*/ -#define kOfxColourspaceOfxLinear "ofx_linear" -#define kOfxColourspaceOfxLinearLabel "ofx_linear" -#define kOfxColourspaceOfxLinearEncoding "scene-linear" -#define kOfxColourspaceOfxLinearIsData false -#define kOfxColourspaceOfxLinearIsBasic true -#define kOfxColourspaceOfxLinearIsCore true -#define kOfxColourspaceOfxLinearIsDisplay false - -/** @brief ofx_log -Any scene-referred colourspace with a log transfer function. +#define kOfxColourspaceOfxDisplayHdr "ofx_display_hdr" +#define kOfxColourspaceOfxDisplayHdrLabel "OFX generic display HDR" +#define kOfxColourspaceOfxDisplayHdrEncoding "hdr-video" +#define kOfxColourspaceOfxDisplayHdrIsData false +#define kOfxColourspaceOfxDisplayHdrIsBasic true +#define kOfxColourspaceOfxDisplayHdrIsCore true +#define kOfxColourspaceOfxDisplayHdrIsDisplay true + +/** @brief ofx_display_sdr +Any display-referred SDR video such as Rec. 709. */ -#define kOfxColourspaceOfxLog "ofx_log" -#define kOfxColourspaceOfxLogLabel "ofx_log" -#define kOfxColourspaceOfxLogEncoding "log" -#define kOfxColourspaceOfxLogIsData false -#define kOfxColourspaceOfxLogIsBasic true -#define kOfxColourspaceOfxLogIsCore true -#define kOfxColourspaceOfxLogIsDisplay false +#define kOfxColourspaceOfxDisplaySdr "ofx_display_sdr" +#define kOfxColourspaceOfxDisplaySdrLabel "OFX generic display SDR" +#define kOfxColourspaceOfxDisplaySdrEncoding "sdr-video" +#define kOfxColourspaceOfxDisplaySdrIsData false +#define kOfxColourspaceOfxDisplaySdrIsBasic true +#define kOfxColourspaceOfxDisplaySdrIsCore true +#define kOfxColourspaceOfxDisplaySdrIsDisplay true /** @brief ofx_raw Image values should not be treated as colour, e.g. motion vectors or masks. */ #define kOfxColourspaceOfxRaw "ofx_raw" -#define kOfxColourspaceOfxRawLabel "ofx_raw" +#define kOfxColourspaceOfxRawLabel "OFX generic raw" #define kOfxColourspaceOfxRawEncoding "" #define kOfxColourspaceOfxRawIsData true #define kOfxColourspaceOfxRawIsBasic true #define kOfxColourspaceOfxRawIsCore true #define kOfxColourspaceOfxRawIsDisplay false -/** @brief ofx_sdr -Any display-referred SDR video such as Rec. 709. +/** @brief ofx_scene_linear +Any scene-referred linear colourspace. +*/ +#define kOfxColourspaceOfxSceneLinear "ofx_scene_linear" +#define kOfxColourspaceOfxSceneLinearLabel "OFX generic scene linear" +#define kOfxColourspaceOfxSceneLinearEncoding "scene-linear" +#define kOfxColourspaceOfxSceneLinearIsData false +#define kOfxColourspaceOfxSceneLinearIsBasic true +#define kOfxColourspaceOfxSceneLinearIsCore true +#define kOfxColourspaceOfxSceneLinearIsDisplay false + +/** @brief ofx_scene_log +Any scene-referred colourspace with a log transfer function. */ -#define kOfxColourspaceOfxSdr "ofx_sdr" -#define kOfxColourspaceOfxSdrLabel "ofx_sdr" -#define kOfxColourspaceOfxSdrEncoding "sdr-video" -#define kOfxColourspaceOfxSdrIsData false -#define kOfxColourspaceOfxSdrIsBasic true -#define kOfxColourspaceOfxSdrIsCore true -#define kOfxColourspaceOfxSdrIsDisplay true +#define kOfxColourspaceOfxSceneLog "ofx_scene_log" +#define kOfxColourspaceOfxSceneLogLabel "OFX generic scene log" +#define kOfxColourspaceOfxSceneLogEncoding "log" +#define kOfxColourspaceOfxSceneLogIsData false +#define kOfxColourspaceOfxSceneLogIsBasic true +#define kOfxColourspaceOfxSceneLogIsCore true +#define kOfxColourspaceOfxSceneLogIsDisplay false // Core Colourspaces diff --git a/include/openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio b/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio similarity index 99% rename from include/openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio rename to include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio index dece8ee7..d071cf66 100644 --- a/include/openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio +++ b/include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio @@ -5,7 +5,7 @@ environment: search_path: "" strictparsing: true luma: [0.2126, 0.7152, 0.0722] -name: openfx-native-v1.5_aces-v1.3_ocio-v2.3 +name: ofx-native-v1.5_aces-v1.3_ocio-v2.3 description: | OpenFX 1.5 Native Mode Config Based on: Academy Color Encoding System - Studio Config [COLORSPACES v2.1.0] [ACES v1.3] [OCIO v2.3] diff --git a/include/ofxColour.h b/include/ofxColour.h index 594757f6..96b78885 100644 --- a/include/ofxColour.h +++ b/include/ofxColour.h @@ -15,13 +15,13 @@ Contains the API for colourspace data exchange. /** @brief What style of colour management does the host or plug-in offer? - Type - string X 1 - - Property Set - host descriptor (read only), plugin descriptor (read/write) + - Property Set - host descriptor (read only), plugin descriptor (read/write), image effect instance (read only) - Default - kOfxImageEffectPropColourManagementStyleNone - Valid Values - This must be one of - ::kOfxImageEffectPropColourManagementNone - no colour management - - ::kOfxImageEffectPropColourManagementBasic - only basic colourspaces from ofxColourspaceList.h may be used - - ::kOfxImageEffectPropColourManagementCore - only core colourspaces from ofxColourspaceList.h may be used - - ::kOfxImageEffectPropColourManagementFull - any colourspace from ofxColourspaceList.h may be used + - ::kOfxImageEffectPropColourManagementBasic - only basic colourspaces from the config header may be used + - ::kOfxImageEffectPropColourManagementCore - only core colourspaces from the config header may be used + - ::kOfxImageEffectPropColourManagementFull - any colourspace from the config header may be used - ::kOfxImageEffectPropColourManagementOCIO - any OCIO config may be used (implies use of the OCIO library) Hosts should set this property if they will provide colourspace information @@ -32,17 +32,19 @@ Collectively, the full, core and basic styles are referred to as native colour management. OCIO is used as the reference for the colour management API, but is not required to implement the native styles. -The colourspace strings used in the native styles are from -openfx-native-1.5.ocio, which is based on the OCIO ACES Studio built-in -config, studio-config-v2.1.0_aces-v1.3_ocio-v2.3, and stored for OFX purposes -in ofxColourspaceList.h. Additionally, there is a scheme for cross-referencing -between clips, and a set of "basic colourspaces", which are designed to be -generic names for a family of colourspaces. When a basic colourspace is used, -this means the host is free to choose any colourspace with the same encoding -and reference space (scene vs display). +The colourspace strings used in the native styles are from ofx-native-1.5.ocio, +which is based on the OCIO ACES Studio built-in config, +studio-config-v2.1.0_aces-v1.3_ocio-v2.3, and stored for OFX purposes in +openfx-native-v1.5_aces-v1.3_ocio-v2.3.h (referred to as the config header). +Additionally, there is a scheme for cross-referencing between clips, and a set +of "basic colourspaces", which are designed to be generic names for a family of +colourspaces. When a basic colourspace is used, this means the host is free to +choose any colourspace with the same encoding and reference space (scene vs +display). The assumption is that OCIO > Full > Core > Basic, so the highest style -supported by both host and plug-in will be chosen. +supported by both host and plug-in should usually be chosen by the host. +The chosen style must be set using this property on an image effect instance. */ #define kOfxImageEffectPropColourManagementStyle "OfxImageEffectPropColourManagementStyle" @@ -57,6 +59,33 @@ supported by both host and plug-in will be chosen. /* String used to indicate that OCIO colour management is available. */ #define kOfxImageEffectPropColourManagementOCIO "OfxImageEffectPropColourManagementOCIO" +/** @brief What native mode configs are supported? + + - Type - string X N + - Property Set - host descriptor (read only), plugin descriptor (read/write) + - Valid Values - A list of config identifiers. The only currently supported + value is ofx-native-v1.5_aces-v1.3_ocio-v2.3. + +While the API for colour management is expected to be stable, the set of +colourspaces will evolve over time. This property must be set by both plug-ins +and hosts specifying the list of native mode configs that are available on each +side. +*/ +#define kOfxImageEffectPropColourManagementAvailableConfigs "OfxImageEffectPropColourManagementAvailableConfigs" + +/** @brief The native colour management config to be used for this instance + + - Type - string X 1 + - Property Set - image effect instance (read only) + - Valid Values - any string provided by the plug-in in + kOfxImageEffectPropColourManagementAvailableConfigs + +If kOfxImageEffectPropColourManagementStyle for the instance is a native style, +the host must set this property to indicate the native colour management config +the plug-in should be used to look up colourspace strings. +*/ +#define kOfxImageEffectPropColourManagementConfig "OfxImageEffectPropColourManagementConfig" + /** @brief The path to the OCIO config used for this instance - Type - string X 1 @@ -66,20 +95,6 @@ supported by both host and plug-in will be chosen. A host must set this property on any effect instances where it has negotiated OCIO colour management (kOfxImageEffectPropColourManagementOCIO). Use of URIs for built-in configs, such as ocio://default is permitted. - -When the core or full styles are in use, a host must set this property to -point to an OCIO config which defines all the colourspaces required for that -style, which will allow a plug-in that uses OCIO to work directly with native -styles. The included config, openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio, is -suitable, but hosts might provide a different config which is compatible. If -hosts choose to use their own config, its definitions for native colourspaces -must exactly match those found in openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio. - -As basic colourspaces are not defined in the OpenFX native config, hosts may -set this property as they wish when using the basic style. If hosts do provide -a config, an OCIO-based plug-in may attempt to use it to look up mappings for -basic colourspaces, but leaving those undefined must not be considered an -error. */ #define kOfxImageEffectPropOCIOConfig "OfxImageEffectPropOCIOConfig" @@ -103,9 +118,9 @@ kOfxImageClipPropPreferredColourspace where reasonable. Cross-referencing between clips is possible by setting this property to "OfxColourspace_". For example a plug-in may set this property on its output clip to "OfxColourspace_Source", telling the host that the colourspace -of the output matches the input. In the basic style, plug-ins are recommended -to use cross-referencing for their output clip unless kOfxColourspaceRaw is -required. +of the output matches the "Source" input clip. In the basic style, plug-ins +are recommended to use cross-referencing for their output clip unless +kOfxColourspaceRaw is required. If a clip sets OfxImageClipPropIsMask or it only supports OfxImageComponentAlpha, colour management is disabled and this property @@ -118,9 +133,9 @@ must be unset. - Type - string X N - Property Set - clip instance (read only) and ::kOfxImageEffectActionGetClipPreferences action out args property (read/write) - Valid Values - colourspace that is permitted under the style in use. - For Basic, any colourspace from ofxColourspaceList.h where IsBasic is true. - For Core, any colourspace from ofxColourspaceList.h where IsCore is true. - For Full, any colourspace from ofxColourspaceList.h. + For Basic, any colourspace from the config header where IsBasic is true. + For Core, any colourspace from the config header where IsCore is true. + For Full, any colourspace from the config header. For OCIO, any string acceptable to Config::getColorSpace(). Plug-ins may set this property during kOfxImageEffectActionGetClipPreferences @@ -156,11 +171,9 @@ plug-in is capable of adapting to any input colourspace, it should not set this preference. Cross-referencing between clips is possible by setting this property to -"OfxColourspace_". For example a plug-in may set this property on a -second input clip to "OfxColourspace_Source" to tell the host it would like -both input clips to be in the same colourspace. A host might set the same -thing on the plug-in's output clip to request that the plug-in outputs the -same colourspace as the input. +"OfxColourspace_". For example, a plug-in in a transition context may set +this property on its "SourceTo" clip to "OfxColourspace_SourceFrom", telling +the host it would like both input clips to be in the same colourspace. If a plug-in has inputs which expect motion vectors, depth values or other non-colour channels, it should set the preferred colourspace to @@ -174,7 +187,7 @@ the request and set kOfxImageClipPropColourspace to kOfxColourspaceRaw. - Type - string X 1 - Property Set - image effect instance (read only) - - Valid Values - any colourspace from ofxColourspaceList.h + - Valid Values - any colourspace from the config header Used with native colour management styles, this property is relevant for plug-ins which have their own viewport in a custom window. Plug-ins should @@ -215,20 +228,24 @@ If not defined, the default rules for choosing a view will be followed. This action allows a host to ask an effect, given a list of preferred colourspaces, what colourspace will be used for its output clip. This should be called after first gathering the plug-ins preferred input colourspaces - via OfxImageEffectActionGetClipPreferences. The host must set - kOfxImageClipPropColourspace on the output clip to the chosen colourspace, - or the default value of OfxColourspace_Source. + via OfxImageEffectActionGetClipPreferences. + + Cross-references to input clip colourspaces are permitted, for example in a + filter context, the host might request "OfxColourspace_Source". @param handle handle to the instance, cast to an \ref OfxImageEffectHandle @param inArgs has the property - - \ref kOfxImageClipPropPreferredColourspaces the list of preferred colourspaces + - \ref kOfxImageClipPropPreferredColourspaces the host's list of preferred colourspaces @param outArgs has the property - - \ref kOfxImageClipPropColourspace the colourspace selected by the plug-in + - \ref kOfxImageClipPropColourspace the colourspace selected by the plug-in, + which may be a cross-reference to an input clip. @returns - - \ref kOfxStatOK, the action was trapped and the colourspace was set in the outArgs property set - - \ref kOfxStatReplyDefault, the action was not trapped and the host should use the default value of OfxColourspace_Source + - \ref kOfxStatOK, the action was trapped and the colourspace was set in + the outArgs property set + - \ref kOfxStatReplyDefault, the action was not trapped and the host + should use the colourspace of the first input clip - \ref kOfxStatErrMemory, in which case the action may be called again after a memory purge - \ref kOfxStatFailed, something wrong, but no error code appropriate, plugin to post message - \ref kOfxStatErrFatal diff --git a/scripts/genColour b/scripts/genColour index d302c787..dab251ac 100755 --- a/scripts/genColour +++ b/scripts/genColour @@ -5,14 +5,14 @@ # Extract information from an OCIO config to C header. # Example invocation: -# OCIO=include/openfx-native-v1.5_aces-v1.3_ocio-v2.3.ocio scripts/genColour > include/ofxColourspaceList.h +# OCIO=include/ofx-native-v1.5_aces-v1.3_ocio-v2.3.ocio scripts/genColour > include/ofxColourspaceList.h import sys import PyOpenColorIO as OCIO from string import Template -header = '''#ifndef _ofxColourspaceList_h_ -#define _ofxColourspaceList_h_ +header = '''#ifndef _${config_name_us}_h_ +#define _${config_name_us}_h_ // Copyright OpenFX and contributors to the OpenFX project. // SPDX-License-Identifier: BSD-3-Clause @@ -25,6 +25,9 @@ extern "C" { Contains the list of supported colourspaces. This file was auto-generated by scripts/genColour from $config_name. */ + +// For use with kOfxImageEffectPropColourManagementAvailableConfigs +#define kOfxConfigIdentifier "$config_name" ''' footer = ''' @@ -36,10 +39,10 @@ footer = ''' ''' role_docs = { - 'ofx_sdr': 'Any display-referred SDR video such as Rec. 709.', - 'ofx_hdr': 'Any display-referred HDR video such as Rec. 2020 HLG or PQ.', - 'ofx_log': 'Any scene-referred colourspace with a log transfer function.', - 'ofx_linear': 'Any scene-referred linear colourspace.', + 'ofx_display_sdr': 'Any display-referred SDR video such as Rec. 709.', + 'ofx_display_hdr': 'Any display-referred HDR video such as Rec. 2100 HLG or PQ.', + 'ofx_scene_log': 'Any scene-referred colourspace with a log transfer function.', + 'ofx_scene_linear': 'Any scene-referred linear colourspace.', 'ofx_raw': 'Image values should not be treated as colour, e.g. motion vectors or masks.', 'aces_interchange': 'Guaranteed to be ACES2065-1.', 'cie_xyz_d65_interchange': 'CIE XYZ colorimetry with the neutral axis at D65.', @@ -52,6 +55,14 @@ role_docs = { 'texture_paint': 'A colourspace suitable for texture painting, typically sRGB.' } +basic_colourspace_labels = { + 'ofx_display_sdr': 'OFX generic display SDR', + 'ofx_display_hdr': 'OFX generic display HDR', + 'ofx_scene_log': 'OFX generic scene log', + 'ofx_scene_linear': 'OFX generic scene linear', + 'ofx_raw': 'OFX generic raw' +} + chars_to_delete = str.maketrans('', '', ' -.()') def camel_name(name): return ' '.join([word[0].upper() + word[1:] for word in name.replace(' ', '_').split('_')]).translate(chars_to_delete) @@ -83,7 +94,7 @@ def print_basic_colourspace(role): spc = ofx_config.getColorSpace(role[1]) print(f'\n/** @brief {role_name}\n{role_docs[role_name]}\n*/') print_name(role_name) - print_metadata(role_name, role_name, spc.getReferenceSpaceType(), spc.getEncoding(), spc.isData(), True, True) + print_metadata(role_name, basic_colourspace_labels[role_name], spc.getReferenceSpaceType(), spc.getEncoding(), spc.isData(), True, True) def print_role(role): role_name = role[0] @@ -108,7 +119,7 @@ def print_colourspace(spc, is_core): print_metadata(name, label, spc.getReferenceSpaceType(), spc.getEncoding(), spc.isData(), False, is_core) # OFX-specific set of basic roles -basic_roles = ['ofx_raw', 'ofx_linear', 'ofx_sdr', 'ofx_log', 'ofx_hdr'] +basic_roles = ['ofx_raw', 'ofx_scene_linear', 'ofx_display_sdr', 'ofx_scene_log', 'ofx_display_hdr'] # OFX-specific set of core colourspaces core_spaces = ['srgb_display', 'displayp3_display', 'rec1886_rec709_display', @@ -127,15 +138,17 @@ ofx_config = OCIO.GetCurrentConfig() # to avoid creating an expectation that these mappings should always be used. # The assigned colourspaces are chosen simply to generate the correct # attributes in the header. -ofx_config.setRole('ofx_sdr', 'rec1886_rec709_display') -ofx_config.setRole('ofx_hdr', 'rec2100_hlg_display') -ofx_config.setRole('ofx_log', 'ACEScct') -ofx_config.setRole('ofx_linear', 'ACEScg') +ofx_config.setRole('ofx_display_sdr', 'rec1886_rec709_display') +ofx_config.setRole('ofx_display_hdr', 'rec2100_hlg_display') +ofx_config.setRole('ofx_scene_log', 'ACEScct') +ofx_config.setRole('ofx_scene_linear', 'ACEScg') ofx_config.setRole('ofx_raw', 'raw') -print(Template(header).substitute(config_name=ofx_config.getName())) +config_name = ofx_config.getName() +print(Template(header).substitute(config_name=config_name, + config_name_us=config_name.replace('-', '_').replace('.', '_'))) -print('\n// Basic Colourspaces\n// These colourspaces are generic names for any colourspace with the correct attributes.') +print('// Basic Colourspaces\n// These colourspaces are generic names for any colourspace with the correct attributes.') for basic_role in [role for role in ofx_config.getRoles() if role[0] in basic_roles]: print_basic_colourspace(basic_role) diff --git a/scripts/genOCIOConfig b/scripts/genOCIOConfig index 84fa937e..16eb831a 100755 --- a/scripts/genOCIOConfig +++ b/scripts/genOCIOConfig @@ -18,7 +18,7 @@ srgb_tx.setEncoding('sdr-video') # Make all colourspaces active, future OCIO configs will also do this ofx_config.setInactiveColorSpaces('') -ofx_config.setName(f'openfx-native-v1.5_aces-v1.3_ocio-v2.3') +ofx_config.setName(f'ofx-native-v1.5_aces-v1.3_ocio-v2.3') ofx_config.setDescription(f'OpenFX 1.5 Native Mode Config\nBased on: {ofx_config.getDescription()}') ofx_config.validate() # will throw if there's an error