HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OpenColorIO.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 // Copyright Contributors to the OpenColorIO Project.
3 
4 
5 #ifndef INCLUDED_OCIO_OPENCOLORIO_H
6 #define INCLUDED_OCIO_OPENCOLORIO_H
7 
8 #include <cstddef>
9 #include <iosfwd>
10 #include <limits>
11 #include <stdexcept>
12 #include <string>
13 #include <fstream>
14 #include <vector>
15 #include <cstdint>
16 #include <map>
17 
18 #include "OpenColorABI.h"
19 #include "OpenColorTypes.h"
20 #include "OpenColorTransforms.h"
21 #include "OpenColorAppHelpers.h"
22 
23 /*
24 
25 C++ API
26 =======
27 
28 **Usage Example:** *Compositing plugin that converts from "log" to "lin"*
29 
30 .. code-block:: cpp
31 
32  #include <OpenColorIO/OpenColorIO.h>
33  namespace OCIO = OCIO_NAMESPACE;
34 
35  try
36  {
37  // Get the global OpenColorIO config
38  // This will auto-initialize (using $OCIO) on first use
39  OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
40 
41  // Get the processor corresponding to this transform.
42  OCIO::ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_COMPOSITING_LOG,
43  OCIO::ROLE_SCENE_LINEAR);
44 
45  // Get the corresponding CPU processor for 32-bit float image processing.
46  OCIO::ConstCPUProcessorRcPtr cpuProcessor = processor->getDefaultCPUProcessor();
47 
48  // Wrap the image in a light-weight ImageDescription
49  OCIO::PackedImageDesc img(imageData, w, h, 4);
50 
51  // Apply the color transformation (in place)
52  cpuProcessor->apply(img);
53  }
54  catch(OCIO::Exception & exception)
55  {
56  std::cerr << "OpenColorIO Error: " << exception.what() << std::endl;
57  }
58 
59 */
60 
61 namespace OCIO_NAMESPACE
62 {
63 ///////////////////////////////////////////////////////////////////////////
64 // Exceptions
65 
66 // Silence warning C4275 under Visual Studio:
67 // Exceptions derive from std::runtime_error but STL classes are not exportable.
68 #ifdef _MSC_VER
69 #pragma warning( push )
70 #pragma warning( disable : 4275 )
71 #endif
72 
73 /**
74  * \brief An exception class to throw for errors detected at runtime.
75  *
76  * \warning
77  * All functions in the Config class can potentially throw this exception.
78  */
79 class OCIOEXPORT Exception : public std::runtime_error
80 {
81 public:
82  Exception() = delete;
83  /// Constructor that takes a string as the exception message.
84  explicit Exception(const char *);
85  /// Constructor that takes an existing exception.
86  Exception(const Exception &);
87  Exception & operator= (const Exception &) = delete;
88 
89  ~Exception();
90 };
91 
92 /**
93  * \brief An exception class for errors detected at runtime.
94  *
95  * Thrown when OCIO cannot find a file that is expected to exist. This is provided as a custom
96  * type to distinguish cases where one wants to continue looking for missing files, but wants
97  * to properly fail for other error conditions.
98  */
100 {
101 public:
102  ExceptionMissingFile() = delete;
103  /// Constructor that takes a string as the exception message.
104  explicit ExceptionMissingFile(const char *);
105  /// Constructor that takes an existing exception.
108 
110 };
111 
112 // Restore default warning behaviour for Visual Studio.
113 #ifdef _MSC_VER
114 #pragma warning( pop )
115 #endif
116 
117 ///////////////////////////////////////////////////////////////////////////
118 // Global
119 // ******
120 
121 /**
122  * During normal usage, OpenColorIO tends to cache certain global information (such
123  * as the contents of LUTs on disk, intermediate results, etc.). Calling this function will flush
124  * all such information. The global information are related to LUT file identifications, loaded LUT
125  * file content and CDL transforms from loaded CDL files.
126  *
127  * Under normal usage, this is not necessary, but it can be helpful in particular instances,
128  * such as designing OCIO profiles, and wanting to re-read luts without restarting.
129  *
130  * \note
131  * This method does not apply to instance-specific caches such as the Processor cache in
132  * a Config instance or the GPU and CPU Processor caches in a Processor instance. So in cases
133  * where you still have a Config instance after calling ClearAllCaches, you should also call
134  * the Config's clearProcessorCache method.
135  */
136 extern OCIOEXPORT void ClearAllCaches();
137 
138 /**
139  * \brief Get the version number for the library, as a dot-delimited string
140  * (e.g., "1.0.0").
141  *
142  * This is also available at compile time as OCIO_VERSION_FULL_STR.
143  */
144 extern OCIOEXPORT const char * GetVersion();
145 
146 /**
147  * \brief Get the version number for the library, as a
148  * single 4-byte hex number (e.g., 0x01050200 for "1.5.2"), to be used
149  * for numeric comparisons.
150  *
151  * This is also at compile time as OCIO_VERSION_HEX.
152  */
153 extern OCIOEXPORT int GetVersionHex();
154 
155 /**
156  * \brief Get the global logging level.
157  *
158  * You can override this at runtime using the \ref OCIO_LOGGING_LEVEL
159  * environment variable. The client application that sets this should use
160  * \ref SetLoggingLevel, and not the environment variable. The default value is INFO.
161  */
163 
164 /// Set the global logging level.
166 
167 /**
168  * \brief Set the logging function to use; otherwise, use the default
169  * (i.e. std::cerr).
170  *
171  * \note
172  * The logging mechanism is thread-safe.
173  */
174 extern OCIOEXPORT void SetLoggingFunction(LoggingFunction logFunction);
176 /// Log a message using the library logging function.
177 extern OCIOEXPORT void LogMessage(LoggingLevel level, const char * message);
178 
179 /**
180  * \brief Set the Compute Hash Function to use; otherwise, use the default.
181  *
182  * This is not used when using CreateFromFile with an OCIOZ archive or CreateFromConfigIOProxy.
183  *
184  * \param ComputeHashFunction
185  */
186 extern OCIOEXPORT void SetComputeHashFunction(ComputeHashFunction hashFunction);
188 
189 //
190 // Note that the following environment variable access methods are not thread safe.
191 //
192 
193 /**
194  * Another call modifies the string obtained from a previous call as the method always uses the
195  * same memory buffer.
196  */
197 extern OCIOEXPORT const char * GetEnvVariable(const char * name);
198 /// \warning This method is not thread safe.
199 extern OCIOEXPORT void SetEnvVariable(const char * name, const char * value);
200 /// \warning This method is not thread safe.
201 extern OCIOEXPORT void UnsetEnvVariable(const char * name);
202 //!cpp:function::
203 extern OCIOEXPORT bool IsEnvVariablePresent(const char * name);
204 
205 /// Get the current configuration.
207 
208 /// Set the current configuration. This will then store a copy of the specified config.
209 extern OCIOEXPORT void SetCurrentConfig(const ConstConfigRcPtr & config);
210 
211 /**
212  * \brief Make a config path forward-compatible by replacing special built-in config names
213  * with the current name.
214  *
215  * Application developers should call this function on any config path they intend to persist
216  * (e.g., to include in a file saved from a DCC).
217  *
218  * As the built-in config collection evolves, special names such as "ocio://default" and
219  * "ocio://studio-config-latest" will point to newer versions of those configs. Therefore, it is
220  * recommended that application developers not save those strings and instead save the string that
221  * refers to the current version of that config. That way, it's guaranteed that there will be no
222  * change of behavior in the future. For example, as of OCIO 2.5, "ocio://default" should be saved
223  * as "ocio://cg-config-v4.0.0_aces-v2.0_ocio-v2.5".
224  *
225  * Note that there is no validation done on the path. That is left to the application since
226  * typically the application will load the config before attempting to save its path
227  * and therefore catch, for example, a badly formed URI such as "ocio:default".
228  *
229  * \return Resolved path if possible. Otherwise, the original path is returned unmodified.
230  */
231 extern OCIOEXPORT const char * ResolveConfigPath(const char * originalPath) noexcept;
232 
233 /**
234  * \brief Extract an OCIO Config archive.
235  *
236  * Converts an archived config file (.ocioz file) back to its original form as a config file
237  * and associated LUT files. This creates destinationDir and then creates a config.ocio file
238  * at the root of that working directory and then unpacks the LUT files into their relative
239  * locations relative to that working directory, creating any necessary sub-directories in the
240  * process. Note that configs which contain LUT files outside the working directory are not
241  * archivable, and so this function will not create directories outside the working directory.
242  *
243  * \param archivePath Absolute path to the .ocioz file.
244  * \param destinationDir Absolute path of the directory you want to be created to contain the
245  * contents of the unarchived config.
246  * \throw Exception If the archive is not found or there is a problem extracting it.
247  */
248 extern OCIOEXPORT void ExtractOCIOZArchive(
249  const char * archivePath,
250  const char * destinationDir
251 );
252 
253 /**
254  * \brief
255  * A config defines all the color spaces to be available at runtime.
256  *
257  * The color configuration (Config) is the main object for interacting with this library. It
258  * encapsulates all of the information necessary to use customized ColorSpaceTransform and
259  * DisplayViewTransform operations.
260  *
261  * See the \ref user-guide for more information on selecting, creating, and working with custom
262  * color configurations.
263  *
264  * For applications interested in using only one color config at a time (this is the vast majority
265  * of apps), their API would traditionally get the global configuration and use that, as opposed
266  * to creating a new one. This simplifies the use case for plugins and bindings, as it alleviates
267  * the need to pass around configuration handles.
268  *
269  * An example of an application where this would not be sufficient would be a multi-threaded image
270  * proxy server (daemon), which wished to handle multiple show configurations in a single process
271  * concurrently. This app would need to keep multiple configurations alive, and to manage them
272  * appropriately.
273  *
274  * Roughly speaking, a novice user should select a default configuration that most closely
275  * approximates the use case (animation, visual effects, etc.), and set the :envvar:`OCIO`
276  * environment variable to point at the root of that configuration.
277  *
278  * \note
279  * Initialization using environment variables is typically preferable in
280  * a multi-app ecosystem, as it allows all applications to be
281  * consistently configured.
282  *
283  * See \ref developers-usageexamples
284  */
286 {
287 public:
288 
289  //
290  // Initialization
291  //
292 
293  /**
294  * \brief Create an empty config of the current version.
295  *
296  * Note that an empty config will not pass validation since required elements will be missing.
297  * \return The Config object.
298  */
299  static ConfigRcPtr Create();
300 
301  /**
302  * \brief Create a fall-back config.
303  *
304  * This may be useful to allow client apps to launch in cases when the
305  * supplied config path is not loadable.
306  * \return The Config object.
307  */
308  static ConstConfigRcPtr CreateRaw();
309 
310  /**
311  * \brief Create a configuration using the OCIO environment variable.
312  *
313  * Also supports the OCIO URI format for Built-in configs and supports archived configs.
314  * See \ref Config::CreateFromFile.
315  *
316  * If the variable is missing or empty, returns the same result as
317  * \ref Config::CreateRaw.
318  * \return The Config object.
319  */
320  static ConstConfigRcPtr CreateFromEnv();
321 
322  /**
323  * \brief Create a configuration using a specific config file.
324  *
325  * Supports the OCIO URI format for Built-in configs.
326  * See \ref Config::CreateFromBuiltinConfig.
327  *
328  * Supports archived configs (.ocioz files).
329  *
330  * \throw Exception If the file may not be read or does not parse.
331  * \return The Config object.
332  */
333  static ConstConfigRcPtr CreateFromFile(const char * filename);
334 
335  /**
336  * \brief Create a configuration using a stream.
337  *
338  * Note that CreateFromStream does not set the working directory so the caller would need to
339  * set that separately in order to resolve FileTransforms. This function is typically only
340  * used for self-contained configs (no LUTs).
341  *
342  * Configs created from CreateFromStream can not be archived unless the working directory is
343  * set and contains any necessary LUT files.
344  *
345  * \param istream Stream to the config.
346  * \throw Exception If the stream does not parse.
347  * \return The Config object.
348  */
349  static ConstConfigRcPtr CreateFromStream(std::istream & istream);
350 
351  /**
352  * \brief Create a config from the supplied ConfigIOProxy object. This allows the calling
353  * program to directly provide the config and associated LUTs rather than reading them from
354  * the standard file system.
355  *
356  * See the \ref ConfigIOProxy class documentation for more info.
357  *
358  * \param ciop ConfigIOProxy object providing access to the config's files.
359  * \throw Exception If the config may not be read from the proxy, or does not parse.
360  * \return The Config object.
361  */
362  static ConstConfigRcPtr CreateFromConfigIOProxy(ConfigIOProxyRcPtr ciop);
363 
364  /**
365  * \brief Create a configuration using an OCIO built-in config.
366  *
367  * \param configName Built-in config name (with or without the "ocio://" URI prefix).
368  *
369  * Also supports the following OCIO URI format for Built-in configs:
370  * "ocio://default" - Default Built-in config.
371  * "ocio://cg-config-latest" - Latest Built-in CG config.
372  * "ocio://studio-config-latest" - Latest Built-in Studio config.
373  * "ocio://<CONFIG NAME>" - A specific Built-in config.
374  *
375  * The available configNames are:
376  *
377  * ACES Studio config, contains a more complete collection of color spaces and displays:
378  * "studio-config-v1.0.0_aces-v1.3_ocio-v2.1"
379  * "studio-config-v2.1.0_aces-v1.3_ocio-v2.3"
380  * "studio-config-v2.2.0_aces-v1.3_ocio-v2.4"
381  * "studio-config-v4.0.0_aces-v2.0_ocio-v2.5"
382  *
383  * ACES CG config, basic color spaces for computer graphics apps:
384  * "cg-config-v1.0.0_aces-v1.3_ocio-v2.1"
385  * "cg-config-v2.1.0_aces-v1.3_ocio-v2.3"
386  * "cg-config-v2.2.0_aces-v1.3_ocio-v2.4"
387  * "cg-config-v4.0.0_aces-v2.0_ocio-v2.5"
388  *
389  * More information is available at:
390  * %https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES
391  *
392  * Information about the available configs is available from the \ref BuiltinConfigRegistry.
393  *
394  * \throw Exception If the configName is not recognized.
395  * \return One of the configs built into the OCIO library.
396  */
397  static ConstConfigRcPtr CreateFromBuiltinConfig(const char * configName);
398 
399  ConfigRcPtr createEditableCopy() const;
400 
401  /// Get the configuration major version.
402  unsigned int getMajorVersion() const;
403 
404  /**
405  * Set the configuration major version.
406  *
407  * Throws if it is not supported. Resets minor to the most recent minor for the given major.
408  */
409  void setMajorVersion(unsigned int major);
410 
411  /// Get the configuration minor version.
412  unsigned int getMinorVersion() const;
413 
414  /// Set the configuration minor version. Throws if it is not supported for the current major.
415  void setMinorVersion(unsigned int minor);
416 
417  /// Set the configuration major and minor versions. Throws if version is not supported.
418  void setVersion(unsigned int major, unsigned int minor);
419 
420  /// Allows an older config to be serialized as the current version.
421  void upgradeToLatestVersion() noexcept;
422 
423  /**
424  * \brief Performs a thorough validation for the most common user errors.
425  *
426  * This will throw an exception if the config is malformed. The most
427  * common error occurs when references are made to colorspaces that do not
428  * exist.
429  */
430  void validate() const;
431 
432  /**
433  * \brief Get/set a name string for the config.
434  *
435  * The name string may be used to communicate config update details or similar information
436  * to workflows external to OCIO in cases where the config path/filename itself does not
437  * provide adequate information.
438  */
439  const char * getName() const noexcept;
440  void setName(const char * name) noexcept;
441 
442  /**
443  * \brief Get the family separator
444  *
445  * A single character used to separate the family string into tokens for use in hierarchical
446  * menus. Defaults to '/'.
447  */
448  char getFamilySeparator() const;
449  /// Get the default family separator i.e. '/' .
450  static char GetDefaultFamilySeparator() noexcept;
451  /**
452  * \brief Set the family separator
453  *
454  * Succeeds if the characters is null or a valid character from the ASCII table i.e. from
455  * value 32 (i.e. space) to 126 (i.e. '~'); otherwise, it throws an exception.
456  */
457  void setFamilySeparator(char separator);
458 
459  const char * getDescription() const;
460  void setDescription(const char * description);
461 
462  /**
463  * \brief Returns the string representation of the Config in YAML text form.
464  *
465  * This is typically stored on disk in a file with the extension .ocio.
466  * NB: This does not validate the config. Applications should validate before serializing.
467  */
468  void serialize(std::ostream & os) const;
469 
470  /**
471  * This will produce a hash of the all colorspace definitions, etc. All external references,
472  * such as files used in FileTransforms, etc., will be incorporated into the cacheID. While
473  * the contents of the files are not read, the file system is queried for relevant information
474  * (mtime, inode) so that the config's cacheID will change when the underlying luts are updated.
475  *
476  * If a context is not provided, the current Context will be used.
477  *
478  * If a null context is provided, file references will not be taken into
479  * account (this is essentially a hash of Config::serialize).
480  */
481  const char * getCacheID() const;
482  const char * getCacheID(const ConstContextRcPtr & context) const;
483 
484  //
485  // Resources
486  //
487 
488  ConstContextRcPtr getCurrentContext() const;
489 
490  /// Add (or update) an environment variable with a default value.
491  /// But it removes it if the default value is null.
492  void addEnvironmentVar(const char * name, const char * defaultValue);
493  int getNumEnvironmentVars() const;
494  const char * getEnvironmentVarNameByIndex(int index) const;
495  const char * getEnvironmentVarDefault(const char * name) const;
496  void clearEnvironmentVars();
497 
498  /**
499  * \brief The EnvironmentMode controls the behavior of loadEnvironment.
500  * * ENV_ENVIRONMENT_LOAD_PREDEFINED - Only update vars already added to the Context.
501  * * ENV_ENVIRONMENT_LOAD_ALL - Load all env. vars into the Context.
502  *
503  * \note Loading ALL the env. vars may reduce performance and reduce cache efficiency.
504  *
505  * Client programs generally will not use these methods because the EnvironmentMode is
506  * set automatically when a Config is loaded. If the Config has an "environment"
507  * section, the mode is set to LOAD_PREDEFINED, and otherwise set to LOAD_ALL.
508  */
509  void setEnvironmentMode(EnvironmentMode mode) noexcept;
510  EnvironmentMode getEnvironmentMode() const noexcept;
511  /// Initialize the environment/context variables in the Config's Context.
512  void loadEnvironment() noexcept;
513 
514  const char * getSearchPath() const;
515  /**
516  * \brief Set all search paths as a concatenated string, use ':' to separate the paths.
517  *
518  * See \ref addSearchPath for a more robust and platform-agnostic method of
519  * setting the search paths.
520  */
521  void setSearchPath(const char * path);
522 
523  int getNumSearchPaths() const;
524  /**
525  * Get a search path from the list.
526  *
527  * The paths are in the order they will be searched (that is, highest to
528  * lowest priority).
529  */
530  const char * getSearchPath(int index) const;
531  void clearSearchPaths();
532  /**
533  * \brief Add a single search path to the end of the list.
534  *
535  * Paths may be either absolute or relative. Relative paths are
536  * relative to the working directory. Forward slashes will be
537  * normalized to reverse for Windows. Environment (context) variables
538  * may be used in paths.
539  */
540  void addSearchPath(const char * path);
541 
542  const char * getWorkingDir() const;
543  /**
544  * \brief
545  *
546  * The working directory defaults to the location of the
547  * config file. It is used to convert any relative paths to absolute.
548  * If no search paths have been set, the working directory will be used
549  * as the fallback search path. No environment (context) variables may
550  * be used in the working directory.
551  */
552  void setWorkingDir(const char * dirname);
553 
554  //
555  // ColorSpaces
556  //
557 
558  /**
559  * \brief Get all active color spaces having a specific category
560  * in the order they appear in the config file.
561  *
562  * \note
563  * If the category is null or empty, the method returns
564  * all the active color spaces like \ref Config::getNumColorSpaces
565  * and \ref Config::getColorSpaceNameByIndex do.
566  *
567  * \note
568  * It's worth noticing that the method returns a copy of the
569  * selected color spaces decoupling the result from the config.
570  * Hence, any changes on the config do not affect the existing
571  * color space sets, and vice-versa.
572  */
573  ColorSpaceSetRcPtr getColorSpaces(const char * category) const;
574 
575  /**
576  * \brief Work on the color spaces selected by the reference color space type
577  * and visibility.
578  */
579  int getNumColorSpaces(SearchReferenceSpaceType searchReferenceType,
580  ColorSpaceVisibility visibility) const;
581 
582  /**
583  * \brief Work on the color spaces selected by the reference color space
584  * type and visibility (active or inactive).
585  *
586  * Return empty for invalid index.
587  */
588  const char * getColorSpaceNameByIndex(SearchReferenceSpaceType searchReferenceType,
589  ColorSpaceVisibility visibility, int index) const;
590 
591  /**
592  * \brief Work on the active color spaces only.
593  *
594  * \note
595  * Only works from the list of active color spaces.
596  */
597  int getNumColorSpaces() const;
598 
599  /**
600  * Work on the active color spaces only and return null for invalid index.
601  *
602  * \note
603  * Only works from the list of active color spaces.
604  */
605  const char * getColorSpaceNameByIndex(int index) const;
606 
607  /**
608  * \brief Get an index from the active color spaces only
609  * and return -1 if the name is not found.
610  *
611  * \note
612  * The fcn accepts either a color space name, role name, or alias.
613  * (Color space names take precedence over roles.)
614  */
615  int getIndexForColorSpace(const char * name) const;
616 
617  /**
618  * \brief Get the color space from all the color spaces
619  * (i.e. active and inactive) and return null if the name is not found.
620  *
621  * \note
622  * The fcn accepts either a color space name, role name, or alias.
623  * (Color space names take precedence over roles.)
624  */
625  ConstColorSpaceRcPtr getColorSpace(const char * name) const;
626 
627  /**
628  * Accepts an alias, role name, named transform name, or color space name and returns the
629  * color space name or the named transform name.
630  */
631  const char * getCanonicalName(const char * name) const;
632 
633  /**
634  * \brief Add a color space to the configuration.
635  *
636  * \note
637  * If another color space is already present with the same name,
638  * this will overwrite it. This stores a copy of the specified
639  * color space.
640  * \note
641  * Adding a color space to a \ref Config does not affect any
642  * \ref ColorSpaceSet sets that have already been created.
643  */
644  void addColorSpace(const ConstColorSpaceRcPtr & cs);
645 
646  /**
647  * \brief Remove a color space from the configuration.
648  *
649  * \note
650  * It does not throw an exception. Name must be the canonical name. If a role name or
651  * alias is provided or if the name is not in the config, nothing is done.
652  * \note
653  * Removing a color space from a \ref Config does not affect any
654  * \ref ColorSpaceSet sets that have already been created.
655  */
656  void removeColorSpace(const char * name);
657 
658  /**
659  * Return true if the color space is used by a transform, a role, or a look.
660  *
661  * \note
662  * Name must be the canonical name.
663  */
664  bool isColorSpaceUsed(const char * name) const noexcept;
665 
666  /**
667  * \brief Remove all the color spaces from the configuration.
668  *
669  * \note
670  * Removing color spaces from a \ref Config does not affect
671  * any \ref ColorSpaceSet sets that have already been created.
672  */
673  void clearColorSpaces();
674 
675  /**
676  * \brief Set/get a list of inactive color space or named transform names.
677  *
678  * Notes:
679  * * List can contain color space and/or named transform names.
680  * * The inactive spaces are color spaces that should not appear in application menus.
681  * * These color spaces will still work in Config::getProcessor calls.
682  * * The argument is a comma-delimited string. A null or empty string empties the list.
683  * * The environment variable OCIO_INACTIVE_COLORSPACES may also be used to set the
684  * inactive color space list.
685  * * The env. var. takes precedence over the inactive_colorspaces list in the config file.
686  * * Setting the list via the API takes precedence over either the env. var. or the
687  * config file list.
688  */
689  void setInactiveColorSpaces(const char * inactiveColorSpaces);
690  const char * getInactiveColorSpaces() const;
691 
692  /// Return true if the color space name is present in the inactive_colorspaces list.
693  bool isInactiveColorSpace(const char * colorspace) const noexcept;
694 
695  /**
696  * \brief Return true if the specified color space is linear.
697  *
698  * The determination of linearity is made with respect to one of the two reference spaces
699  * (i.e., either the scene-referred one or the display-referred one). If the reference space
700  * type of the color space is the opposite of the requested reference space type, false is
701  * returned immediately rather than trying to invoke the default view transform to convert
702  * between the reference spaces.
703  *
704  * Note: This function relies on heuristics that may sometimes give an incorrect result.
705  * For example, if the encoding attribute is not set appropriately or the sampled values fail
706  * to detect non-linearity.
707  *
708  * The algorithm proceeds as follows:
709  * -- If the color space isdata attribute is true, return false.
710  * -- If the reference space type of the color space differs from the requested reference
711  * space type, return false.
712  * -- If the color space's encoding attribute is present, return true if it matches the
713  * expected reference space type (i.e., "scene-linear" for REFERENCE_SPACE_SCENE or
714  * "display-linear" for REFERENCE_SPACE_DISPLAY) and false otherwise.
715  * -- If the color space has no to_reference or from_reference transform, return true.
716  * -- Evaluate several points through the color space's transform and check if the output only
717  * differs by a scale factor (which may be different per channel, e.g. allowing an arbitrary
718  * matrix transform, with no offset).
719  *
720  * Note that the encoding test happens before the sampled value test to give config authors
721  * ultimate control over the linearity determination. For example, they could set the encoding
722  * attribute to indicate linearity if they want to ignore some areas of non-linearity
723  * (e.g., at extreme values). Or they could set it to indicate that a color space should not
724  * be considered linear, even if it is, in a mathematical sense.
725  *
726  * \param colorSpace Color space to evaluate.
727  * \param referenceSpaceType Evaluate linearity with respect to the specified reference space
728  * (either scene-referred or display-referred).
729  */
730  bool isColorSpaceLinear(const char * colorSpace, ReferenceSpaceType referenceSpaceType) const;
731 
732  /**
733  * \brief Find the name of the color space in the source config that is the same as
734  * a color space in the default built-in config. For example, setting the
735  * builtinColorSpaceName to "sRGB - Texture" (a color space name from that
736  * config), would return the name for the corresponding sRGB texture space in
737  * the current config (or empty if it was not found). Note that this method
738  * relies on heuristics which may evolve over time and which may not work on
739  * all configs.
740  *
741  * The method only looks at active color spaces. If the interchange roles are
742  * missing and heuristics are used, only scene-referred color spaces are searched.
743  *
744  * \param srcConfig The config to search for the desired color space.
745  * \param builtinConfig The built-in config to use. See \ref Config::CreateFromBuiltinConfig.
746  * \param builtinColorSpaceName Color space name in the built-in default config.
747  * \return Matching color space name from the source config. Empty if not found.
748  *
749  * \throw Exception if an interchange space cannot be found or the equivalent space cannot be found.
750  */
751  static const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
752  const ConstConfigRcPtr & builtinConfig,
753  const char * builtinColorSpaceName);
754 
755  /**
756  * \brief Identify the two names of a common color space that exists in both the
757  * given config and the provided built-in config that may be used for converting
758  * color spaces between the two configs. If both configs have the interchange
759  * role set, than the color spaces set to that role will be returned. Otherwise,
760  * heuristics will be used to try and identify a known color space in the source
761  * config. These are the same heuristics that are used for other methods such as
762  * identifyBuiltinColorSpace and GetProcessorTo/FromBuiltinColorSpace.
763  *
764  * Using this method in connection with GetProcessorFromConfigs is more efficient
765  * if you need to call GetProcessorTo/FromBuiltinColorSpace multiple times since it
766  * is only necessary to run the heuristics once (to identify the interchange spaces).
767  *
768  * The srcColorSpaceName and builtinColorSpace name are used to decide which
769  * interchange role to use (scene- or display-referred). However, they are not
770  * used if the interchange roles are not present and the heuristics are used.
771  * It is actually only the ReferenceSpaceType of the color spaces that are used,
772  * so it is not necessary to call this function multiple times if all the spaces
773  * are of the same type. (These are the same arguments that would also be set if
774  * you were instead calling GetProcessorTo/FromBuiltinColorSpace.)
775  *
776  * \param[out] srcInterchangeName Color space name from the source config.
777  * \param[out] builtinInterchangeName Corresponding color space name from the built-in config.
778  * \param srcConfig The config to search for the desired color space.
779  * \param srcColorSpaceName Color space name in the given config to convert to/from.
780  * \param builtinConfig The built-in config to use. See \ref Config::CreateFromBuiltinConfig.
781  * \param builtinColorSpaceName Color space name in the default built-in config.
782  *
783  * \throw Exception if either the srcInterchange or builtinInterchange cannot be identified.
784  */
785  static void IdentifyInterchangeSpace(const char ** srcInterchangeName,
786  const char ** builtinInterchangeName,
787  const ConstConfigRcPtr & srcConfig,
788  const char * srcColorSpaceName,
789  const ConstConfigRcPtr & builtinConfig,
790  const char * builtinColorSpaceName);
791 
792  /**
793  * Methods related to Roles.
794  *
795  * A role allows a config author to indicate that a given color space should be used
796  * for a particular purpose.
797  *
798  * Role names may be passed to most functions that accept color space names, such as
799  * getColorSpace. So for example, you may find the name of the color space assigned
800  * to the scene_linear role by getting the color space object for "scene_linear" and
801  * then calling getName on the color space object.
802  */
803 
804  /**
805  * \brief
806  *
807  * \note
808  * Setting the ``colorSpaceName`` name to a null string unsets it.
809  */
810  void setRole(const char * role, const char * colorSpaceName);
811  int getNumRoles() const;
812  /// Return true if the role has been defined.
813  bool hasRole(const char * role) const;
814  /**
815  * \brief Get the role name at index, this will return values
816  * like 'scene_linear', 'compositing_log'.
817  *
818  * Return empty string if index is out of range.
819  */
820  const char * getRoleName(int index) const;
821  /**
822  * \brief Get the role color space at index.
823  *
824  * Return empty string if index is out of range.
825  */
826  const char * getRoleColorSpace(int index) const;
827  /**
828  * \brief Get the color space name used for the specified role.
829  *
830  * Return an empty string if the role is not present
831  */
832  const char * getRoleColorSpace(const char * roleName) const noexcept;
833 
834  /**
835  * Methods related to displays and views.
836  *
837  * The following methods only manipulate active displays and views. Active
838  * displays and views are defined from an env. variable or from the config file.
839  *
840  * Looks is a potentially comma (or colon) delimited list of lookNames,
841  * Where +/- prefixes are optionally allowed to denote forward/inverse
842  * look specification. (And forward is assumed in the absence of either)
843 
844  * Add shared view (or replace existing one with same name).
845  * Shared views are defined at config level and can be referenced by several
846  * displays. Either provide a view transform and a display color space or
847  * just a color space (and a null view transform). Looks, rule and description
848  * are optional, they can be null or empty.
849  *
850  * Shared views using a view transform may use the token <USE_DISPLAY_NAME>
851  * for the color space (see :c:var:`OCIO_VIEW_USE_DISPLAY_NAME`). In that
852  * case, when the view is referenced in a display, the display color space
853  * that is used will be the one matching the display name. In other words,
854  * the view will be customized based on the display it is used in.
855  * \ref Config::validate will throw if the config does not contain
856  * the matching display color space.
857  */
858 
859  /// Check if a view within a given display is referencing one of the config's shared views.
860  bool isViewShared(const char * dispName, const char * viewName) const;
861 
862  /// Will throw if view or colorSpaceName are null or empty.
863  void addSharedView(const char * view, const char * viewTransformName,
864  const char * colorSpaceName, const char * looks,
865  const char * ruleName, const char * description);
866  /// Remove a shared view. Will throw if the view does not exist.
867  void removeSharedView(const char * view);
868 
869  /// Clear all shared views. This will throw if any displays are still using the shared views.
870  void clearSharedViews();
871 
872  const char * getDefaultDisplay() const;
873  int getNumDisplays() const;
874  /// Will return "" if the index is invalid.
875  const char * getDisplay(int index) const;
876 
877  const char * getDefaultView(const char * display) const;
878  // Get the default view for a given color space using the viewing rules.
879  // This is the preferred call to use if the color space being viewed is known.
880  const char * getDefaultView(const char * display, const char * colorspaceName) const;
881 
882  /**
883  * Return the number of active views attached to the display including the number of
884  * shared views if any. Return 0 if display does not exist.
885  */
886  int getNumViews(const char * display) const;
887  const char * getView(const char * display, int index) const;
888 
889  /**
890  * If the config has ViewingRules, get the number of active Views for this
891  * colorspace. (If there are no rules, it returns all of them.)
892  */
893  int getNumViews(const char * display, const char * colorspaceName) const;
894  const char * getView(const char * display, const char * colorspaceName, int index) const;
895 
896  /**
897  * \brief Compare views in a pair of configs.
898  *
899  * Will return false if either of the views does not exist. This will return true even
900  * if the view is display-defined in one config and a reference to a shared view in the
901  * other config (both within the same display), as long as the contents match. The
902  * description text (if any) is ignored, since it is not a functional difference.
903  *
904  * Note that the comparison is only on the strings contained in the view definition,
905  * the function does not attempt to compare that the color spaces or view transforms
906  * being referenced are identical (only that they have the same name).
907  */
908  static bool AreViewsEqual(const ConstConfigRcPtr & first,
909  const ConstConfigRcPtr & second,
910  const char * dispName,
911  const char * viewName);
912 
913  /**
914  * Returns the view_transform attribute of the (display, view) pair. View can
915  * be a shared view of the display. If display is null or empty, config shared views are used.
916  */
917  const char * getDisplayViewTransformName(const char * display, const char * view) const;
918  /**
919  * Returns the colorspace attribute of the (display, view) pair.
920  * (Note that this may be either a color space or a display color space.)
921  */
922  const char * getDisplayViewColorSpaceName(const char * display, const char * view) const;
923  /// Returns the looks attribute of a (display, view) pair.
924  const char * getDisplayViewLooks(const char * display, const char * view) const;
925  /// Returns the rule attribute of a (display, view) pair.
926  const char * getDisplayViewRule(const char * display, const char * view) const noexcept;
927  /// Returns the description attribute of a (display, view) pair.
928  const char * getDisplayViewDescription(const char * display, const char * view) const noexcept;
929 
930  /**
931  * \brief Determine if a display and view exist.
932  *
933  * This returns false if either the display or view doesn't exist. It works regardless
934  * of whether the display or view are active, and it works regardless of whether the
935  * view is display-defined or if the display has this as a shared view. It will only
936  * check config-level shared views if dispName is null. It will not check config level
937  * shared views if dispName is not null.
938  */
939  bool hasView(const char * dispName, const char * viewName) const;
940 
941  /**
942  * For the (display, view) pair, specify which color space and look to use.
943  * If a look is not desired, then just pass a null or empty string.
944  */
945  void addDisplayView(const char * display, const char * view,
946  const char * colorSpaceName, const char * looks);
947 
948  /**
949  * \brief
950  *
951  * For the (display, view) pair, specify the color space or alternatively
952  * specify the view transform and display color space. The looks, viewing rule, and
953  * description are optional. Pass a null or empty string for any optional arguments.
954  * If the view already exists, it is replaced.
955  *
956  * Will throw if:
957  * * Display, view or colorSpace are null or empty.
958  * * Display already has a shared view with the same name.
959  */
960  void addDisplayView(const char * display, const char * view, const char * viewTransformName,
961  const char * colorSpaceName, const char * looks,
962  const char * ruleName, const char * description);
963 
964  /**
965  * \brief Add a (reference to a) shared view to a display.
966  *
967  * The shared view must be part of the config. See \ref Config::addSharedView
968  *
969  * This will throw if:
970  * * Display or view are null or empty.
971  * * Display already has a view (shared or not) with the same name.
972  */
973  void addDisplaySharedView(const char * display, const char * sharedView);
974 
975  /**
976  * \brief Remove the view and the display if no more views.
977  *
978  * It does not remove the associated color space. If the view name is a
979  * shared view, it only removes the reference to the view from the display
980  * but the shared view, remains in the config.
981  *
982  * Will throw if the view does not exist.
983  */
984  void removeDisplayView(const char * display, const char * view);
985  /// Clear all the displays.
986  void clearDisplays();
987 
988  /**
989  * Methods related to the Virtual Display.
990  *
991  * ... (See descriptions for the non-virtual methods above.)
992  *
993  * The virtual display is the way to incorporate the ICC monitor profile for a user's display
994  * into OCIO. The views that are defined for the virtual display are the views that are used to
995  * create a new display for an ICC profile. They serve as a kind of template that lets OCIO
996  * know how to build the new display.
997  *
998  * Typically the views will define a View Transform and set the colorSpaceName to
999  * "<USE_DISPLAY_NAME>" so that it will use the display color space with the same name as the
1000  * display, in this case corresponding to the ICC profile.
1001  *
1002  */
1003 
1004  /**
1005  * \brief Determine if a virtual view exists.
1006  *
1007  * This returns false if the virtual view doesn't exist. It works regardless of
1008  * whether the virtual view is active, and it works regardless of whether the virtual
1009  * view is display-defined or if the display has this as a shared virtual view.
1010  */
1011  bool hasVirtualView(const char * viewName) const;
1012 
1013  /// Check if a given virtual view is referencing one of the config's shared views.
1014  bool isVirtualViewShared(const char * viewName) const;
1015 
1016  void addVirtualDisplayView(const char * view,
1017  const char * viewTransformName,
1018  const char * colorSpaceName,
1019  const char * looks,
1020  const char * ruleName,
1021  const char * description);
1022 
1023  void addVirtualDisplaySharedView(const char * sharedView);
1024 
1025  /// Get the number of views associated to the virtual display.
1026  int getVirtualDisplayNumViews(ViewType type) const noexcept;
1027  /// Get the view name at a specific index.
1028  const char * getVirtualDisplayView(ViewType type, int index) const noexcept;
1029 
1030  /**
1031  * \brief Compare virtual views in a pair of configs.
1032  *
1033  * Will return false if either of the virtual views does not exist. This will return true
1034  * even if the virtual view is display-defined in one config and a reference to a shared
1035  * virtual view in the other config, as long as the contents match.
1036  *
1037  * The description text (if any) is ignored, since it is not a functional difference.
1038  *
1039  * Note that the comparison is only on the strings contained in the view definition,
1040  * the function does not attempt to compare that the color spaces or view transforms
1041  * being referenced are identical (only that they have the same name).
1042  */
1043  static bool AreVirtualViewsEqual(const ConstConfigRcPtr & first,
1044  const ConstConfigRcPtr & second,
1045  const char * viewName);
1046 
1047  const char * getVirtualDisplayViewTransformName(const char * view) const noexcept;
1048  const char * getVirtualDisplayViewColorSpaceName(const char * view) const noexcept;
1049  const char * getVirtualDisplayViewLooks(const char * view) const noexcept;
1050  const char * getVirtualDisplayViewRule(const char * view) const noexcept;
1051  const char * getVirtualDisplayViewDescription(const char * view) const noexcept;
1052 
1053  /// Remove the view from the virtual display.
1054  void removeVirtualDisplayView(const char * view) noexcept;
1055 
1056  /// Clear the virtual display.
1057  void clearVirtualDisplay() noexcept;
1058 
1059  /**
1060  * \brief Instantiate a new display from a virtual display, using the monitor name.
1061  *
1062  * This method uses the virtual display to create an actual display for the given monitorName.
1063  * The new display will receive the views from the virtual display.
1064  *
1065  * After the ICC profile is read, a display name will be created by combining the description
1066  * text from the profile with the monitorName obtained from the OS. Use the SystemMonitors class
1067  * to obtain the list of monitorName strings for the displays connected to the computer.
1068  *
1069  * A new display color space will also be created using the display name. It will have a
1070  * from_display_reference transform that is a FileTransform pointing to the ICC profile.
1071  *
1072  * Any instantiated display color spaces for a virtual display are intended to be temporary
1073  * (i.e. last as long as the current session). By default, they are not saved when writing a
1074  * config file. If there is a need to make it a permanent color space, it may be desirable to
1075  * copy the ICC profile somewhere under the config search_path.
1076  *
1077  * Will throw if the config does not have a virtual display or if the monitorName does not exist.
1078  *
1079  * If there is already a display or a display color space with the name monitorName, it will be
1080  * replaced/updated.
1081  *
1082  * Returns the index of the display.
1083  */
1084  int instantiateDisplayFromMonitorName(const char * monitorName);
1085 
1086  /**
1087  * \brief Instantiate a new display from a virtual display, using an ICC profile.
1088  *
1089  * On platforms such as Linux, where the SystemMonitors class is not able to obtain a list of
1090  * ICC profiles from the OS, this method may be used to manually specify a path to an ICC profile.
1091  *
1092  * Will throw if the virtual display definition is missing from the config.
1093  *
1094  * Returns the index of the display.
1095  */
1096  int instantiateDisplayFromICCProfile(const char * ICCProfileFilepath);
1097 
1098  /**
1099  * \brief
1100  *
1101  * The Active Displays list allows end users, config authors, and client apps to filter and
1102  * reorder of the list of displays available in a user-interface. The list may be left empty
1103  * to indicate all displays are active.
1104  *
1105  * The first active display is the config's Default Display.
1106  *
1107  * If the active list would remove all displays from a config, it is ignored (though the
1108  * config won't validate).
1109  *
1110  * When serialized in the config, commas are used as separators. However, if a display name
1111  * contains a comma, the name will be enclosed in quotes so its comma is not a separator.
1112  *
1113  * The OCIO_ACTIVE_DISPLAYS environment variable will override the active list specified in
1114  * the config file as well as any modifications made by the client app. These functions
1115  * only get and set what is in the config object and do not take into account the override
1116  * and thus may not represent the actual user experience.
1117  */
1118  /// Set all active displays at once as a comma or colon delimited string. This replaces any
1119  /// previous contents of the list.
1120  void setActiveDisplays(const char * displays);
1121  /// Get a string with all active displays (as it would appear in a config file).
1122  /// Commas are always used as the separator.
1123  const char * getActiveDisplays() const;
1124  /// Get the number of active displays.
1125  int getNumActiveDisplays() const;
1126  /// Get a single active display, by index. Returns nullptr if the index is out of range.
1127  const char * getActiveDisplay(int index) const;
1128  /// Add a single active display to the end of the list. If the display is already present,
1129  /// no action is taken.
1130  void addActiveDisplay(const char * display);
1131  /// Remove a single display. Will throw if the display is not present.
1132  void removeActiveDisplay(const char * display);
1133  /// Clear the active displays list.
1134  void clearActiveDisplays();
1135 
1136  /**
1137  * \brief
1138  *
1139  * The Active Views list allows end users, config authors, and client apps to filter and
1140  * reorder of the list of views available in a user-interface. The list may be left empty
1141  * to indicate all views are active.
1142  *
1143  * The first active view for a display is its Default View.
1144  *
1145  * If the active list would remove all views from a display, the list is ignored for that
1146  * display and all views are shown for it.
1147  *
1148  * When serialized in the config, commas are used as separators. However, if a view name
1149  * contains a comma, the name will be enclosed in quotes so its comma is not a separator.
1150  *
1151  * The OCIO_ACTIVE_VIEWS environment variable will override the active list specified in
1152  * the config file as well as any modifications made by the client app. These functions
1153  * only get and set what is in the config object and do not take into account the override
1154  * and thus may not represent the actual user experience.
1155  */
1156  /// Set all active views at once as a comma or colon delimited string. This replaces any
1157  /// previous contents of the list.
1158  void setActiveViews(const char * views);
1159  /// Get a string with all active views (as it would appear in a config file).
1160  /// Commas are always used as the separator.
1161  const char * getActiveViews() const;
1162  /// Get the number of active views.
1163  int getNumActiveViews() const;
1164  /// Get a single active view, by index. Returns nullptr if the index is out of range.
1165  const char * getActiveView(int index) const;
1166  /// Add a single active view to the end of the list. If the view is already present,
1167  /// no action is taken.
1168  void addActiveView(const char * view);
1169  /// Remove a single view. Will throw if the view is not present.
1170  void removeActiveView(const char * view);
1171  /// Clear the active views list.
1172  void clearActiveViews();
1173 
1174  /// Get all displays in the config, ignoring the active_displays list.
1175  int getNumDisplaysAll() const noexcept;
1176  const char * getDisplayAll(int index) const noexcept;
1177  int getDisplayAllByName(const char *) const noexcept;
1178  /**
1179  * Will be true for a display that was instantiated from a virtual display. These displays are
1180  * intended to be temporary (i.e. for the current session) and are not saved to a config file.
1181  */
1182  bool isDisplayTemporary(int index) const noexcept;
1183  /**
1184  * Allows setting the flag that controls whether a display is temporary. This may be helpful,
1185  * for example, to share a config with a temporary instantiated display with an OFX plug-in.
1186  */
1187  void setDisplayTemporary(int index, bool isTemporary) noexcept;
1188 
1189  /**
1190  * Get either the shared or display-defined views for a display. The
1191  * active_views list is ignored. Passing a null or empty display (with type=VIEW_SHARED)
1192  * returns the contents of the shared_views section of the config. Return 0 if display
1193  * does not exist.
1194  */
1195  int getNumViews(ViewType type, const char * display) const;
1196  const char * getView(ViewType type, const char * display, int index) const;
1197 
1198  //
1199  // Viewing Rules
1200  //
1201 
1202  /// Get read-only version of the viewing rules.
1203  ConstViewingRulesRcPtr getViewingRules() const noexcept;
1204 
1205  /**
1206  * \brief Set viewing rules.
1207  *
1208  * \note
1209  * The argument is cloned.
1210  */
1211  void setViewingRules(ConstViewingRulesRcPtr viewingRules);
1212 
1213  //
1214  // Luma
1215  // ^^^^
1216 
1217  /**
1218  * \brief Get the default coefficients for computing luma.
1219  *
1220  * \note
1221  * There is no "1 size fits all" set of luma coefficients. (The
1222  * values are typically different for each colorspace, and the
1223  * application of them may be nonsensical depending on the
1224  * intensity coding anyways). Thus, the 'right' answer is to make
1225  * these functions on the ColorSpace class. However, it's
1226  * often useful to have a config-wide default so here it is. We will
1227  * add the colorspace specific luma call if/when another client is
1228  * interesting in using it.
1229  */
1230  void getDefaultLumaCoefs(double * rgb) const;
1231  /// These should be normalized (sum to 1.0 exactly).
1232  void setDefaultLumaCoefs(const double * rgb);
1233 
1234 
1235  //
1236  // Look
1237  //
1238 
1239  // Manager per-shot look settings.
1240 
1241  ConstLookRcPtr getLook(const char * name) const;
1242 
1243  int getNumLooks() const;
1244 
1245  const char * getLookNameByIndex(int index) const;
1246 
1247  void addLook(const ConstLookRcPtr & look);
1248 
1249  void clearLooks();
1250 
1251 
1252  //
1253  // View Transforms
1254  //
1255 
1256  // ViewTransform objects are used with the display reference space.
1257 
1258  int getNumViewTransforms() const noexcept;
1259 
1260  ConstViewTransformRcPtr getViewTransform(const char * name) const noexcept;
1261 
1262  const char * getViewTransformNameByIndex(int i) const noexcept;
1263 
1264  void addViewTransform(const ConstViewTransformRcPtr & viewTransform);
1265 
1266  /**
1267  * \brief
1268  *
1269  * This view transform is the one that will be used by default if a ColorSpaceTransform is
1270  * needed between a scene-referred and display-referred color space. The config author may
1271  * specify a transform to use via the default_view_transform entry in the config. If that is
1272  * not present, or does not return a valid view transform from the scene-referred connection
1273  * space, the fall-back is to use the first valid view transform in the config. Returns a
1274  * null ConstTransformRcPtr if there isn't one.
1275  */
1276  ConstViewTransformRcPtr getDefaultSceneToDisplayViewTransform() const;
1277 
1278  /**
1279  * Get or set the default_view_transform string from the config.
1280  *
1281  * Note that if this is not the name of a valid view transform from the scene-referred
1282  * connection space, it will be ignored.
1283  */
1284  const char * getDefaultViewTransformName() const noexcept;
1285  void setDefaultViewTransformName(const char * defaultName) noexcept;
1286 
1287 
1288  void clearViewTransforms();
1289 
1290  /**
1291  * Methods related to named transforms.
1292  */
1293 
1294  /**
1295  * \brief Work on the named transforms selected by visibility.
1296  */
1297  int getNumNamedTransforms(NamedTransformVisibility visibility) const noexcept;
1298 
1299  /**
1300  * \brief Work on the named transforms selected by visibility (active or inactive).
1301  *
1302  * Return an empty string for invalid index.
1303  */
1304  const char * getNamedTransformNameByIndex(NamedTransformVisibility visibility,
1305  int index) const noexcept;
1306 
1307  /// Work on the active named transforms only.
1308  int getNumNamedTransforms() const noexcept;
1309 
1310  /// Work on the active named transforms only and return an empty string for invalid index.
1311  const char * getNamedTransformNameByIndex(int index) const noexcept;
1312 
1313  /// Get an index from the active named transforms only and return -1 if the name is not found.
1314  int getIndexForNamedTransform(const char * name) const noexcept;
1315 
1316  /**
1317  * \brief Get the named transform from all the named transforms (i.e. active and inactive) and
1318  * return null if the name is not found.
1319  */
1320  ConstNamedTransformRcPtr getNamedTransform(const char * name) const noexcept;
1321 
1322  /**
1323  * \brief Add or replace named transform.
1324  *
1325  * \note
1326  * Throws if namedTransform is null, name is missing, or no transform is set. Also throws
1327  * if the name or the aliases conflict with names or aliases already in the config.
1328  */
1329  void addNamedTransform(const ConstNamedTransformRcPtr & namedTransform);
1330 
1331  /**
1332  * \brief Remove a named transform. (Does nothing if name is not found.)
1333  */
1334  void removeNamedTransform(const char * name);
1335 
1336  /// Clear all named transforms.
1337  void clearNamedTransforms();
1338 
1339  //
1340  // File Rules
1341  //
1342 
1343  /// Get read-only version of the file rules.
1344  ConstFileRulesRcPtr getFileRules() const noexcept;
1345 
1346  /**
1347  * \brief Set file rules.
1348  *
1349  * \note
1350  * The argument is cloned.
1351  */
1352  void setFileRules(ConstFileRulesRcPtr fileRules);
1353 
1354  /// Get the color space of the first rule that matched filePath. (For v1 configs, this is
1355  /// equivalent to calling parseColorSpaceFromString with strictparsing set to false.)
1356  const char * getColorSpaceFromFilepath(const char * filePath) const;
1357 
1358  /**
1359  * Most applications will use the preceding method, but this method may be
1360  * used for applications that want to know which was the highest priority rule to match
1361  * filePath. \ref FileRules::getNumCustomKeys and custom keys methods
1362  * may then be used to get additional information about the matching rule.
1363  */
1364  const char * getColorSpaceFromFilepath(const char * filePath, size_t & ruleIndex) const;
1365 
1366  /**
1367  * \brief
1368  *
1369  * Returns true if the only rule matched by filePath is the default rule.
1370  * This is a convenience method for applications that want to require the user to manually
1371  * choose a color space when strictParsing is true and no other rules match.
1372  */
1373  bool filepathOnlyMatchesDefaultRule(const char * filePath) const;
1374 
1375  /**
1376  * Given the specified string, get the longest, right-most, colorspace substring that
1377  * appears.
1378  *
1379  * * If strict parsing is enabled, and no color space is found, return
1380  * an empty string.
1381  * * If strict parsing is disabled, return ROLE_DEFAULT (if defined).
1382  * * If the default role is not defined, return an empty string.
1383  */
1384  OCIO_DEPRECATED("This was marked as deprecated starting in v2.0, please use Config::getColorSpaceFromFilepath().")
1385  const char * parseColorSpaceFromString(const char * str) const;
1386 
1387  bool isStrictParsingEnabled() const;
1388  void setStrictParsingEnabled(bool enabled);
1389 
1390  //
1391  // Processors
1392  //
1393 
1394  // Create a Processor to assemble a transformation between two
1395  // color spaces. It may then be used to create a CPUProcessor
1396  // or GPUProcessor to process/convert pixels.
1397 
1398  /// Get the processor to apply a ColorSpaceTransform from a source to a destination
1399  /// color space.
1400  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1401  const ConstColorSpaceRcPtr & srcColorSpace,
1402  const ConstColorSpaceRcPtr & dstColorSpace) const;
1403  ConstProcessorRcPtr getProcessor(const ConstColorSpaceRcPtr & srcColorSpace,
1404  const ConstColorSpaceRcPtr & dstColorSpace) const;
1405 
1406  /**
1407  * \brief
1408  *
1409  * \note
1410  * Names can be colorspace name, role name, or a combination of both.
1411  */
1412  ConstProcessorRcPtr getProcessor(const char * srcColorSpaceName,
1413  const char * dstColorSpaceName) const;
1414  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1415  const char * srcColorSpaceName,
1416  const char * dstColorSpaceName) const;
1417 
1418  /// Get the processor to apply a DisplayViewTransform for a display and view. Refer to the
1419  /// Display/View Registration section above for more info on the display and view arguments.
1420  ConstProcessorRcPtr getProcessor(const char * srcColorSpaceName,
1421  const char * display,
1422  const char * view,
1424 
1425  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1426  const char * srcColorSpaceName,
1427  const char * display,
1428  const char * view,
1429  TransformDirection direction) const;
1430 
1431  /// Get the processor to apply a NamedTransform in the specified direction.
1432  ConstProcessorRcPtr getProcessor(const ConstNamedTransformRcPtr & namedTransform,
1433  TransformDirection direction) const;
1434  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1435  const ConstNamedTransformRcPtr & namedTransform,
1436  TransformDirection direction) const;
1437 
1438  ConstProcessorRcPtr getProcessor(const char * namedTransformName,
1439  TransformDirection direction) const;
1440  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1441  const char * namedTransformName,
1442  TransformDirection direction) const;
1443 
1444  /**
1445  * \brief Get the processor for the specified transform.
1446  *
1447  * Not often needed, but will allow for the re-use of atomic OCIO
1448  * functionality (such as to apply an individual LUT file).
1449  */
1450  ConstProcessorRcPtr getProcessor(const ConstTransformRcPtr & transform) const;
1451  ConstProcessorRcPtr getProcessor(const ConstTransformRcPtr & transform,
1452  TransformDirection direction) const;
1453  ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context,
1454  const ConstTransformRcPtr & transform,
1455  TransformDirection direction) const;
1456 
1457  /**
1458  * \brief Get a Processor to or from a known external color space.
1459  *
1460  * These methods provide a way to interface color spaces in a config with known standard
1461  * external color spaces. The set of external color space are those contained in the current
1462  * default Built-in config. This includes common spaces such as "Linear Rec.709 (sRGB)",
1463  * "sRGB - Texture", "ACEScg", and "ACES2065-1".
1464  *
1465  * If the source config defines the necessary Interchange Role (typically "aces_interchange"),
1466  * then the conversion will be well-defined and equivalent to calling GetProcessorFromConfigs
1467  * with the source config and the Built-in config.
1468  *
1469  * However, if the Interchange Roles are not present, heuristics will be used to try and
1470  * identify a common color space in the source config that may be used to allow the conversion
1471  * to proceed. If the heuristics fail to find a suitable space, an exception is thrown.
1472  * The heuristics may evolve, so the results returned by this function for a given source config
1473  * and color space may change in future releases of the library. However, the Interchange Roles
1474  * are required in config versions 2.2 and higher, so it is hoped that the need for the heuristics
1475  * will decrease over time.
1476  *
1477  * \param srcConfig The user's source config.
1478  * \param srcColorSpaceName The name of the color space in the source config.
1479  * \param builtinColorSpaceName The name of the color space in the current default Built-in config.
1480  *
1481  * \throw Exception if either the src or builtin interchange space cannot be identified.
1482  */
1483  static ConstProcessorRcPtr GetProcessorToBuiltinColorSpace(ConstConfigRcPtr srcConfig,
1484  const char * srcColorSpaceName,
1485  const char * builtinColorSpaceName);
1486  /**
1487  * \brief See description of GetProcessorToBuiltinColorSpace.
1488  *
1489  * \param builtinColorSpaceName The name of the color space in the current default Built-in config.
1490  * \param srcConfig The user's source config.
1491  * \param srcColorSpaceName The name of the color space in the source config.
1492  */
1493  static ConstProcessorRcPtr GetProcessorFromBuiltinColorSpace(const char * builtinColorSpaceName,
1494  ConstConfigRcPtr srcConfig,
1495  const char * srcColorSpaceName);
1496 
1497  /**
1498  * \brief Get a processor to convert between color spaces in two separate configs.
1499  *
1500  * This relies on both configs having the aces_interchange role (when srcName
1501  * is scene-referred) or the role cie_xyz_d65_interchange (when srcName is
1502  * display-referred) defined. An exception is thrown if that is not the case.
1503  */
1504  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstConfigRcPtr & srcConfig,
1505  const char * srcColorSpaceName,
1506  const ConstConfigRcPtr & dstConfig,
1507  const char * dstColorSpaceName);
1508  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstContextRcPtr & srcContext,
1509  const ConstConfigRcPtr & srcConfig,
1510  const char * srcColorSpaceName,
1511  const ConstContextRcPtr & dstContext,
1512  const ConstConfigRcPtr & dstConfig,
1513  const char * dstColorSpaceName);
1514 
1515  /**
1516  * The srcInterchangeName and dstInterchangeName must refer to a pair of
1517  * color spaces in the two configs that are the same. A role name may also be used.
1518  *
1519  * Note: For all of the two-config GetProcessor functions, if either the source or
1520  * destination color spaces are data spaces, the entire processor will be a no-op.
1521  */
1522  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstConfigRcPtr & srcConfig,
1523  const char * srcColorSpaceName,
1524  const char * srcInterchangeName,
1525  const ConstConfigRcPtr & dstConfig,
1526  const char * dstColorSpaceName,
1527  const char * dstInterchangeName);
1528 
1529  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstContextRcPtr & srcContext,
1530  const ConstConfigRcPtr & srcConfig,
1531  const char * srcColorSpaceName,
1532  const char * srcInterchangeName,
1533  const ConstContextRcPtr & dstContext,
1534  const ConstConfigRcPtr & dstConfig,
1535  const char * dstColorSpaceName,
1536  const char * dstInterchangeName);
1537 
1538  /**
1539  * \brief Get a processor to convert from a color space to a display and view in
1540  * two separate configs.
1541  */
1542  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstConfigRcPtr & srcConfig,
1543  const char * srcColorSpaceName,
1544  const ConstConfigRcPtr & dstConfig,
1545  const char * dstDisplay,
1546  const char * dstView,
1547  TransformDirection direction);
1548 
1549  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstContextRcPtr & srcContext,
1550  const ConstConfigRcPtr & srcConfig,
1551  const char * srcColorSpaceName,
1552  const ConstContextRcPtr & dstContext,
1553  const ConstConfigRcPtr & dstConfig,
1554  const char * dstDisplay,
1555  const char * dstView,
1556  TransformDirection direction);
1557 
1558  /**
1559  * The srcInterchangeName and dstInterchangeName must refer to a pair of
1560  * color spaces in the two configs that are the same. A role name may also be used.
1561  */
1562  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstConfigRcPtr & srcConfig,
1563  const char * srcColorSpaceName,
1564  const char * srcInterchangeName,
1565  const ConstConfigRcPtr & dstConfig,
1566  const char * dstDisplay,
1567  const char * dstView,
1568  const char * dstInterchangeName,
1569  TransformDirection direction);
1570 
1571  static ConstProcessorRcPtr GetProcessorFromConfigs(const ConstContextRcPtr & srcContext,
1572  const ConstConfigRcPtr & srcConfig,
1573  const char * srcColorSpaceName,
1574  const char * srcInterchangeName,
1575  const ConstContextRcPtr & dstContext,
1576  const ConstConfigRcPtr & dstConfig,
1577  const char * dstDisplay,
1578  const char * dstView,
1579  const char * dstInterchangeName,
1580  TransformDirection direction);
1581 
1582  /// Get the Processor Cache flags.
1583  ProcessorCacheFlags getProcessorCacheFlags() const noexcept;
1584 
1585  /// Control the caching of processors in the config instance. By default, caching is on.
1586  /// The flags allow turning caching off entirely or only turning it off if dynamic
1587  /// properties are being used by the processor.
1588  void setProcessorCacheFlags(ProcessorCacheFlags flags) const noexcept;
1589 
1590  /**
1591  * \brief Clears this config's cache of Processor, CPUProcessor, and GPUProcessor instances.
1592  *
1593  * This must be done if any of the LUT files used by these Processors have been modified.
1594  * Note that setProcessorCacheFlags(PROCESSOR_CACHE_OFF) turns off caching but does not clear
1595  * any existing cache.
1596  */
1597  void clearProcessorCache() noexcept;
1598 
1599  /// Set the ConfigIOProxy object used to provision the config and LUTs from somewhere other
1600  /// than the file system. (This is set on the config's embedded Context object.)
1601  void setConfigIOProxy(ConfigIOProxyRcPtr ciop);
1602  ConfigIOProxyRcPtr getConfigIOProxy() const;
1603 
1604  /**
1605  * \brief Verify if the config is archivable.
1606  *
1607  * A config is not archivable if any of the following are true:
1608  * -- The working directory is not set
1609  * -- It contains FileTransforms with a src outside the working directory
1610  * -- The search path contains paths outside the working directory
1611  * -- The search path contains paths that start with a context variable
1612  *
1613  * Context variables are allowed but the intent is that they may only resolve to paths that
1614  * are within or below the working directory. This is because the archiving function will
1615  * only archive files that are within the working directory in order to ensure that if it is
1616  * later expanded, that it will not create any files outside this directory.
1617  *
1618  * For example, a context variable on the search path intended to contain the name of a
1619  * sub-directory under the working directory must have the form "./$DIR_NAME" rather than just
1620  * "$DIR_NAME" to be considered archivable. This is imperfect since there is no way to
1621  * prevent the context variable from creating a path outside the working dir, but it should
1622  * at least draw attention to the fact that the archive would fail if used with context vars
1623  * that try to abuse the intended functionality.
1624  *
1625  * \return bool Archivable if true.
1626  */
1627  bool isArchivable() const;
1628 
1629  /**
1630  * \brief Archive the config and its LUTs into the specified output stream.
1631  *
1632  * The config is archived by serializing the Config object into a file named "config.ocio" and
1633  * then walking through the current working directory and any sub-directories. Any files that
1634  * have an extension matching a supported LUT file format are added to the archive. Any files
1635  * that do not have an extension (or have some unsupported LUT extension, including .ocio),
1636  * will not be added to the archive. To reiterate, it is the in-memory Config object that is
1637  * archived, and not any .ocio file in the current working directory. The directory structure
1638  * relative to the working directory is preserved. No files outside the working directory are
1639  * archived so that if it is later expanded, no files will be created outside the working dir.
1640  *
1641  * The reason the archive is created using all supported LUT file extensions rather than by
1642  * trying to resolve all the FileTransforms in the Config to specific files is because of the
1643  * goal to allow context variables to continue to work.
1644  *
1645  * If a Config is created with CreateFromStream, CreateFromFile with an OCIOZ archive, or
1646  * CreateFromConfigIOProxy, it cannot be archived unless the working directory is manually set
1647  * to a directory that contains any necessary LUT files.
1648  *
1649  * The provided output stream must be closed by the caller, if necessary (e.g., an ofstream).
1650  *
1651  * \param ostream The output stream to write to.
1652  */
1653  void archive(std::ostream & ostream) const;
1654 
1655  Config(const Config &) = delete;
1656  Config& operator= (const Config &) = delete;
1657 
1658  /// Do not use (needed only for pybind11).
1659  ~Config();
1660 
1661 private:
1662  Config();
1663 
1664  static void deleter(Config* c);
1665 
1666  class Impl;
1667  Impl * m_impl;
1668  Impl * getImpl() { return m_impl; }
1669  const Impl * getImpl() const { return m_impl; }
1670 };
1671 
1672 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Config&);
1673 
1674 
1675 /**
1676  * \brief
1677  * The File Rules are a set of filepath to color space mappings that are evaluated
1678  * from first to last. The first rule to match is what determines which color space is
1679  * returned. There are four types of rules available. Each rule type has a name key that may
1680  * be used by applications to refer to that rule. Name values must be unique i.e. using a
1681  * case insensitive comparison. The other keys depend on the rule type:
1682  *
1683  * * *Basic Rule*: This is the basic rule type that uses Unix glob style pattern matching and
1684  * is thus very easy to use. It contains the keys:
1685  * * name: Name of the rule
1686  * * colorspace: Color space name to be returned.
1687  * * pattern: Glob pattern to be used for the main part of the name/path.
1688  * * extension: Glob pattern to be used for the file extension. Note that if glob tokens
1689  * are not used, the extension will be used in a non-case-sensitive way by default.
1690  *
1691  * * *Regex Rule*: This is similar to the basic rule but allows additional capabilities for
1692  * power-users. It contains the keys:
1693  * * name: Name of the rule
1694  * * colorspace: Color space name to be returned.
1695  * * regex: Regular expression to be evaluated.
1696  *
1697  * * *OCIO v1 style Rule*: This rule allows the use of the OCIO v1 style, where the string
1698  * is searched for color space names from the config. This rule may occur 0 or 1 times
1699  * in the list. The position in the list prioritizes it with respect to the other rules.
1700  * StrictParsing is not used. If no color space is found in the path, the rule will not
1701  * match and the next rule will be considered.
1702  * see \ref insertPathSearchRule.
1703  * It has the key:
1704  * * name: Must be "ColorSpaceNamePathSearch".
1705  *
1706  * * *Default Rule*: The file_rules must always end with this rule. If no prior rules match,
1707  * this rule specifies the color space applications will use.
1708  * see \ref setDefaultRuleColorSpace.
1709  * It has the keys:
1710  * * name: must be "Default".
1711  * * colorspace : Color space name to be returned.
1712  *
1713  * Custom string keys and associated string values may be used to convey app or
1714  * workflow-specific information, e.g. whether the color space should be left as is
1715  * or converted into a working space.
1716  *
1717  * Getters and setters are using the rule position, they will throw if the position is not
1718  * valid. If the rule at the specified position does not implement the requested property
1719  * getter will return NULL and setter will throw.
1720  *
1721  * When loading a v1 config, a set of FileRules are created with ColorSpaceNamePathSearch followed
1722  * by the Default rule pointing to the default role. This allows getColorSpaceFromFilepath to emulate
1723  * OCIO v1 code that used parseColorSpaceFromString with strictparsing set to false.
1724  */
1725 
1727 {
1728 public:
1729 
1730  /// Reserved rule name for the default rule.
1731  static const char * DefaultRuleName;
1732  /// Reserved rule name for the file path search rule \see FileRules::insertPathSearchRule.
1733  static const char * FilePathSearchRuleName;
1734 
1735  /**
1736  * Creates FileRules for a Config. File rules will contain the default rule
1737  * using the default role. The default rule cannot be removed.
1738  */
1739  static FileRulesRcPtr Create();
1740 
1741  /// The method clones the content decoupling the two instances.
1742  FileRulesRcPtr createEditableCopy() const;
1743 
1744  /// Does include default rule. Result will be at least 1.
1745  size_t getNumEntries() const noexcept;
1746 
1747  /// Get the index from the rule name. Throws if the rule is not found.
1748  size_t getIndexForRule(const char * ruleName) const;
1749 
1750  /// Get name of the rule.
1751  const char * getName(size_t ruleIndex) const;
1752 
1753  /// Setting pattern will erase regex.
1754  const char * getPattern(size_t ruleIndex) const;
1755  void setPattern(size_t ruleIndex, const char * pattern);
1756 
1757  /// Setting extension will erase regex.
1758  const char * getExtension(size_t ruleIndex) const;
1759  void setExtension(size_t ruleIndex, const char * extension);
1760 
1761  /// Setting a regex will erase pattern & extension.
1762  const char * getRegex(size_t ruleIndex) const;
1763  void setRegex(size_t ruleIndex, const char * regex);
1764 
1765  /// Set the rule's color space (may also be a role).
1766  const char * getColorSpace(size_t ruleIndex) const;
1767  void setColorSpace(size_t ruleIndex, const char * colorSpace);
1768 
1769  /// Get number of key/value pairs.
1770  size_t getNumCustomKeys(size_t ruleIndex) const;
1771  /// Get name of key.
1772  const char * getCustomKeyName(size_t ruleIndex, size_t key) const;
1773  /// Get value for the key.
1774  const char * getCustomKeyValue(size_t ruleIndex, size_t key) const;
1775  /**
1776  * Adds a key/value or replace value if key exists. Setting a NULL or an
1777  * empty value will erase the key.
1778  */
1779  void setCustomKey(size_t ruleIndex, const char * key, const char * value);
1780 
1781  /**
1782  * \brief Insert a rule at a given ruleIndex.
1783  *
1784  * Rule currently at ruleIndex will be pushed to index: ruleIndex + 1.
1785  * Name must be unique.
1786  * - "Default" is a reserved name for the default rule. The default rule is automatically
1787  * added and can't be removed. (see \ref FileRules::setDefaultRuleColorSpace ).
1788  * - "ColorSpaceNamePathSearch" is also a reserved name
1789  * (see \ref FileRules::insertPathSearchRule ).
1790  *
1791  * Will throw if pattern, extension or regex is a null or empty string.
1792  *
1793  * Will throw if ruleIndex is not less than \ref FileRules::getNumEntries .
1794  */
1795  void insertRule(size_t ruleIndex, const char * name, const char * colorSpace,
1796  const char * pattern, const char * extension);
1797  void insertRule(size_t ruleIndex, const char * name, const char * colorSpace,
1798  const char * regex);
1799  /**
1800  * \brief Helper function to insert a rule.
1801  *
1802  * Uses \ref Config:parseColorSpaceFromString to search the path for any of
1803  * the color spaces named in the config (as per OCIO v1).
1804  */
1805  void insertPathSearchRule(size_t ruleIndex);
1806  /// Helper function to set the color space for the default rule.
1807  void setDefaultRuleColorSpace(const char * colorSpace);
1808 
1809  /**
1810  * \brief
1811  *
1812  * \note
1813  * Default rule can't be removed.
1814  * Will throw if ruleIndex + 1 is not less than \ref FileRules::getNumEntries .
1815  */
1816  void removeRule(size_t ruleIndex);
1817 
1818  /// Move a rule closer to the start of the list by one position.
1819  void increaseRulePriority(size_t ruleIndex);
1820 
1821  /// Move a rule closer to the end of the list by one position.
1822  void decreaseRulePriority(size_t ruleIndex);
1823 
1824  /**
1825  * Check if there is only the default rule using default role and no custom key. This is the
1826  * default FileRules state when creating a new config.
1827  */
1828  bool isDefault() const noexcept;
1829 
1830  FileRules(const FileRules &) = delete;
1831  FileRules & operator= (const FileRules &) = delete;
1832 
1833  /// Do not use (needed only for pybind11).
1834  virtual ~FileRules();
1835 
1836 private:
1837  FileRules();
1838 
1839  static void deleter(FileRules* c);
1840 
1841  friend class Config;
1842 
1843  class Impl;
1844  Impl * m_impl;
1845  Impl * getImpl() { return m_impl; }
1846  const Impl * getImpl() const { return m_impl; }
1847 };
1848 
1849 extern OCIOEXPORT std::ostream & operator<< (std::ostream &, const FileRules &);
1850 
1851 
1852 
1853 /**
1854  * ViewingRules
1855  *
1856  * Viewing Rules allow config authors to filter the list of views an application should offer
1857  * based on the color space of an image. For example, a config may define a large number of
1858  * views but not all of them may be appropriate for use with all color spaces. E.g., some views
1859  * may be intended for use with scene-linear color space encodings and others with video color
1860  * space encodings.
1861  *
1862  * Each rule has a name key for applications to refer to the rule. Name values must be unique
1863  * (using case insensitive comparison). Viewing Rules may also have the following keys:
1864  *
1865  * * colorspaces: Either a single colorspace name or a list of names.
1866  *
1867  * * encodings: One or more strings to be found in the colorspace's encoding attribute.
1868  * Either this attribute or colorspaces must be present, but not both.
1869  *
1870  * * custom : Allows arbitrary key / value string pairs, similar to FileRules.
1871  *
1872  * Getters and setters are using the rule position, they will throw if the position is not
1873  * valid.
1874 */
1876 {
1877 public:
1878  /// Creates ViewingRules for a Config.
1879  static ViewingRulesRcPtr Create();
1880 
1881  /// The method clones the content decoupling the two instances.
1882  ViewingRulesRcPtr createEditableCopy() const;
1883 
1884  size_t getNumEntries() const noexcept;
1885 
1886  /**
1887  * Get the index from the rule name. Will throw if there is no rule named
1888  * ruleName.
1889  */
1890  size_t getIndexForRule(const char * ruleName) const;
1891 
1892  /// Get name of the rule. Will throw if ruleIndex is invalid.
1893  const char * getName(size_t ruleIndex) const;
1894 
1895  /// Get number of colorspaces. Will throw if ruleIndex is invalid.
1896  size_t getNumColorSpaces(size_t ruleIndex) const;
1897  /// Get colorspace name. Will throw if ruleIndex or colorSpaceIndex is invalid.
1898  const char * getColorSpace(size_t ruleIndex, size_t colorSpaceIndex) const;
1899  /**
1900  * \brief
1901  *
1902  * Add colorspace name. Will throw if:
1903  * * RuleIndex is invalid.
1904  * * \ref ViewingRules::getNumEncodings is not 0.
1905  */
1906  void addColorSpace(size_t ruleIndex, const char * colorSpace);
1907  /// Remove colorspace. Will throw if ruleIndex or colorSpaceIndex is invalid.
1908  void removeColorSpace(size_t ruleIndex, size_t colorSpaceIndex);
1909 
1910  /// Get number of encodings. Will throw if ruleIndex is invalid.
1911  size_t getNumEncodings(size_t ruleIndex) const;
1912  /// Get encoding name. Will throw if ruleIndex or encodingIndex is invalid.
1913  const char * getEncoding(size_t ruleIndex, size_t encodingIndex) const;
1914 
1915  /**
1916  * \brief
1917  * Add encoding name. Will throw if:
1918  * * RuleIndex is invalid.
1919  * * \ref ViewingRules::getNumColorSpaces is not 0.
1920  */
1921  void addEncoding(size_t ruleIndex, const char * encoding);
1922  /// Remove encoding. Will throw if ruleIndex or encodingIndex is invalid.
1923  void removeEncoding(size_t ruleIndex, size_t encodingIndex);
1924 
1925  /// Get number of key/value pairs. Will throw if ruleIndex is invalid.
1926  size_t getNumCustomKeys(size_t ruleIndex) const;
1927  /// Get name of key. Will throw if ruleIndex or keyIndex is invalid.
1928  const char * getCustomKeyName(size_t ruleIndex, size_t keyIndex) const;
1929  /// Get value for the key. Will throw if ruleIndex or keyIndex is invalid.
1930  const char * getCustomKeyValue(size_t ruleIndex, size_t keyIndex) const;
1931  /**
1932  * Adds a key/value or replace value if key exists. Setting a NULL or an
1933  * empty value will erase the key. Will throw if ruleIndex is invalid.
1934  */
1935  void setCustomKey(size_t ruleIndex, const char * key, const char * value);
1936 
1937  /**
1938  * \brief Insert a rule at a given ruleIndex.
1939  *
1940  * Rule currently at ruleIndex will be pushed to index: ruleIndex + 1. If ruleIndex is
1941  * \ref ViewingRules::getNumEntries, a new rule will be added at the end. Will throw if:
1942  * * RuleIndex is invalid (must be less than or equal to
1943  * \ref ViewingRules::getNumEntries).
1944  * * RuleName already exists.
1945  */
1946  void insertRule(size_t ruleIndex, const char * ruleName);
1947 
1948  /// Remove a rule. Throws if ruleIndex is not valid.
1949  void removeRule(size_t ruleIndex);
1950 
1951  ViewingRules(const ViewingRules &) = delete;
1952  ViewingRules & operator= (const ViewingRules &) = delete;
1953  /// Do not use (needed only for pybind11).
1954  virtual ~ViewingRules();
1955 
1956 private:
1957  ViewingRules();
1958 
1959  static void deleter(ViewingRules* c);
1960 
1961  friend class Config;
1962 
1963  class Impl;
1964  Impl * m_impl;
1965  Impl * getImpl() { return m_impl; }
1966  const Impl * getImpl() const { return m_impl; }
1967 };
1968 
1969 extern OCIOEXPORT std::ostream & operator<< (std::ostream &, const ViewingRules &);
1970 
1971 //
1972 // ColorSpace
1973 //
1974 /**
1975  * The *ColorSpace* is the state of an image with respect to colorimetry
1976  * and color encoding. Transforming images between different
1977  * *ColorSpaces* is the primary motivation for this library.
1978  *
1979  * While a complete discussion of color spaces is beyond the scope of
1980  * header documentation, traditional uses would be to have *ColorSpaces*
1981  * corresponding to: physical capture devices (known cameras, scanners),
1982  * and internal 'convenience' spaces (such as scene linear, logarithmic).
1983  */
1985 {
1986 public:
1987  static ColorSpaceRcPtr Create();
1988 
1989  static ColorSpaceRcPtr Create(ReferenceSpaceType referenceSpace);
1990 
1991  ColorSpaceRcPtr createEditableCopy() const;
1992 
1993  const char * getName() const noexcept;
1994  /// If the name is already an alias, that alias is removed.
1995  void setName(const char * name) noexcept;
1996 
1997  size_t getNumAliases() const noexcept;
1998  /// Return empty string if idx is out of range.
1999  const char * getAlias(size_t idx) const noexcept;
2000  /// Return true if alias exists.
2001  bool hasAlias(const char * alias) const noexcept;
2002  /**
2003  * Add an alias for the color space name (the aliases may be used as a synonym for the
2004  * name). Nothing will be added if the alias is already the color space name, one of its
2005  * aliases, or the argument is null. The aliases must not conflict with existing roles,
2006  * color space names, named transform names, or other aliases. This is verified when
2007  * adding the color space to the config.
2008  */
2009  void addAlias(const char * alias) noexcept;
2010  /// Does nothing if alias is not present.
2011  void removeAlias(const char * alias) noexcept;
2012  void clearAliases() noexcept;
2013 
2014  /**
2015  * Get the family, for use in user interfaces (optional)
2016  * The family string could use a '/' separator to indicate levels to be used
2017  * by hierarchical menus.
2018  */
2019  const char * getFamily() const noexcept;
2020  /// Set the family, for use in user interfaces (optional)
2021  void setFamily(const char * family);
2022 
2023  /**
2024  * Get the ColorSpace group name (used for equality comparisons)
2025  * This allows no-op transforms between different colorspaces.
2026  * If an equalityGroup is not defined (an empty string), it will be considered
2027  * unique (i.e., it will not compare as equal to other ColorSpaces with an
2028  * empty equality group).
2029  */
2030  const char * getEqualityGroup() const noexcept;
2031  void setEqualityGroup(const char * equalityGroup);
2032 
2033  const char * getDescription() const noexcept;
2034  void setDescription(const char * description);
2035 
2036  /**
2037  * Get/Set the interop ID for the color space. The interop ID is a
2038  * structured string defined by the Color Interop Forum. It is intended to
2039  * identify color spaces in a way that is portable across different configs,
2040  * making it suitable for use in various file formats. The Color Interop
2041  * Forum publishes ID strings for common color spaces. If you create your
2042  * own IDs, they must be preceded by a namespace string. The setter will
2043  * throw if the string does not follow certain rules (run ociocheck for a
2044  * more complete validation).
2045  */
2046  const char * getInteropID() const noexcept;
2047  void setInteropID(const char * interopID);
2048 
2049  /**
2050  * Get/Set the interchange attributes.
2051  *
2052  * Currently supported attribute names are "amf_transform_ids" and
2053  * "icc_profile_name". Using any other name will throw. If the attribute is
2054  * not defined, it will return an empty string. Setting the value to an empty
2055  * string will effectively delete the attribute.
2056  *
2057  * The AMF transform IDs are used to identify specific transforms in the
2058  * ACES Metadata File. Multiple transform IDs can be specified in a
2059  * newline-separated string.
2060  *
2061  * The ICC profile name identifies the ICC color profile associated with
2062  * this color space. This can be used to link OCIO color spaces with
2063  * corresponding ICC profiles for applications that need to work with both
2064  * color management systems.
2065  */
2066  const char *getInterchangeAttribute(const char *attrName) const;
2067  void setInterchangeAttribute(const char* attrName, const char *value);
2068  std::map<std::string, std::string> getInterchangeAttributes() const noexcept;
2069 
2070  BitDepth getBitDepth() const noexcept;
2071  void setBitDepth(BitDepth bitDepth);
2072 
2073  /// A display color space will use the display-referred reference space.
2074  ReferenceSpaceType getReferenceSpaceType() const noexcept;
2075 
2076  //
2077  // Categories
2078  //
2079 
2080  /**
2081  * A category is used to allow applications to filter the list of color spaces
2082  * they display in menus based on what that color space is used for.
2083  *
2084  * Here is an example config entry that could appear under a ColorSpace:
2085  *
2086  * \code{.yaml}
2087  * categories: [ file-io, working-space, basic-3d ]
2088  * \endcode
2089  *
2090  * The example contains three categories: 'file-io', 'working-space' and 'basic-3d'.
2091  *
2092  * \note
2093  * Category strings are not case-sensitive and the order is not significant.
2094  *
2095  * There is no limit imposed on length or number. Although users may add their own categories,
2096  * the strings will typically come from a fixed set listed in the documentation (similar to
2097  * roles).
2098  */
2099  /// Return true if the category is present.
2100  bool hasCategory(const char * category) const;
2101  /**
2102  * \brief Add a single category.
2103  *
2104  * \note
2105  * Will do nothing if the category already exists.
2106  */
2107  void addCategory(const char * category);
2108  /**
2109  * \brief Remove a category.
2110  *
2111  * \note
2112  * Will do nothing if the category is missing.
2113  */
2114  void removeCategory(const char * category);
2115  /// Get the number of categories.
2116  int getNumCategories() const;
2117  /**
2118  * \brief Return the category name using its index
2119  *
2120  * \note
2121  * Will be null if the index is invalid.
2122  */
2123  const char * getCategory(int index) const;
2124  /// Clear all the categories.
2125  void clearCategories();
2126 
2127  /**
2128  * *Encodings*
2129  *
2130  * It is sometimes useful for applications to group color spaces based on how the color values
2131  * are digitally encoded. For example, images in scene-linear, logarithmic, video, and data
2132  * color spaces could have different default views. Unlike the Family and EqualityGroup
2133  * attributes of a color space, the list of Encodings is predefined in the OCIO documentation
2134  * (rather than being config-specific) to make it easier for applications to utilize.
2135  *
2136  * Here is an example config entry that could appear under a ColorSpace:
2137  *
2138  * \code{.yaml}
2139  * encoding: scene-linear
2140  * \endcode
2141  *
2142  * Encoding strings are not case-sensitive. Although users may add their own encodings, the
2143  * strings will typically come from a fixed set listed in the documentation (similar to roles).
2144  */
2145  const char * getEncoding() const noexcept;
2146  void setEncoding(const char * encoding);
2147 
2148  /**
2149  * *Data*
2150  *
2151  * ColorSpaces that are data are treated a bit special. Basically, any colorspace transforms
2152  * you try to apply to them are ignored. (Think of applying a gamut mapping transform to an
2153  * ID pass). However, the setDataBypass method on ColorSpaceTransform and DisplayViewTransform
2154  * allow applications to process data when necessary. (Think of sending mattes to an HDR
2155  * monitor.)
2156  *
2157  * This is traditionally used for pixel data that represents non-color
2158  * pixel data, such as normals, point positions, ID information, etc.
2159  */
2160  bool isData() const noexcept;
2161  void setIsData(bool isData) noexcept;
2162 
2163  /**
2164  * *Allocation*
2165  *
2166  * If this colorspace needs to be transferred to a limited dynamic
2167  * range coding space (such as during display with a GPU path), use this
2168  * allocation to maximize bit efficiency.
2169  */
2170  Allocation getAllocation() const noexcept;
2171  void setAllocation(Allocation allocation) noexcept;
2172 
2173  /**
2174  * Specify the optional variable values to configure the allocation.
2175  * If no variables are specified, the defaults are used.
2176  *
2177  * ALLOCATION_UNIFORM::
2178  *
2179  * 2 vars: [min, max]
2180  *
2181  * ALLOCATION_LG2::
2182  *
2183  * 2 vars: [lg2min, lg2max]
2184  * 3 vars: [lg2min, lg2max, linear_offset]
2185  */
2186  int getAllocationNumVars() const;
2187  void getAllocationVars(float * vars) const;
2188  void setAllocationVars(int numvars, const float * vars);
2189 
2190  /**
2191  * *Transform*
2192  *
2193  * If a transform in the specified direction has been specified,
2194  * return it. Otherwise return a null ConstTransformRcPtr
2195  */
2196  ConstTransformRcPtr getTransform(ColorSpaceDirection dir) const noexcept;
2197  /**
2198  * Specify the transform for the appropriate direction.
2199  * Setting the transform to null will clear it.
2200  */
2201  void setTransform(const ConstTransformRcPtr & transform, ColorSpaceDirection dir);
2202 
2203  ColorSpace(const ColorSpace &) = delete;
2204  ColorSpace& operator= (const ColorSpace &) = delete;
2205  /// Do not use (needed only for pybind11).
2206  ~ColorSpace();
2207 
2208 private:
2209  explicit ColorSpace(ReferenceSpaceType referenceSpace);
2210  ColorSpace();
2211 
2212  static void deleter(ColorSpace* c);
2213 
2214  class Impl;
2215  Impl * m_impl;
2216  Impl * getImpl() { return m_impl; }
2217  const Impl * getImpl() const { return m_impl; }
2218 };
2219 
2220 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ColorSpace&);
2221 
2222 
2223 
2224 
2225 //
2226 // ColorSpaceSet
2227 //
2228 
2229 
2230 /**
2231  * The *ColorSpaceSet* is a set of color spaces (i.e. no color space duplication)
2232  * which could be the result of \ref Config::getColorSpaces
2233  * or built from scratch.
2234  *
2235  * \note
2236  * The color spaces are decoupled from the config ones, i.e., any
2237  * changes to the set itself or to its color spaces do not affect the
2238  * original color spaces from the configuration. If needed,
2239  * use \ref Config::addColorSpace to update the configuration.
2240  */
2242 {
2243 public:
2244  /// Create an empty set of color spaces.
2245  static ColorSpaceSetRcPtr Create();
2246 
2247  /// Create a set containing a copy of all the color spaces.
2248  ColorSpaceSetRcPtr createEditableCopy() const;
2249 
2250  /**
2251  * \brief Return true if the two sets are equal.
2252  *
2253  * \note
2254  * The comparison is done on the color space names (not a deep comparison).
2255  */
2256  bool operator==(const ColorSpaceSet & css) const;
2257  /// Return true if the two sets are different.
2258  bool operator!=(const ColorSpaceSet & css) const;
2259 
2260  /// Return the number of color spaces.
2261  int getNumColorSpaces() const;
2262  /**
2263  * Return the color space name using its index.
2264  * This will be null if an invalid index is specified.
2265  */
2266  const char * getColorSpaceNameByIndex(int index) const;
2267  /**
2268  * Return the color space using its index.
2269  * This will be empty if an invalid index is specified.
2270  */
2271  ConstColorSpaceRcPtr getColorSpaceByIndex(int index) const;
2272 
2273  /**
2274  * \brief
2275  *
2276  * \note
2277  * Only accepts color space names (i.e. no role name).
2278  *
2279  * Will return null if the name is not found.
2280  */
2281  ConstColorSpaceRcPtr getColorSpace(const char * name) const;
2282  /**
2283  * Will return -1 if the name is not found.
2284  *
2285  * \note
2286  * Only accepts color space names (i.e. no role name).
2287  */
2288  int getColorSpaceIndex(const char * name) const;
2289  /**
2290  * \brief
2291  *
2292  * \note
2293  * Only accepts color space names (i.e. no role name)
2294  *
2295  * \param name
2296  * \return true
2297  * \return false
2298  */
2299  bool hasColorSpace(const char * name) const;
2300 
2301  /**
2302  * \brief Add color space(s).
2303  *
2304  * \note
2305  * If another color space is already registered with the same name,
2306  * this will overwrite it. This stores a copy of the specified
2307  * color space(s). Throws if one of the aliases is already assigned as
2308  * a name or alias to an existing color space.
2309  */
2310  void addColorSpace(const ConstColorSpaceRcPtr & cs);
2311  void addColorSpaces(const ConstColorSpaceSetRcPtr & cs);
2312 
2313  /**
2314  * \brief Remove color space(s) using color space names (i.e. no role name).
2315  *
2316  * \note
2317  * The removal of a missing color space does nothing.
2318  */
2319  void removeColorSpace(const char * name);
2320  void removeColorSpaces(const ConstColorSpaceSetRcPtr & cs);
2321 
2322  /// Clear all color spaces.
2323  void clearColorSpaces();
2324 
2325  /// Do not use (needed only for pybind11).
2326  ~ColorSpaceSet();
2327 
2328 private:
2329  ColorSpaceSet();
2330 
2331  ColorSpaceSet(const ColorSpaceSet &);
2333 
2334  static void deleter(ColorSpaceSet * c);
2335 
2336  class Impl;
2337  Impl * m_impl;
2338  Impl * getImpl() { return m_impl; }
2339  const Impl * getImpl() const { return m_impl; }
2340 };
2341 
2342 /** ColorSpaceSetOperators
2343  */
2344 
2345 /**
2346  * \brief Perform the union of two sets.
2347  *
2348  * \note
2349  * This function provides operations on two color space sets
2350  * where the result contains copied color spaces and no duplicates.
2351  *
2352  * \param lcss
2353  * \param rcss
2354  */
2356  const ConstColorSpaceSetRcPtr & rcss);
2357  /**
2358  * \brief Perform the intersection of two sets.
2359  *
2360  * \note
2361  * This function provides operations on two color space sets
2362  * where the result contains copied color spaces and no duplicates.
2363  *
2364  * \param lcss
2365  * \param rcss
2366  */
2368  const ConstColorSpaceSetRcPtr & rcss);
2369 /**
2370  * \brief Perform the difference of two sets.
2371  *
2372  * \note
2373  * This function provides operations on two color space sets
2374  * where the result contains copied color spaces and no duplicates.
2375  *
2376  * \param lcss
2377  * \param rcss
2378  */
2380  const ConstColorSpaceSetRcPtr & rcss);
2381 
2382 
2383 //
2384 // Look
2385 //
2386 
2387 /**
2388  * The *Look* is an 'artistic' image modification, in a specified image
2389  * state.
2390  * The processSpace defines the ColorSpace the image is required to be
2391  * in, for the math to apply correctly.
2392  */
2394 {
2395 public:
2396  static LookRcPtr Create();
2397 
2398  LookRcPtr createEditableCopy() const;
2399 
2400  const char * getName() const;
2401  void setName(const char * name);
2402 
2403  const char * getProcessSpace() const;
2404  void setProcessSpace(const char * processSpace);
2405 
2406  ConstTransformRcPtr getTransform() const;
2407  /// Setting a transform to a non-null call makes it allowed.
2408  void setTransform(const ConstTransformRcPtr & transform);
2409 
2410  ConstTransformRcPtr getInverseTransform() const;
2411  /// Setting a transform to a non-null call makes it allowed.
2412  void setInverseTransform(const ConstTransformRcPtr & transform);
2413 
2414  const char * getDescription() const;
2415  void setDescription(const char * description);
2416 
2417  /**
2418  * Get/Set the interchange attributes.
2419  *
2420  * Currently the only supported attribute name is "amf_transform_ids". Using
2421  * any other name will throw. If the attribute is not defined, it will return
2422  * an empty string. Setting the value to an empty string will effectively
2423  * delete the attribute.
2424  *
2425  * The AMF transform IDs are used to identify specific transforms in the ACES
2426  * Metadata File. Multiple transform IDs can be specified in a
2427  * newline-separated string.
2428  */
2429  const char *getInterchangeAttribute(const char *attrName) const;
2430  void setInterchangeAttribute(const char* attrName, const char *value);
2431  std::map<std::string, std::string> getInterchangeAttributes() const noexcept;
2432 
2433  Look(const Look &) = delete;
2434  Look& operator= (const Look &) = delete;
2435  /// Do not use (needed only for pybind11).
2436  ~Look();
2437 
2438 private:
2439  Look();
2440 
2441  static void deleter(Look* c);
2442 
2443  class Impl;
2444  Impl * m_impl;
2445  Impl * getImpl() { return m_impl; }
2446  const Impl * getImpl() const { return m_impl; }
2447 };
2448 
2449 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Look&);
2450 
2451 
2452 /**
2453  * \brief NamedTransform.
2454  *
2455  * A NamedTransform provides a way for config authors to include a set of color
2456  * transforms that are independent of the color space being processed. For example a "utility
2457  * curve" transform where there is no need to convert to or from a reference space.
2458  */
2459 
2461 {
2462 public:
2463  static NamedTransformRcPtr Create();
2464 
2465  virtual NamedTransformRcPtr createEditableCopy() const = 0;
2466 
2467  virtual const char * getName() const noexcept = 0;
2468  virtual void setName(const char * name) noexcept = 0;
2469 
2470  /// Aliases can be used instead of the name. They must be unique within the config.
2471  virtual size_t getNumAliases() const noexcept = 0;
2472  /// Return empty string if idx is out of range.
2473  virtual const char * getAlias(size_t idx) const noexcept = 0;
2474  /// Return true if alias exists.
2475  virtual bool hasAlias(const char* alias) const noexcept = 0;
2476  /**
2477  * Nothing is done if alias is NULL or empty, if it is already there, or if it is already
2478  * the named transform name.
2479  */
2480  virtual void addAlias(const char * alias) noexcept = 0;
2481  /// Does nothing if alias is not present.
2482  virtual void removeAlias(const char * alias) noexcept = 0;
2483  virtual void clearAliases() noexcept = 0;
2484 
2485  /// \see ColorSpace::getFamily
2486  virtual const char * getFamily() const noexcept = 0;
2487  /// \see ColorSpace::setFamily
2488  virtual void setFamily(const char * family) noexcept = 0;
2489 
2490  virtual const char * getDescription() const noexcept = 0;
2491  virtual void setDescription(const char * description) noexcept = 0;
2492 
2493  /// \see ColorSpace::hasCategory
2494  virtual bool hasCategory(const char * category) const noexcept = 0;
2495  /// \see ColorSpace::addCategory
2496  virtual void addCategory(const char * category) noexcept = 0;
2497  /// \see ColorSpace::removeCategory
2498  virtual void removeCategory(const char * category) noexcept = 0;
2499  /// \see ColorSpace::getNumCategories
2500  virtual int getNumCategories() const noexcept = 0;
2501  /// \see ColorSpace::getCategory
2502  virtual const char * getCategory(int index) const noexcept = 0;
2503  /// \see ColorSpace::clearCategories
2504  virtual void clearCategories() noexcept = 0;
2505 
2506  /**
2507  * A NamedTransform is not a color space and does not have an encoding in the same sense.
2508  * However, it may be useful to associate a color space encoding that the transform is intended
2509  * to be used with, for organizational purposes.
2510  */
2511  virtual const char * getEncoding() const noexcept = 0;
2512  virtual void setEncoding(const char * encoding) noexcept = 0;
2513 
2514  virtual ConstTransformRcPtr getTransform(TransformDirection dir) const = 0;
2515  virtual void setTransform(const ConstTransformRcPtr & transform, TransformDirection dir) = 0;
2516 
2517  /**
2518  * Will create the transform from the inverse direction if the transform for requested
2519  * direction is missing.
2520  */
2521  static ConstTransformRcPtr GetTransform(const ConstNamedTransformRcPtr & nt,
2522  TransformDirection dir);
2523 
2524  NamedTransform(const NamedTransform &) = delete;
2525  NamedTransform & operator= (const NamedTransform &) = delete;
2526  // Do not use (needed only for pybind11).
2527  virtual ~NamedTransform() = default;
2528 
2529 protected:
2530  NamedTransform() = default;
2531 };
2532 
2533 extern OCIOEXPORT std::ostream & operator<< (std::ostream &, const NamedTransform &);
2534 
2535 
2536 /**
2537  * A *ViewTransform* provides a conversion from the main (usually scene-referred) reference space
2538  * to the display-referred reference space. This allows splitting the conversion from the main
2539  * reference space to a display into two parts: the ViewTransform plus a display color space.
2540  *
2541  * It is also possible to provide a ViewTransform that converts from the display-referred
2542  * reference space back to that space. This is useful in cases when a ViewTransform is needed
2543  * when converting between displays (such as HDR to SDR).
2544  *
2545  * The ReferenceSpaceType indicates whether the ViewTransform converts from scene-to-display
2546  * reference or display-to-display reference.
2547  *
2548  * The from_reference transform direction is the one that is used when going out towards a display.
2549  */
2551 {
2552 public:
2553  static ViewTransformRcPtr Create(ReferenceSpaceType referenceSpace);
2554 
2555  ViewTransformRcPtr createEditableCopy() const;
2556 
2557  const char * getName() const noexcept;
2558  void setName(const char * name) noexcept;
2559 
2560  /// \see ColorSpace::getFamily
2561  const char * getFamily() const noexcept;
2562  /// \see ColorSpace::setFamily
2563  void setFamily(const char * family);
2564 
2565  const char * getDescription() const noexcept;
2566  void setDescription(const char * description);
2567 
2568  /**
2569  * Get/Set the interchange attributes.
2570  *
2571  * Currently the only supported attribute name is "amf_transform_ids". Using
2572  * any other name will throw. If the attribute is not defined, it will return
2573  * an empty string. Setting the value to an empty string will effectively
2574  * delete the attribute.
2575  *
2576  * The AMF transform IDs are used to identify specific transforms in the ACES
2577  * Metadata File. Multiple transform IDs can be specified in a
2578  * newline-separated string.
2579  */
2580  const char *getInterchangeAttribute(const char *attrName) const;
2581  void setInterchangeAttribute(const char* attrName, const char *value);
2582  std::map<std::string, std::string> getInterchangeAttributes() const noexcept;
2583 
2584  /// \see ColorSpace::hasCategory
2585  bool hasCategory(const char * category) const;
2586  /// \see ColorSpace::addCategory
2587  void addCategory(const char * category);
2588  /// \see ColorSpace::removeCategory
2589  void removeCategory(const char * category);
2590  /// \see ColorSpace::getNumCategories
2591  int getNumCategories() const;
2592  /// \see ColorSpace::getCategory
2593  const char * getCategory(int index) const;
2594  /// \see ColorSpace::clearCategories
2595  void clearCategories();
2596 
2597  ReferenceSpaceType getReferenceSpaceType() const noexcept;
2598 
2599  /**
2600  * If a transform in the specified direction has been specified, return it.
2601  * Otherwise return a null ConstTransformRcPtr
2602  */
2603  ConstTransformRcPtr getTransform(ViewTransformDirection dir) const noexcept;
2604 
2605  /**
2606  * Specify the transform for the appropriate direction. Setting the transform
2607  * to null will clear it.
2608  */
2609  void setTransform(const ConstTransformRcPtr & transform, ViewTransformDirection dir);
2610 
2611  ViewTransform(const ViewTransform &) = delete;
2612  ViewTransform & operator= (const ViewTransform &) = delete;
2613  /// Do not use (needed only for pybind11).
2614  ~ViewTransform();
2615 
2616 private:
2617  ViewTransform();
2618  explicit ViewTransform(ReferenceSpaceType referenceSpace);
2619 
2620  static void deleter(ViewTransform * c);
2621 
2622  class Impl;
2623  Impl * m_impl;
2624  Impl * getImpl() { return m_impl; }
2625  const Impl * getImpl() const { return m_impl; }
2626 };
2627 
2628 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ViewTransform&);
2629 
2630 //
2631 // Processor
2632 //
2633 
2634 
2635 /**
2636  * The *Processor* represents a specific color transformation which is
2637  * the result of \ref Config::getProcessor.
2638  */
2640 {
2641 public:
2642  bool isNoOp() const;
2643 
2644  /**
2645  * True if the image transformation is non-separable.
2646  * For example, if a change in red may also cause a change in green or blue.
2647  */
2648  bool hasChannelCrosstalk() const;
2649 
2650  /**
2651  * Returns a hash string generated by hashing the cachedIDs of the (unoptimized) list of ops
2652  * contained in the Processor. (This forms part of the key used by the config's processor cache.)
2653  */
2654  const char * getCacheID() const;
2655 
2656  /**
2657  * The ProcessorMetadata contains technical information
2658  * such as the number of files and looks used in the processor.
2659  */
2660  ConstProcessorMetadataRcPtr getProcessorMetadata() const;
2661 
2662  /**
2663  * Get a FormatMetadata containing the top level metadata
2664  * for the processor. For a processor from a CLF file, this corresponds to
2665  * the ProcessList metadata.
2666  */
2667  const FormatMetadata & getFormatMetadata() const;
2668 
2669  /**
2670  * Get the number of transforms that comprise the processor.
2671  * Each transform has a (potentially empty) FormatMetadata.
2672  */
2673  int getNumTransforms() const;
2674  /**
2675  * Get a FormatMetadata containing the metadata for a
2676  * transform within the processor. For a processor from a CLF file, this
2677  * corresponds to the metadata associated with an individual process node.
2678  */
2679  const FormatMetadata & getTransformFormatMetadata(int index) const;
2680 
2681  /**
2682  * Return a \ref GroupTransform that contains a copy of the transforms that comprise the
2683  * processor. (Changes to it will not modify the original processor.) Note that the
2684  * GroupTransform::write method may be used to serialize a Processor. Serializing to
2685  * CTF format is a useful technique for debugging Processor contents.
2686  */
2687  GroupTransformRcPtr createGroupTransform() const;
2688 
2689  /**
2690  * The returned pointer may be used to set the default value of any dynamic
2691  * properties of the requested type. Throws if the requested property is not found. Note
2692  * that if the processor contains several ops that support the requested property, only one
2693  * can be dynamic and only this one will be controlled.
2694  *
2695  * \note The dynamic properties are a convenient way to change on-the-fly values without
2696  * generating again and again a CPU or GPU processor instance. Color transformations can
2697  * contain dynamic properties from a ExposureContrastTransform for example.
2698  * So, Processor, CPUProcessor and GpuShaderCreator all have ways to manage dynamic
2699  * properties. However, the transform dynamic properties are decoupled between the types
2700  * of processor instances so that the same Processor can generate several independent CPU
2701  * and/or GPU processor instances i.e. changing the value of the exposure dynamic property
2702  * from a CPU processor instance does not affect the corresponding GPU processor instance.
2703  * Processor creation will log a warning if there are more than one property of a given type.
2704  * There may be more than one property of a given type, but only one will respond to parameter
2705  * updates, the others will use their original parameter values.
2706  */
2707  DynamicPropertyRcPtr getDynamicProperty(DynamicPropertyType type) const;
2708  /// True if at least one dynamic property of that type exists.
2709  bool hasDynamicProperty(DynamicPropertyType type) const noexcept;
2710  /// True if at least one dynamic property of any type exists and is dynamic.
2711  bool isDynamic() const noexcept;
2712 
2713  /**
2714  * Run the optimizer on a Processor to create a new Processor.
2715  * It is usually not necessary to call this since getting a CPUProcessor or GPUProcessor
2716  * will also optimize. However if you need both, calling this method first makes getting
2717  * a CPU and GPU Processor faster since the optimization is effectively only done once.
2718  */
2719  ConstProcessorRcPtr getOptimizedProcessor(OptimizationFlags oFlags) const;
2720 
2721  /**
2722  * Create a Processor that is optimized for a specific in and out bit-depth (as CPUProcessor
2723  * would do). This method is provided primarily for diagnostic purposes.
2724  */
2725  ConstProcessorRcPtr getOptimizedProcessor(BitDepth inBD, BitDepth outBD,
2726  OptimizationFlags oFlags) const;
2727 
2728  //
2729  // GPU Renderer
2730  //
2731 
2732  /// Get an optimized GPUProcessor instance.
2733  ConstGPUProcessorRcPtr getDefaultGPUProcessor() const;
2734  ConstGPUProcessorRcPtr getOptimizedGPUProcessor(OptimizationFlags oFlags) const;
2735 
2736  /**
2737  * Get an optimized GPUProcessor instance that will emulate the OCIO v1 GPU path. This approach
2738  * bakes some of the ops into a single Lut3D and so is less accurate than the current GPU
2739  * processing methods.
2740  */
2741  ConstGPUProcessorRcPtr getOptimizedLegacyGPUProcessor(OptimizationFlags oFlags,
2742  unsigned edgelen) const;
2743 
2744  //
2745  // CPU Renderer
2746  //
2747 
2748  /**
2749  * Get an optimized CPUProcessor instance.
2750  *
2751  * \note
2752  * This may provide higher fidelity than anticipated due to internal
2753  * optimizations. For example, if the inputColorSpace and the
2754  * outputColorSpace are members of the same equalitygroup, no conversion
2755  * will be applied, even though strictly speaking quantization
2756  * should be added.
2757  *
2758  * \note
2759  * The typical use case to apply color processing to an image is:
2760  *
2761  * \code{.cpp}
2762  *
2763  * OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
2764  *
2765  * OCIO::ConstProcessorRcPtr processor
2766  * = config->getProcessor(colorSpace1, colorSpace2);
2767  *
2768  * OCIO::ConstCPUProcessorRcPtr cpuProcessor
2769  * = processor->getDefaultCPUProcessor();
2770  *
2771  * OCIO::PackedImageDesc img(imgDataPtr, imgWidth, imgHeight, imgChannels);
2772  * cpuProcessor->apply(img);
2773  *
2774  * \endcode
2775  */
2776  ConstCPUProcessorRcPtr getDefaultCPUProcessor() const;
2777  ConstCPUProcessorRcPtr getOptimizedCPUProcessor(OptimizationFlags oFlags) const;
2778  ConstCPUProcessorRcPtr getOptimizedCPUProcessor(BitDepth inBitDepth,
2779  BitDepth outBitDepth,
2780  OptimizationFlags oFlags) const;
2781 
2782  Processor(const Processor &) = delete;
2783  Processor & operator= (const Processor &) = delete;
2784  /// Do not use (needed only for pybind11).
2785  ~Processor();
2786 
2787 private:
2788  Processor();
2789 
2790  static ProcessorRcPtr Create();
2791 
2792  static void deleter(Processor* c);
2793 
2794  friend class Config;
2795 
2796  class Impl;
2797  Impl * m_impl;
2798  Impl * getImpl() { return m_impl; }
2799  const Impl * getImpl() const { return m_impl; }
2800 };
2801 
2802 
2803 ///////////////////////////////////////////////////////////////////////////
2804 // CPUProcessor
2805 
2807 {
2808 public:
2809  /// The in and out bit-depths must be equal for isNoOp to be true.
2810  bool isNoOp() const;
2811 
2812  /**
2813  * Equivalent to isNoOp from the underlying Processor, i.e., it ignores
2814  * in/out bit-depth differences.
2815  */
2816  bool isIdentity() const;
2817 
2818  bool hasChannelCrosstalk() const;
2819 
2820  const char * getCacheID() const;
2821 
2822  /// Bit-depth of the input pixel buffer.
2823  BitDepth getInputBitDepth() const;
2824  /// Bit-depth of the output pixel buffer.
2825  BitDepth getOutputBitDepth() const;
2826 
2827  /**
2828  * The returned pointer may be used to set the value of any dynamic properties
2829  * of the requested type. Throws if the requested property is not found. Note that if the
2830  * processor contains several ops that support the requested property, only one can be dynamic.
2831  *
2832  * \note The dynamic properties in this object are decoupled from the ones in the
2833  * \ref Processor it was generated from. For each dynamic property in the Processor,
2834  * there is one in the CPU processor.
2835  */
2836  DynamicPropertyRcPtr getDynamicProperty(DynamicPropertyType type) const;
2837  /// True if at least one dynamic property of that type exists.
2838  bool hasDynamicProperty(DynamicPropertyType type) const noexcept;
2839  /// True if at least one dynamic property of any type exists and is dynamic.
2840  bool isDynamic() const noexcept;
2841 
2842  /**
2843  * \brief Apply to an image with any kind of channel ordering while
2844  * respecting the input and output bit-depths.
2845  */
2846  void apply(const ImageDesc & imgDesc) const;
2847  void apply(const ImageDesc & srcImgDesc, ImageDesc & dstImgDesc) const;
2848 
2849  /**
2850  * Apply to a single pixel respecting that the input and output bit-depths
2851  * be 32-bit float and the image buffer be packed RGB/RGBA.
2852  *
2853  * \note
2854  * This is not as efficient as applying to an entire image at once.
2855  * If you are processing multiple pixels, and have the flexibility,
2856  * use the above function instead.
2857  */
2858  void applyRGB(float * pixel) const;
2859  void applyRGBA(float * pixel) const;
2860 
2861  CPUProcessor(const CPUProcessor &) = delete;
2862  CPUProcessor& operator= (const CPUProcessor &) = delete;
2863  /// Do not use (needed only for pybind11).
2864  ~CPUProcessor();
2865 
2866 private:
2867  CPUProcessor();
2868 
2869  static void deleter(CPUProcessor * c);
2870 
2871  friend class Processor;
2872 
2873  class Impl;
2874  Impl * m_impl;
2875  Impl * getImpl() { return m_impl; }
2876  const Impl * getImpl() const { return m_impl; }
2877 };
2878 
2879 
2880 ///////////////////////////////////////////////////////////////////////////
2881 // GPUProcessor
2882 
2884 {
2885 public:
2886  bool isNoOp() const;
2887 
2888  bool hasChannelCrosstalk() const;
2889 
2890  const char * getCacheID() const;
2891 
2892  /// Extract & Store the shader information to implement the color processing.
2893  void extractGpuShaderInfo(GpuShaderDescRcPtr & shaderDesc) const;
2894 
2895  /// Extract the shader information using a custom GpuShaderCreator class.
2896  void extractGpuShaderInfo(GpuShaderCreatorRcPtr & shaderCreator) const;
2897 
2898  GPUProcessor(const GPUProcessor &) = delete;
2899  GPUProcessor& operator= (const GPUProcessor &) = delete;
2900  /// Do not use (needed only for pybind11).
2901  ~GPUProcessor();
2902 
2903 private:
2904  GPUProcessor();
2905 
2906  static void deleter(GPUProcessor * c);
2907 
2908  friend class Processor;
2909 
2910  class Impl;
2911  Impl * m_impl;
2912  Impl * getImpl() { return m_impl; }
2913  const Impl * getImpl() const { return m_impl; }
2914 };
2915 
2916 
2917 /**
2918  * \brief
2919  *
2920  * This class contains meta information about the process that generated
2921  * this processor. The results of these functions do not
2922  * impact the pixel processing.
2923  */
2925 {
2926 public:
2927  static ProcessorMetadataRcPtr Create();
2928 
2929  int getNumFiles() const;
2930  const char * getFile(int index) const;
2931 
2932  int getNumLooks() const;
2933  const char * getLook(int index) const;
2934 
2935  void addFile(const char * fname);
2936  void addLook(const char * look);
2937 
2938  ProcessorMetadata(const ProcessorMetadata &) = delete;
2939  ProcessorMetadata& operator= (const ProcessorMetadata &) = delete;
2940  /// Do not use (needed only for pybind11).
2941  ~ProcessorMetadata();
2942 
2943 private:
2945 
2946  static void deleter(ProcessorMetadata* c);
2947 
2948  class Impl;
2949  Impl * m_impl;
2950  Impl * getImpl() { return m_impl; }
2951  const Impl * getImpl() const { return m_impl; }
2952 };
2953 
2954 
2955 
2956 /**
2957  * In certain situations it is necessary to serialize transforms into a variety
2958  * of application specific LUT formats. Note that not all file formats that may
2959  * be read also support baking.
2960  *
2961  * **Usage Example:** *Bake a CSP sRGB viewer LUT*
2962  *
2963  * \code{.cpp}
2964  *
2965  * OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromEnv();
2966  * OCIO::BakerRcPtr baker = OCIO::Baker::Create();
2967  * baker->setConfig(config);
2968  * baker->setFormat("csp");
2969  * baker->setInputSpace("lnf");
2970  * baker->setShaperSpace("log");
2971  * baker->setTargetSpace("sRGB");
2972  * auto & metadata = baker->getFormatMetadata();
2973  * metadata.addChildElement(OCIO::METADATA_DESCRIPTION, "A first comment");
2974  * metadata.addChildElement(OCIO::METADATA_DESCRIPTION, "A second comment");
2975  * std::ostringstream out;
2976  * baker->bake(out); // fresh bread anyone!
2977  * std::cout << out.str();
2978  *
2979  * \endcode
2980  */
2982 {
2983 public:
2984  /// Create a new Baker.
2985  static BakerRcPtr Create();
2986 
2987  /// Create a copy of this Baker.
2988  BakerRcPtr createEditableCopy() const;
2989 
2990  ConstConfigRcPtr getConfig() const;
2991  /// Set the config to use.
2992  void setConfig(const ConstConfigRcPtr & config);
2993 
2994  const char * getFormat() const;
2995  /// Set the LUT output format.
2996  void setFormat(const char * formatName);
2997 
2998  const FormatMetadata & getFormatMetadata() const;
2999  /**
3000  * Get editable *optional* format metadata. The metadata that will be used
3001  * varies based on the capability of the given file format. Formats such as CSP,
3002  * IridasCube, and ResolveCube will create comments in the file header using the value of
3003  * any first-level children elements of the formatMetadata. The CLF/CTF formats will make
3004  * use of the top-level "id" and "name" attributes and children elements "Description",
3005  * "InputDescriptor", "OutputDescriptor", and "Info".
3006  */
3007  FormatMetadata & getFormatMetadata();
3008 
3009  const char * getInputSpace() const;
3010  /// Set the input ColorSpace that the LUT will be applied to.
3011  void setInputSpace(const char * inputSpace);
3012 
3013  const char * getShaperSpace() const;
3014  /**
3015  * Set an *optional* ColorSpace or NamedTransform to shape the incoming
3016  * values of the LUT. When baking 3DLUT, this will correspond to the 1D
3017  * shaper used to normalise incoming values to the unit range. When baking
3018  * 1D LUT, this will be used to determine the input range of the LUT.
3019  */
3020  void setShaperSpace(const char * shaperSpace);
3021 
3022  const char * getLooks() const;
3023  /**
3024  * Set the looks to be applied during baking. Looks is a potentially comma
3025  * (or colon) delimited list of lookNames, where +/- prefixes are optionally allowed to
3026  * denote forward/inverse look specification. (And forward is assumed in the absence of
3027  * either).
3028  */
3029  void setLooks(const char * looks);
3030 
3031  const char * getTargetSpace() const;
3032  /// Set the target (i.e., output) color space for the LUT. Must not be used if setDisplayView is used.
3033  void setTargetSpace(const char * targetSpace);
3034 
3035  const char * getDisplay() const;
3036  const char * getView() const;
3037  /// Set the display and view to apply during the baking. Must not be used if setTargetSpace is used.
3038  void setDisplayView(const char * display, const char * view);
3039 
3040  int getShaperSize() const;
3041  /**
3042  * Override the default shaper LUT size. Default value is -1, which allows
3043  * each format to use its own most appropriate size. For the CLF format, the default uses
3044  * a half-domain LUT1D (which is ideal for scene-linear inputs).
3045  */
3046  void setShaperSize(int shapersize);
3047 
3048  int getCubeSize() const;
3049  /**
3050  * Override the main LUT (3d or 1d) sample size. Default value is -1, which allows
3051  * each format to use its own most appropriate size.
3052  */
3053  void setCubeSize(int cubesize);
3054 
3055  /// Bake the LUT into the output stream.
3056  void bake(std::ostream & os) const;
3057 
3058  /// Get the number of LUT bakers.
3059  static int getNumFormats();
3060 
3061  /**
3062  * Get the LUT baker format name at index, return empty string if an invalid
3063  * index is specified.
3064  */
3065  static const char * getFormatNameByIndex(int index);
3066  /**
3067  * Get the LUT baker format extension at index, return empty string if an
3068  * invalid index is specified.
3069  */
3070  static const char * getFormatExtensionByIndex(int index);
3071 
3072  Baker(const Baker &) = delete;
3073  Baker& operator= (const Baker &) = delete;
3074  /// Do not use (needed only for pybind11).
3075  ~Baker();
3076 
3077 private:
3078  Baker();
3079 
3080  static void deleter(Baker* o);
3081 
3082  class Impl;
3083  Impl * m_impl;
3084  Impl * getImpl() { return m_impl; }
3085  const Impl * getImpl() const { return m_impl; }
3086 };
3087 
3088 
3089 ///////////////////////////////////////////////////////////////////////////
3090 // ImageDesc
3091 
3093 
3094 /**
3095  * \brief
3096  * This is a light-weight wrapper around an image, that provides a context
3097  * for pixel access. This does NOT claim ownership of the pixels or copy
3098  * image data.
3099  */
3101 {
3102 public:
3103  ImageDesc();
3104  virtual ~ImageDesc();
3105 
3106  /// Get a pointer to the red channel of the first pixel.
3107  virtual void * getRData() const = 0;
3108  /// Get a pointer to the green channel of the first pixel.
3109  virtual void * getGData() const = 0;
3110  /// Get a pointer to the blue channel of the first pixel.
3111  virtual void * getBData() const = 0;
3112  /**
3113  * Get a pointer to the alpha channel of the first pixel
3114  * or null as alpha channel is optional.
3115  */
3116  virtual void * getAData() const = 0;
3117 
3118  /// Get the bit-depth.
3119  virtual BitDepth getBitDepth() const = 0;
3120 
3121  /// Get the width to process (where x position starts at 0 and ends at width-1).
3122  virtual long getWidth() const = 0;
3123  /// Get the height to process (where y position starts at 0 and ends at height-1).
3124  virtual long getHeight() const = 0;
3125 
3126  /// Get the step in bytes to find the same color channel of the next pixel.
3127  virtual ptrdiff_t getXStrideBytes() const = 0;
3128  /**
3129  * Get the step in bytes to find the same color channel
3130  * of the pixel at the same position in the next line.
3131  */
3132  virtual ptrdiff_t getYStrideBytes() const = 0;
3133 
3134  /**
3135  * Is the image buffer in packed mode with the 4 color channels?
3136  * ("Packed" here means that XStrideBytes is 4x the bytes per channel, so it is more specific
3137  * than simply any PackedImageDesc.)
3138  */
3139  virtual bool isRGBAPacked() const = 0;
3140  /// Is the image buffer 32-bit float?
3141  virtual bool isFloat() const = 0;
3142 
3143 private:
3144  ImageDesc(const ImageDesc &);
3145  ImageDesc & operator= (const ImageDesc &);
3146 };
3147 
3148 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ImageDesc&);
3149 
3150 
3151 ///////////////////////////////////////////////////////////////////////////
3152 // PackedImageDesc
3153 
3154 /**
3155  * All the constructors expect a pointer to packed image data (such as
3156  * rgbrgbrgb or rgbargbargba) starting at the first color channel of
3157  * the first pixel to process (which does not need to be the first pixel
3158  * of the image). The number of channels must be greater than or equal to 3.
3159  * If a 4th channel is specified, it is assumed to be alpha
3160  * information. Channels > 4 will be ignored.
3161  *
3162  * \note
3163  * The methods assume the CPUProcessor bit-depth type for the data pointer.
3164  */
3166 {
3167 public:
3168 
3169  /**
3170  * \note
3171  * numChannels must be 3 (RGB) or 4 (RGBA).
3172  */
3173  PackedImageDesc(void * data,
3174  long width, long height,
3175  long numChannels);
3176 
3177  /**
3178  * \note
3179  * numChannels must be 3 (RGB) or 4 (RGBA).
3180  */
3181  PackedImageDesc(void * data,
3182  long width, long height,
3183  long numChannels,
3184  BitDepth bitDepth,
3185  ptrdiff_t chanStrideBytes,
3186  ptrdiff_t xStrideBytes,
3187  ptrdiff_t yStrideBytes);
3188 
3189  PackedImageDesc(void * data,
3190  long width, long height,
3191  ChannelOrdering chanOrder);
3192 
3193  PackedImageDesc(void * data,
3194  long width, long height,
3195  ChannelOrdering chanOrder,
3196  BitDepth bitDepth,
3197  ptrdiff_t chanStrideBytes,
3198  ptrdiff_t xStrideBytes,
3199  ptrdiff_t yStrideBytes);
3200 
3201  virtual ~PackedImageDesc();
3202 
3203  /// Get the channel ordering of all the pixels.
3204  ChannelOrdering getChannelOrder() const;
3205 
3206  /// Get the bit-depth.
3207  BitDepth getBitDepth() const override;
3208 
3209  /// Get a pointer to the first color channel of the first pixel.
3210  void * getData() const;
3211 
3212  void * getRData() const override;
3213  void * getGData() const override;
3214  void * getBData() const override;
3215  void * getAData() const override;
3216 
3217  long getWidth() const override;
3218  long getHeight() const override;
3219  long getNumChannels() const;
3220 
3221  ptrdiff_t getChanStrideBytes() const;
3222  ptrdiff_t getXStrideBytes() const override;
3223  ptrdiff_t getYStrideBytes() const override;
3224 
3225  bool isRGBAPacked() const override;
3226  bool isFloat() const override;
3227 
3228 private:
3229  struct Impl;
3230  Impl * m_impl;
3231  Impl * getImpl() { return m_impl; }
3232  const Impl * getImpl() const { return m_impl; }
3233 
3234  PackedImageDesc();
3237 };
3238 
3239 
3240 ///////////////////////////////////////////////////////////////////////////
3241 // PlanarImageDesc
3242 
3243 /**
3244  * All the constructors expect pointers to the specified image planes
3245  * (i.e. rrrr gggg bbbb) starting at the first color channel of the
3246  * first pixel to process (which need not be the first pixel of the image).
3247  * Pass NULL for aData if no alpha exists (r/g/bData must not be NULL).
3248  *
3249  * \note
3250  * The methods assume the CPUProcessor bit-depth type for the R/G/B/A data pointers.
3251  */
3253 {
3254 public:
3255 
3256  PlanarImageDesc(void * rData, void * gData, void * bData, void * aData,
3257  long width, long height);
3258 
3259  /**
3260  *
3261  * Note that although PlanarImageDesc is powerful enough to also describe
3262  * all PackedImageDesc scenarios, it is recommended to use
3263  * a PackedImageDesc where possible since that allows for additional
3264  * optimizations.
3265  */
3266  PlanarImageDesc(void * rData, void * gData, void * bData, void * aData,
3267  long width, long height,
3268  BitDepth bitDepth,
3269  ptrdiff_t xStrideBytes,
3270  ptrdiff_t yStrideBytes);
3271 
3272  virtual ~PlanarImageDesc();
3273 
3274  void * getRData() const override;
3275  void * getGData() const override;
3276  void * getBData() const override;
3277  void * getAData() const override;
3278 
3279  /// Get the bit-depth.
3280  BitDepth getBitDepth() const override;
3281 
3282  long getWidth() const override;
3283  long getHeight() const override;
3284 
3285  ptrdiff_t getXStrideBytes() const override;
3286  ptrdiff_t getYStrideBytes() const override;
3287 
3288  bool isRGBAPacked() const override;
3289  bool isFloat() const override;
3290 
3291 private:
3292  struct Impl;
3293  Impl * m_impl;
3294  Impl * getImpl() { return m_impl; }
3295  const Impl * getImpl() const { return m_impl; }
3296 
3297  PlanarImageDesc();
3300 };
3301 
3302 
3303 ///////////////////////////////////////////////////////////////////////////
3304 // GpuShaderCreator
3305 /**
3306  * Inherit from the class to fully customize the implementation of a GPU shader program
3307  * from a color transformation.
3308  *
3309  * When no customizations are needed and the intermediate in-memory step is acceptable then the
3310  * \ref GpuShaderDesc is a better choice.
3311  *
3312  * \note
3313  * To better decouple the \ref DynamicProperties from their GPU implementation, the code provides
3314  * several addUniform() methods i.e. one per access function types. For example, an
3315  * \ref ExposureContrastTransform instance owns three \ref DynamicProperties and they are all
3316  * implemented by a double. When creating the GPU fragment shader program, the addUniform() with
3317  * GpuShaderCreator::DoubleGetter is called when property is dynamic, up to three times.
3318  *
3319  * **An OCIO shader program could contain:**
3320  *
3321  * * A declaration part e.g., uniform sampled3D tex3;
3322  *
3323  * * Some helper methods
3324  *
3325  * * The OCIO shader function may be broken down as:
3326  *
3327  * * The function header e.g., void OCIODisplay(in vec4 inColor) {
3328  * * The function body e.g., vec4 outColor.rgb = texture3D(tex3, inColor.rgb).rgb;
3329  * * The function footer e.g., return outColor; }
3330  *
3331  *
3332  * **Usage Example:**
3333  *
3334  * Below is a code snippet to highlight the different parts of the OCIO shader program.
3335  *
3336  * \code{.cpp}
3337  *
3338  * // All global declarations
3339  * uniform sampled3D tex3;
3340  *
3341  * // All helper methods
3342  * vec3 computePosition(vec3 color)
3343  * {
3344  * vec3 coords = color;
3345  * // Some processing...
3346  * return coords;
3347  * }
3348  *
3349  * // The shader function
3350  * vec4 OCIODisplay(in vec4 inColor) //
3351  * { // Function Header
3352  * vec4 outColor = inColor; //
3353  *
3354  * outColor.rgb = texture3D(tex3, computePosition(inColor.rgb)).rgb;
3355  *
3356  * return outColor; // Function Footer
3357  * } //
3358  *
3359  * \endcode
3360  */
3362 {
3363 public:
3364 
3365  virtual GpuShaderCreatorRcPtr clone() const = 0;
3366 
3367  const char * getUniqueID() const noexcept;
3368  void setUniqueID(const char * uid) noexcept;
3369 
3370  GpuLanguage getLanguage() const noexcept;
3371  /// Set the shader program language.
3372  void setLanguage(GpuLanguage lang) noexcept;
3373 
3374  const char * getFunctionName() const noexcept;
3375  // Set the function name of the shader program.
3376  void setFunctionName(const char * name) noexcept;
3377 
3378  const char * getPixelName() const noexcept;
3379  /// Set the pixel name variable holding the color values.
3380  void setPixelName(const char * name) noexcept;
3381 
3382  /**
3383  *
3384  * \note
3385  * Some applications require that textures, uniforms,
3386  * and helper methods be uniquely named because several
3387  * processor instances could coexist.
3388  */
3389  const char * getResourcePrefix() const noexcept;
3390  /// Set a prefix to the resource name
3391  void setResourcePrefix(const char * prefix) noexcept;
3392 
3393  /**
3394  * \brief Set the descriptor set index and texture binding start index to use for the shader program.
3395  *
3396  * \note Only supported for shading languages, such as Vulkan, that use descriptor sets and texture bindings.
3397  *
3398  * \param index The descriptor set index to use.
3399  * \param textureBindingStart The texture binding start index to use. The default index starts at 1
3400  * and is incremented by 1 for each texture. Otherwise, the texture binding starts
3401  * at textureBindingStart and is incremented by 1 for each texture.
3402  * The binding of a texture is equal to the texture index + textureBindingStart.
3403  * The texture binding start index must be greater than 0, as binding 0 is reserved
3404  * for the uniform buffer binding
3405  * */
3406  void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 1);
3407  unsigned getDescriptorSetIndex() const noexcept;
3408  unsigned getTextureBindingStart() const noexcept;
3409 
3410  virtual const char * getCacheID() const noexcept;
3411 
3412  /// Start to collect the shader data.
3413  virtual void begin(const char * uid);
3414  /// End to collect the shader data.
3415  virtual void end();
3416 
3417  /// Some graphic cards could have 1D & 2D textures with size limitations.
3418  virtual void setTextureMaxWidth(unsigned maxWidth) = 0;
3419  virtual unsigned getTextureMaxWidth() const noexcept = 0;
3420 
3421  /// Allow 1D GPU resource type, otherwise always using 2D resources for 1D LUTs.
3422  virtual void setAllowTexture1D(bool allowed) = 0;
3423  virtual bool getAllowTexture1D() const = 0;
3424 
3425  /**
3426  * To avoid global texture sampler and uniform name clashes always append an increasing index
3427  * to the resource name.
3428  */
3429  unsigned getNextResourceIndex() noexcept;
3430 
3431  /// Function returning a double, used by uniforms. GPU converts double to float.
3432  typedef std::function<double()> DoubleGetter;
3433  /// Function returning a bool, used by uniforms.
3434  typedef std::function<bool()> BoolGetter;
3435  /// Functions returning a Float3, used by uniforms.
3436  typedef std::function<const Float3 &()> Float3Getter;
3437  /// Function returning an int, used by uniforms.
3438  typedef std::function<int()> SizeGetter;
3439  /// Function returning a float *, used by uniforms.
3440  typedef std::function<const float *()> VectorFloatGetter;
3441  /// Function returning an int *, used by uniforms.
3442  typedef std::function<const int *()> VectorIntGetter;
3443 
3444  virtual bool addUniform(const char * name,
3445  const DoubleGetter & getDouble) = 0;
3446 
3447  virtual bool addUniform(const char * name,
3448  const BoolGetter & getBool) = 0;
3449 
3450  virtual bool addUniform(const char * name,
3451  const Float3Getter & getFloat3) = 0;
3452 
3453  /// The size of the vector can be smaller than the size of the corresponding
3454  /// array that is declared in the shader. The parameter maxSize must be used
3455  /// to pass the size of the array declared in the shader. This is important for
3456  /// being able to calculate the correct uniform buffer offset for subsequent uniforms
3457  virtual bool addUniform(const char * name,
3458  const SizeGetter & getSize,
3459  const VectorFloatGetter & getVectorFloat,
3460  const unsigned maxSize) = 0;
3461 
3462  /// The size of the vector can be smaller than the size of the corresponding
3463  /// array that is declared in the shader. The parameter maxSize must be used
3464  /// to pass the size of the array declared in the shader. This is important for
3465  /// being able to calculate the correct uniform buffer offset for subsequent uniforms
3466  virtual bool addUniform(const char * name,
3467  const SizeGetter & getSize,
3468  const VectorIntGetter & getVectorInt,
3469  const unsigned maxSize) = 0;
3470 
3471  /// Adds the property (used internally).
3472  void addDynamicProperty(DynamicPropertyRcPtr & prop);
3473 
3474  /// Dynamic Property related methods.
3475  unsigned getNumDynamicProperties() const noexcept;
3476  DynamicPropertyRcPtr getDynamicProperty(unsigned index) const;
3477 
3478  bool hasDynamicProperty(DynamicPropertyType type) const;
3479  /**
3480  * Dynamic properties allow changes once the fragment shader program has been created. The
3481  * steps are to get the appropriate DynamicProperty instance, and then change its value.
3482  */
3483  DynamicPropertyRcPtr getDynamicProperty(DynamicPropertyType type) const;
3484 
3486  {
3487  TEXTURE_RED_CHANNEL, ///< Only need a red channel texture
3488  TEXTURE_RGB_CHANNEL ///< Need a RGB texture
3489  };
3490 
3491  /**
3492  * Dimension enum used to differentiate between 1D and 2D object/resource types.
3493  */
3494  enum TextureDimensions : uint8_t {
3495  TEXTURE_1D = 1,
3496  TEXTURE_2D = 2,
3497  };
3498 
3499  /**
3500  * Add a 1D or 2D texture
3501  *
3502  * \note
3503  * The 'values' parameter contains the LUT data which must be used as-is as the dimensions and
3504  * origin are hard-coded in the fragment shader program. So, it means one GPU texture per entry.
3505  *
3506  * \return Index of the texture. For shading languages using explicit texture bindings, the return
3507  * value is the same as the texture binding index in the generated shader program.
3508  **/
3509  virtual unsigned addTexture(const char * textureName,
3510  const char * samplerName,
3511  unsigned width, unsigned height,
3512  TextureType channel,
3513  TextureDimensions dimensions,
3514  Interpolation interpolation,
3515  const float * values) = 0;
3516 
3517  /**
3518  * Add a 3D texture with RGB channel type.
3519  *
3520  * \note
3521  * The 'values' parameter contains the 3D LUT data which must be used as-is as the dimension
3522  * and origin are hard-coded in the fragment shader program. So, it means one GPU 3D texture
3523  * per entry.
3524  *
3525  * \return Index of the texture. For shading languages using explicit texture bindings, the return
3526  * value is the same as the texture binding index in the generated shader program.
3527  **/
3528  virtual unsigned add3DTexture(const char * textureName,
3529  const char * samplerName,
3530  unsigned edgelen,
3531  Interpolation interpolation,
3532  const float * values) = 0;
3533 
3534  // Methods to specialize parts of a OCIO shader program
3535  virtual void addToParameterDeclareShaderCode(const char * shaderCode);
3536  virtual void addToTextureDeclareShaderCode(const char* shaderCode);
3537  virtual void addToHelperShaderCode(const char * shaderCode);
3538  virtual void addToFunctionHeaderShaderCode(const char * shaderCode);
3539  virtual void addToFunctionShaderCode(const char * shaderCode);
3540  virtual void addToFunctionFooterShaderCode(const char * shaderCode);
3541 
3542  /**
3543  * \brief Create the OCIO shader program
3544  *
3545  * \note
3546  * The OCIO shader program is decomposed to allow a specific implementation
3547  * to change some parts. Some product integrations add the color processing
3548  * within a client shader program, imposing constraints requiring this flexibility.
3549  */
3550  virtual void createShaderText(const char * shaderParameterDeclarations,
3551  const char * shaderTextureDeclarations,
3552  const char * shaderHelperMethods,
3553  const char * shaderFunctionHeader,
3554  const char * shaderFunctionBody,
3555  const char * shaderFunctionFooter);
3556 
3557  virtual void finalize();
3558 
3559  GpuShaderCreator(const GpuShaderCreator &) = delete;
3560  GpuShaderCreator & operator= (const GpuShaderCreator &) = delete;
3561  /// Do not use (needed only for pybind11).
3562  virtual ~GpuShaderCreator();
3563 
3564 protected:
3565  GpuShaderCreator();
3566 
3567  class Impl;
3568  Impl * m_impl;
3569  Impl * getImpl() { return m_impl; }
3570  const Impl * getImpl() const { return m_impl; }
3571 };
3572 
3573 // GpuShaderDesc
3574 /**
3575  * \brief This class holds the GPU-related information needed to build a shader program
3576  * from a specific processor.
3577  *
3578  * This class defines the interface and there are two implementations provided.
3579  * The "legacy" mode implements the OCIO v1 approach of baking certain ops
3580  * in order to have at most one 3D-LUT. The "generic" mode is the v2 default and
3581  * allows all the ops to be processed as-is, without baking, like the CPU renderer.
3582  * Custom implementations could be written to accommodate the GPU needs of a
3583  * specific client app.
3584  *
3585  *
3586  * The complete fragment shader program is decomposed in two main parts:
3587  * the OCIO shader program for the color processing and the client shader
3588  * program which consumes the pixel color processing.
3589  *
3590  * The OCIO shader program is fully described by the GpuShaderDesc
3591  * independently from the client shader program. The only critical
3592  * point is the agreement on the OCIO function shader name.
3593  *
3594  * To summarize, the complete shader program is:
3595  *
3596  * \code{.cpp}
3597  *
3598  * ////////////////////////////////////////////////////////////////////////
3599  * // //
3600  * // The complete fragment shader program //
3601  * // //
3602  * ////////////////////////////////////////////////////////////////////////
3603  * // //
3604  * // ////////////////////////////////////////////////////////////// //
3605  * // // // //
3606  * // // The OCIO shader program // //
3607  * // // // //
3608  * // ////////////////////////////////////////////////////////////// //
3609  * // // // //
3610  * // // // All global declarations // //
3611  * // // uniform sampled3D tex3; // //
3612  * // // // //
3613  * // // // All helper methods // //
3614  * // // vec3 computePos(vec3 color) // //
3615  * // // { // //
3616  * // // vec3 coords = color; // //
3617  * // // ... // //
3618  * // // return coords; // //
3619  * // // } // //
3620  * // // // //
3621  * // // // The OCIO shader function // //
3622  * // // vec4 OCIODisplay(in vec4 inColor) // //
3623  * // // { // //
3624  * // // vec4 outColor = inColor; // //
3625  * // // ... // //
3626  * // // outColor.rbg // //
3627  * // // = texture3D(tex3, computePos(inColor.rgb)).rgb; // //
3628  * // // ... // //
3629  * // // return outColor; // //
3630  * // // } // //
3631  * // // // //
3632  * // ////////////////////////////////////////////////////////////// //
3633  * // //
3634  * // ////////////////////////////////////////////////////////////// //
3635  * // // // //
3636  * // // The client shader program // //
3637  * // // // //
3638  * // ////////////////////////////////////////////////////////////// //
3639  * // // // //
3640  * // // uniform sampler2D image; // //
3641  * // // // //
3642  * // // void main() // //
3643  * // // { // //
3644  * // // vec4 inColor = texture2D(image, gl_TexCoord[0].st); // //
3645  * // // ... // //
3646  * // // vec4 outColor = OCIODisplay(inColor); // //
3647  * // // ... // //
3648  * // // gl_FragColor = outColor; // //
3649  * // // } // //
3650  * // // // //
3651  * // ////////////////////////////////////////////////////////////// //
3652  * // //
3653  * ////////////////////////////////////////////////////////////////////////
3654  * \endcode
3655  *
3656  * **Usage Example:** *Building a GPU shader*
3657  *
3658  * This example is based on the code in: src/apps/ociodisplay/main.cpp
3659  *
3660  * \code{.cpp}
3661  *
3662  * // Get the processor
3663  * //
3664  * OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromEnv();
3665  * OCIO::ConstProcessorRcPtr processor
3666  * = config->getProcessor("ACES - ACEScg", "Output - sRGB");
3667  *
3668  * // Step 1: Create a GPU shader description
3669  * //
3670  * // The two potential scenarios are:
3671  * //
3672  * // 1. Instantiate the generic shader description. The color processor
3673  * // is used as-is (i.e. without any baking step) and could contain
3674  * // any number of 1D & 3D luts.
3675  * //
3676  * // This is the default OCIO v2 behavior and allows a much better
3677  * // match between the CPU and GPU renderers.
3678  * //
3679  * OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::Create();
3680  * //
3681  * // 2. Instantiate a custom shader description.
3682  * //
3683  * // Writing a custom shader description is a way to tailor the shaders
3684  * // to the needs of a given client program. This involves writing a
3685  * // new class inheriting from the pure virtual class GpuShaderDesc.
3686  * //
3687  * // Please refer to the GenericGpuShaderDesc class for an example.
3688  * //
3689  * OCIO::GpuShaderDescRcPtr shaderDesc = MyCustomGpuShader::Create();
3690  *
3691  * shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2);
3692  * shaderDesc->setFunctionName("OCIODisplay");
3693  *
3694  * // Step 2: Collect the shader program information for a specific processor
3695  * //
3696  * processor->extractGpuShaderInfo(shaderDesc);
3697  *
3698  * // Step 3: Create a helper to build the shader. Here we use a helper for
3699  * // OpenGL but there will also be helpers for other languages.
3700  * //
3701  * OpenGLBuilderRcPtr oglBuilder = OpenGLBuilder::Create(shaderDesc);
3702  *
3703  * // Step 4: Allocate & upload all the LUTs
3704  * //
3705  * oglBuilder->allocateAllTextures();
3706  *
3707  * // Step 5: Build the complete fragment shader program using
3708  * // g_fragShaderText which is the client shader program.
3709  * //
3710  * g_programId = oglBuilder->buildProgram(g_fragShaderText);
3711  *
3712  * // Step 6: Enable the fragment shader program, and all needed textures
3713  * //
3714  * glUseProgram(g_programId);
3715  * glUniform1i(glGetUniformLocation(g_programId, "tex1"), 1); // image texture
3716  * oglBuilder->useAllTextures(g_programId); // LUT textures
3717  *
3718  * // Step 7: Update uniforms from dynamic property instances.
3719  * m_oglBuilder->useAllUniforms();
3720  * \endcode
3721  *
3722  */
3724 {
3725 public:
3726 
3727  /// Create the default shader description.
3728  static GpuShaderDescRcPtr CreateShaderDesc();
3729 
3730  GpuShaderCreatorRcPtr clone() const override;
3731 
3732  /**
3733  * Used to retrieve uniform information. UniformData m_type indicates the type of uniform
3734  * and what member of the structure should be used:
3735  * * UNIFORM_DOUBLE: m_getDouble.
3736  * * UNIFORM_BOOL: m_getBool.
3737  * * UNIFORM_FLOAT3: m_getFloat3.
3738  * * UNIFORM_VECTOR_FLOAT: m_vectorFloat.
3739  * * UNIFORM_VECTOR_INT: m_vectorInt.
3740  *
3741  * The m_bufferOffset is the offset in bytes from the start of the uniform buffer.
3742  * For shading languages that use uniform buffers, the offset can be used to
3743  * determine the location of the uniform in the buffer and fill it with the
3744  * corresponding data.
3745  */
3747  {
3749  std::size_t m_bufferOffset{};
3750  DoubleGetter m_getDouble{};
3751  BoolGetter m_getBool{};
3752  Float3Getter m_getFloat3{};
3754  {
3755  SizeGetter m_getSize{};
3756  VectorFloatGetter m_getVector{};
3757  } m_vectorFloat{};
3758  struct VectorInt
3759  {
3760  SizeGetter m_getSize{};
3761  VectorIntGetter m_getVector{};
3762  } m_vectorInt{};
3763  };
3764  virtual unsigned getNumUniforms() const noexcept = 0;
3765  /// Returns name of uniform and data as parameter.
3766  virtual const char * getUniform(unsigned index, UniformData & data) const = 0;
3767 
3768  /**
3769  * For shading languages that use uniform buffers, a uniform buffer
3770  * containing all uniforms is generated in the shader code. This method can
3771  * be used to create a buffer of the same size in the client code that can
3772  * be filled with the corresponding data.
3773  *
3774  * \return Size of the uniform buffer in bytes
3775  **/
3776  virtual std::size_t getUniformBufferSize() const noexcept = 0;
3777 
3778  // 1D lut related methods
3779  virtual unsigned getNumTextures() const noexcept = 0;
3780  virtual void getTexture(unsigned index,
3781  const char *& textureName,
3782  const char *& samplerName,
3783  unsigned & width,
3784  unsigned & height,
3785  TextureType & channel,
3786  TextureDimensions & dimensions,
3787  Interpolation & interpolation) const = 0;
3788  virtual void getTextureValues(unsigned index, const float *& values) const = 0;
3789 
3790  // 3D lut related methods
3791  virtual unsigned getNum3DTextures() const noexcept = 0;
3792  virtual void get3DTexture(unsigned index,
3793  const char *& textureName,
3794  const char *& samplerName,
3795  unsigned & edgelen,
3796  Interpolation & interpolation) const = 0;
3797  virtual void get3DTextureValues(unsigned index, const float *& values) const = 0;
3798 
3799  /// Get the complete OCIO shader program.
3800  const char * getShaderText() const noexcept;
3801 
3802  GpuShaderDesc(const GpuShaderDesc &) = delete;
3803  GpuShaderDesc& operator= (const GpuShaderDesc &) = delete;
3804  /// Do not use (needed only for pybind11).
3805  virtual ~GpuShaderDesc();
3806 
3807 protected:
3808  GpuShaderDesc();
3809 };
3810 
3811 
3812 /**
3813  * Context
3814  *
3815  * A context defines some overrides to a Config. For example, it can override the
3816  * search path or change the value of a context variable.
3817  *
3818  * \note
3819  * Only some \ref Config::getProcessor methods accept a custom context; otherwise,
3820  * the default context instance is used (see \ref Config::getCurrentContext).
3821  *
3822  * Context Variables
3823  *
3824  * The context variables allow changes at runtime using environment variables. For example,
3825  * a color space name (such as src & dst for the ColorSpaceTransform) or a file
3826  * name (such as LUT file name for the FileTransform) could be defined by context
3827  * variables. The color transformation is then customized based on some environment variables.
3828  *
3829  * In a config the context variables support three syntaxes (i.e. ${VAR}, $VAR and %VAR%) and
3830  * the parsing starts from longest to shortest. So, the resolve works like '$TEST_$TESTING_$TE'
3831  * expands in this order '2 1 3'.
3832  *
3833  * Config authors are recommended to include the "environment" section in their configs. This
3834  * improves performance as well as making the config more readable. When present, this section
3835  * must declare all context variables used in the config. It may also provide a default value,
3836  * in case the variable is not present in the user's environment.
3837  *
3838  * A context variable may only be used in the following places:
3839  * * the \ref `ColorSpaceTransform` to define the source and the destination color space names,
3840  * * the \ref `FileTransform` to define the source file name (e.g. a LUT file name),
3841  * * the search_path,
3842  * * the cccid of the \ref `FileTransform` to only extract one specific transform from
3843  * the CDL & CCC files.
3844  *
3845  * Some specific restrictions are worth calling out:
3846  * * they cannot be used as either the name or value of a role,
3847  * * the context variable characters $ and % are prohibited in a color space name.
3848  */
3850 {
3851 public:
3852  static ContextRcPtr Create();
3853 
3854  ContextRcPtr createEditableCopy() const;
3855 
3856  const char * getCacheID() const;
3857 
3858  void setSearchPath(const char * path);
3859  const char * getSearchPath() const;
3860 
3861  int getNumSearchPaths() const;
3862  const char * getSearchPath(int index) const;
3863  void clearSearchPaths();
3864  void addSearchPath(const char * path);
3865  void setWorkingDir(const char * dirname);
3866  const char * getWorkingDir() const;
3867 
3868  /// Add (or update) a context variable. But it removes it if the value argument is null.
3869  /// Note that a Context StringVar is the same thing as a Config EnvironmentVar and these
3870  /// are both often referred to as a "context var".
3871  void setStringVar(const char * name, const char * value) noexcept;
3872  /// Get the context variable value. It returns an empty string if the context
3873  /// variable is null or does not exist.
3874  const char * getStringVar(const char * name) const noexcept;
3875 
3876  int getNumStringVars() const;
3877  const char * getStringVarNameByIndex(int index) const;
3878 
3879  const char * getStringVarByIndex(int index) const;
3880 
3881  void clearStringVars();
3882 
3883  /// Add to the instance all the context variables from ctx.
3884  void addStringVars(const ConstContextRcPtr & ctx) noexcept;
3885 
3886  /// See \ref Config::setEnvironmentMode.
3887  void setEnvironmentMode(EnvironmentMode mode) noexcept;
3888  EnvironmentMode getEnvironmentMode() const noexcept;
3889 
3890  /// Seed string vars with the current environment, based on the EnvironmentMode setting.
3891  void loadEnvironment() noexcept;
3892 
3893  /// Resolve all the context variables from the string. It could be color space
3894  /// names or file names. Note that it recursively applies the context variable resolution.
3895  /// Returns the string unchanged if it does not contain any context variable.
3896  const char * resolveStringVar(const char * string) const noexcept;
3897  /// Resolve all the context variables from the string and return all the context
3898  /// variables used to resolve the string (empty if no context variables were used).
3899  const char * resolveStringVar(const char * string, ContextRcPtr & usedContextVars) const noexcept;
3900 
3901  /**
3902  * Build the resolved and expanded filepath using the search_path when needed,
3903  * and check if the filepath exists. If it cannot be resolved or found, an exception will be
3904  * thrown. The method argument is directly from the config file so it can be an absolute or
3905  * relative file path or a file name.
3906  *
3907  * \note The filepath existence check could add a performance hit.
3908  *
3909  * \note The context variable resolution is performed using :cpp:func:`resolveStringVar`.
3910  */
3911  const char * resolveFileLocation(const char * filename) const;
3912  /// Build the resolved and expanded filepath and return all the context variables
3913  /// used to resolve the filename (empty if no context variables were used).
3914  const char * resolveFileLocation(const char * filename, ContextRcPtr & usedContextVars) const;
3915 
3916  /// Set the ConfigIOProxy object used to provision the config and LUTs from somewhere other
3917  /// than the file system.
3918  void setConfigIOProxy(ConfigIOProxyRcPtr ciop);
3919  ConfigIOProxyRcPtr getConfigIOProxy() const;
3920 
3921  Context(const Context &) = delete;
3922  Context& operator= (const Context &) = delete;
3923  /// Do not use (needed only for pybind11).
3924  ~Context();
3925 
3926 private:
3927  Context();
3928 
3929  static void deleter(Context* c);
3930 
3931  class Impl;
3932  Impl * m_impl;
3933  Impl * getImpl() { return m_impl; }
3934  const Impl * getImpl() const { return m_impl; }
3935 };
3936 
3937 extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Context&);
3938 
3939 
3940 ///////////////////////////////////////////////////////////////////////////
3941 // BuiltinTransformRegistry
3942 
3943 /**
3944  * The built-in transform registry contains all the existing built-in transforms which can
3945  * be used by a configuration (version 2 or higher only).
3946  */
3948 {
3949 public:
3952 
3953  /// Get the current built-in transform registry.
3954  static ConstBuiltinTransformRegistryRcPtr Get() noexcept;
3955 
3956  /// Get the number of built-in transforms available.
3957  virtual size_t getNumBuiltins() const noexcept = 0;
3958  /**
3959  * Get the style string for the i-th built-in transform.
3960  * The style is the ID string that identifies a given transform.
3961  */
3962  virtual const char * getBuiltinStyle(size_t index) const = 0;
3963  /// Get the description string for the i-th built-in transform.
3964  virtual const char * getBuiltinDescription(size_t index) const = 0;
3965 
3966 protected:
3967  BuiltinTransformRegistry() = default;
3968  virtual ~BuiltinTransformRegistry() = default;
3969 };
3970 
3971 ///////////////////////////////////////////////////////////////////////////
3972 // BuiltinConfigRegistry
3973 
3974 /**
3975  * The built-in configs registry contains information about all the existing built-in configs.
3976  */
3978 {
3979 public:
3980  BuiltinConfigRegistry(const BuiltinConfigRegistry &) = delete;
3982 
3983  /// Get the current built-in configs registry.
3984  static const BuiltinConfigRegistry & Get() noexcept;
3985 
3986  /// Get the number of built-in configs available.
3987  virtual size_t getNumBuiltinConfigs() const noexcept = 0;
3988 
3989  /// Get the name of the config at the specified (zero-based) index.
3990  /// Throws for illegal index.
3991  virtual const char * getBuiltinConfigName(size_t configIndex) const = 0;
3992 
3993  // Get a user-friendly name for a built-in config, appropriate for displaying in a user interface.
3994  /// Throws for illegal index.
3995  virtual const char * getBuiltinConfigUIName(size_t configIndex) const = 0;
3996 
3997  /// Get Yaml text of the built-in config at the specified index.
3998  /// Throws for illegal index.
3999  virtual const char * getBuiltinConfig(size_t configIndex) const = 0;
4000 
4001  /// Get the Yaml text of the built-in config with the specified name.
4002  /// Throws if the name is not found.
4003  virtual const char * getBuiltinConfigByName(const char * configName) const = 0;
4004 
4005  /**
4006  * @brief Check if a specific built-in config is recommended.
4007  *
4008  * For backwards compatibility reasons, configs will remain in the registry even if they have
4009  * been superseded. If an app is presenting a list of configs to users, it should not include
4010  * configs that are no longer recommended.
4011  *
4012  * Throws if the name is not found.
4013  *
4014  * @param configIndex Index of built-in config.
4015  * @return true if the config is recommended.
4016  */
4017  virtual bool isBuiltinConfigRecommended(size_t configIndex) const = 0;
4018 
4019 protected:
4020  BuiltinConfigRegistry() = default;
4021  virtual ~BuiltinConfigRegistry() = default;
4022 };
4023 
4024 
4025 ///////////////////////////////////////////////////////////////////////////
4026 // SystemMonitors
4027 
4028 /**
4029  * Provides access to the ICC monitor profile provided by the operating system for each active display.
4030  */
4032 {
4033 public:
4034  SystemMonitors(const SystemMonitors &) = delete;
4035  SystemMonitors & operator= (const SystemMonitors &) = delete;
4036 
4037  /// Get the existing instance.
4038  static ConstSystemMonitorsRcPtr Get() noexcept;
4039 
4040  /**
4041  * True if the OS is able to provide ICC profiles for the attached monitors (macOS, Windows)
4042  * and false otherwise.
4043  */
4044  virtual bool isSupported() const noexcept = 0;
4045 
4046  /**
4047  * Methods to access some information of the attached and active monitors.
4048  */
4049 
4050  /// Get the number of active monitors reported by the operating system.
4051  virtual size_t getNumMonitors() const noexcept = 0;
4052 
4053  /**
4054  * \brief Get the monitor profile name.
4055  *
4056  * Get the string describing the monitor. It is used as an argument to instantiateDisplay. It
4057  * may also be used in a UI to ask a user which of several monitors they want to instantiate a
4058  * display for.
4059  */
4060  virtual const char * getMonitorName(size_t idx) const = 0;
4061  /// Get the ICC profile path associated to the monitor.
4062  virtual const char * getProfileFilepath(size_t idx) const = 0;
4063 
4064 protected:
4065  SystemMonitors() = default;
4066  virtual ~SystemMonitors() = default;
4067 };
4068 
4069 
4070 ///////////////////////////////////////////////////////////////////////////
4071 // ConfigIOProxy
4072 
4073 /**
4074  * ConfigIOProxy is a proxy class to allow the calling program to supply the config and any
4075  * associated LUT files directly, without relying on the standard file system.
4076  *
4077  * The OCIOZ archive feature is implemented using this mechanism.
4078  */
4080 {
4081 public:
4082  ConfigIOProxy() = default;
4083  virtual ~ConfigIOProxy() = default;
4084 
4085  /**
4086  * \brief Provide the contents of a LUT file as a buffer of uint8_t data.
4087  *
4088  * \param filepath Fully resolved path to the "file."
4089  *
4090  * The file path is based on the Config's current working directory and is the same absolute
4091  * path that would have been provided to the file system.
4092  *
4093  * \return Vector of uint8 with the content of the LUT.
4094  */
4095  virtual std::vector<uint8_t> getLutData(const char * filepath) const = 0;
4096 
4097  /**
4098  * \brief Provide the config file Yaml to be parsed.
4099  *
4100  * \return String with the config Yaml.
4101  */
4102  virtual std::string getConfigData() const = 0;
4103 
4104  /**
4105  * \brief Provide a fast unique ID for a LUT file.
4106  *
4107  * This is intended to supply the string that will be used in OCIO's FileCacheMap.
4108  * This should be highly performant and typically should not require extensive
4109  * computation such as calculating the md5 hash of the file, unless it is pre-computed.
4110  *
4111  * If the "file" does not exist, in other words, if the proxy is unable to supply the requested
4112  * file contents, the function must return an empty string.
4113  *
4114  * \param filepath Fully resolve the path to the "file."
4115  *
4116  * The file path is based on the Config's current working directory and is the same absolute
4117  * path that would have been provided to the file system.
4118  *
4119  * \return The file hash string.
4120  */
4121  virtual std::string getFastLutFileHash(const char * filepath) const = 0;
4122 };
4123 
4124 } // namespace OCIO_NAMESPACE
4125 
4126 #endif // INCLUDED_OCIO_OPENCOLORIO_H
OCIOEXPORT ConstConfigRcPtr GetCurrentConfig()
Get the current configuration.
EnvironmentMode
Controls which environment variables are loaded into a Context object.
GLint first
Definition: glcorearb.h:405
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
OCIO_SHARED_PTR< const ViewTransform > ConstViewTransformRcPtr
GLbitfield flags
Definition: glcorearb.h:1596
static const char * DefaultRuleName
Reserved rule name for the default rule.
Definition: OpenColorIO.h:1731
class OCIOEXPORT GpuShaderDesc
PXL_API const char * getDescription(const ColorSpace *space)
Return the description of the color space.
GT_API const UT_StringHolder filename
OCIOEXPORT ConstColorSpaceSetRcPtr operator&&(const ConstColorSpaceSetRcPtr &lcss, const ConstColorSpaceSetRcPtr &rcss)
Perform the intersection of two sets.
bool isDefault(const cgltf_texture_view &tv)
PXL_API void getColorSpaces(UT_StringArray &names)
Returns a list of the supported color spaces.
This class holds the GPU-related information needed to build a shader program from a specific process...
Definition: OpenColorIO.h:3723
std::function< const float *()> VectorFloatGetter
Function returning a float *, used by uniforms.
Definition: OpenColorIO.h:3440
class OCIOEXPORT ColorSpaceSet
OCIOEXPORT void SetLoggingLevel(LoggingLevel level)
Set the global logging level.
OCIO_SHARED_PTR< ViewingRules > ViewingRulesRcPtr
OCIOEXPORT void SetComputeHashFunction(ComputeHashFunction hashFunction)
Set the Compute Hash Function to use; otherwise, use the default.
OCIO_SHARED_PTR< GpuShaderCreator > GpuShaderCreatorRcPtr
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
PXL_API void getActiveViews(UT_StringArray &names)
Returns the list of active views.
ChannelOrdering
Used by PackedImageDesc to indicate the channel ordering of the image to process. ...
This is a light-weight wrapper around an image, that provides a context for pixel access...
Definition: OpenColorIO.h:3100
OCIO_SHARED_PTR< Processor > ProcessorRcPtr
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
class OCIOEXPORT BuiltinTransformRegistry
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
OptimizationFlags
Provides control over how the ops in a Processor are combined in order to improve performance...
const Impl * getImpl() const
Definition: OpenColorIO.h:3570
class OCIOEXPORT ViewingRules
OCIO_SHARED_PTR< const Transform > ConstTransformRcPtr
GLint level
Definition: glcorearb.h:108
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:860
OCIO_SHARED_PTR< FileRules > FileRulesRcPtr
std::function< int()> SizeGetter
Function returning an int, used by uniforms.
Definition: OpenColorIO.h:3438
An exception class to throw for errors detected at runtime.
Definition: OpenColorIO.h:79
OCIO_SHARED_PTR< const BuiltinTransformRegistry > ConstBuiltinTransformRegistryRcPtr
OCIOEXPORT bool operator!=(const GradingRGBM &lhs, const GradingRGBM &rhs)
std::function< const Float3 &()> Float3Getter
Functions returning a Float3, used by uniforms.
Definition: OpenColorIO.h:3436
OCIO_SHARED_PTR< ConfigIOProxy > ConfigIOProxyRcPtr
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
class OCIOEXPORT Config
PXL_API const char * getDefaultView(const char *display=NULL)
Returns the current color space name.
#define OCIO_NAMESPACE
Definition: OpenColorABI.h:8
DynamicPropertyType
Types for dynamic properties.
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:2539
OCIOEXPORT void LogMessage(LoggingLevel level, const char *message)
Log a message using the library logging function.
class OCIOEXPORT Exception
class OCIOEXPORT Look
OCIOEXPORT int GetVersionHex()
Get the version number for the library, as a single 4-byte hex number (e.g., 0x01050200 for "1...
OCIO_SHARED_PTR< const NamedTransform > ConstNamedTransformRcPtr
static const char * FilePathSearchRuleName
Reserved rule name for the file path search rule.
Definition: OpenColorIO.h:1733
std::function< const int *()> VectorIntGetter
Function returning an int *, used by uniforms.
Definition: OpenColorIO.h:3442
OCIOEXPORT void ClearAllCaches()
GpuLanguage
Used when there is a choice of hardware shader language.
ProcessorCacheFlags
cpp:type:: Enum to control the behavior of the internal caches e.g. the processor cache in ...
OCIO_SHARED_PTR< Look > LookRcPtr
OCIO_SHARED_PTR< const ProcessorMetadata > ConstProcessorMetadataRcPtr
class OCIOEXPORT GpuShaderCreator
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
OCIO_SHARED_PTR< const Context > ConstContextRcPtr
class OCIOEXPORT Context
OCIOEXPORT ConstColorSpaceSetRcPtr operator||(const ConstColorSpaceSetRcPtr &lcss, const ConstColorSpaceSetRcPtr &rcss)
Perform the union of two sets.
class OCIOEXPORT CPUProcessor
OCIO_SHARED_PTR< ProcessorMetadata > ProcessorMetadataRcPtr
OCIO_SHARED_PTR< const CPUProcessor > ConstCPUProcessorRcPtr
OCIOEXPORT void SetLoggingFunction(LoggingFunction logFunction)
Set the logging function to use; otherwise, use the default (i.e. std::cerr).
OCIOEXPORT void ResetToDefaultLoggingFunction()
class OCIOEXPORT ViewTransform
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
class OCIOEXPORT ConfigIOProxy
OCIO_SHARED_PTR< Baker > BakerRcPtr
OCIOEXPORT const char * GetEnvVariable(const char *name)
class OCIOEXPORT ProcessorMetadata
GLuint GLuint end
Definition: glcorearb.h:475
A config defines all the color spaces to be available at runtime.
Definition: OpenColorIO.h:285
class OCIOEXPORT GPUProcessor
PXL_API bool getAllocationVars(const ColorSpace *space, bool &uniform, fpreal &min, fpreal &max, fpreal &offset)
Return the allocation variable meta data about the color space.
OPENVDB_API void setVersion(std::ios_base &, const VersionId &libraryVersion, uint32_t fileVersion)
Associate specific file format and library version numbers with the given stream. ...
std::function< void(const char *)> LoggingFunction
Define the logging function signature.
std::function< double()> DoubleGetter
Function returning a double, used by uniforms. GPU converts double to float.
Definition: OpenColorIO.h:3432
#define OCIOEXPORT
Definition: OpenColorABI.h:67
OCIOEXPORT void SetEnvVariable(const char *name, const char *value)
OCIO_SHARED_PTR< const Processor > ConstProcessorRcPtr
GLuint const GLchar * name
Definition: glcorearb.h:786
OCIO_SHARED_PTR< const ColorSpaceSet > ConstColorSpaceSetRcPtr
OCIO_SHARED_PTR< const FileRules > ConstFileRulesRcPtr
GLushort pattern
Definition: glad.h:2583
#define OCIO_DEPRECATED(msg)
Definition: OpenColorABI.h:38
PXL_API const char * getDefaultDisplay()
Returns the current color space name.
GA_API const UT_StringHolder transform
class OCIOEXPORT Baker
OCIOEXPORT void ResetComputeHashFunction()
PXL_API const char * parseColorSpaceFromString(const char *string)
OCIOEXPORT const char * GetVersion()
Get the version number for the library, as a dot-delimited string (e.g., "1.0.0").
UniformDataType
Types for uniform data.
GLenum mode
Definition: glcorearb.h:99
std::function< std::string(const std::string &)> ComputeHashFunction
Define Compute Hash function signature.
OCIO_SHARED_PTR< const SystemMonitors > ConstSystemMonitorsRcPtr
std::function< bool()> BoolGetter
Function returning a bool, used by uniforms.
Definition: OpenColorIO.h:3434
OCIO_SHARED_PTR< ColorSpaceSet > ColorSpaceSetRcPtr
OCIO_SHARED_PTR< const Config > ConstConfigRcPtr
OCIO_SHARED_PTR< NamedTransform > NamedTransformRcPtr
OCIO_SHARED_PTR< const Look > ConstLookRcPtr
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
class OCIOEXPORT Processor
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
OCIOEXPORT bool operator==(const GradingRGBM &lhs, const GradingRGBM &rhs)
class OCIOEXPORT ImageDesc
OCIO_SHARED_PTR< Config > ConfigRcPtr
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
class OCIOEXPORT NamedTransform
OCIO_SHARED_PTR< Context > ContextRcPtr
OCIOEXPORT void SetCurrentConfig(const ConstConfigRcPtr &config)
Set the current configuration. This will then store a copy of the specified config.
OCIOEXPORT void ExtractOCIOZArchive(const char *archivePath, const char *destinationDir)
Extract an OCIO Config archive.
GLint GLsizei width
Definition: glcorearb.h:103
OCIOEXPORT std::ostream & operator<<(std::ostream &, const ColorSpaceMenuParameters &)
OCIO_SHARED_PTR< GpuShaderDesc > GpuShaderDescRcPtr
class OCIOEXPORT FileRules
OCIOEXPORT void UnsetEnvVariable(const char *name)
OCIOEXPORT bool IsEnvVariablePresent(const char *name)
cpp:function::
class OCIOEXPORT SystemMonitors
OCIO_SHARED_PTR< GroupTransform > GroupTransformRcPtr
class OCIOEXPORT ColorSpace
PXL_API void getLooks(UT_StringArray &looks)
Returns a list of looks (color transforms)
const ptrdiff_t AutoStride
Definition: OpenColorIO.h:3092
OCIO_SHARED_PTR< const ViewingRules > ConstViewingRulesRcPtr
PXL_API void getActiveDisplays(UT_StringArray &names)
Returns the list of active displays.
OCIO_SHARED_PTR< ColorSpace > ColorSpaceRcPtr
OCIOEXPORT const char * ResolveConfigPath(const char *originalPath) noexcept
Make a config path forward-compatible by replacing special built-in config names with the current nam...
OCIOEXPORT LoggingLevel GetLoggingLevel()
Get the global logging level.
An exception class for errors detected at runtime.
Definition: OpenColorIO.h:99
This class contains meta information about the process that generated this processor. The results of these functions do not impact the pixel processing.
Definition: OpenColorIO.h:2924
OCIO_SHARED_PTR< const ColorSpace > ConstColorSpaceRcPtr
OCIOEXPORT ConstColorSpaceSetRcPtr operator-(const ConstColorSpaceSetRcPtr &lcss, const ConstColorSpaceSetRcPtr &rcss)
Perform the difference of two sets.
OIIO_UTIL_API std::string extension(string_view filepath, bool include_dot=true) noexcept
OCIO_SHARED_PTR< const GPUProcessor > ConstGPUProcessorRcPtr
Definition: format.h:1821
The File Rules are a set of filepath to color space mappings that are evaluated from first to last...
Definition: OpenColorIO.h:1726
OCIO_SHARED_PTR< ViewTransform > ViewTransformRcPtr
OCIO_SHARED_PTR< DynamicProperty > DynamicPropertyRcPtr