HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
color.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 #pragma once
6 
7 #include <memory>
8 
9 #include <OpenImageIO/export.h>
10 #include <OpenImageIO/fmath.h>
11 #include <OpenImageIO/imageio.h>
12 #include <OpenImageIO/typedesc.h>
13 #include <OpenImageIO/ustring.h>
14 
15 
17 
18 /// The ColorProcessor encapsulates a baked color transformation, suitable for
19 /// application to raw pixels, or ImageBuf(s). These are generated using
20 /// ColorConfig::createColorProcessor, and referenced in ImageBufAlgo
21 /// (amongst other places)
23 public:
25  virtual ~ColorProcessor(void) {};
26  virtual bool isNoOp() const { return false; }
27  virtual bool hasChannelCrosstalk() const { return false; }
28 
29  // Convert an array/image of color values. The strides are the distance,
30  // in bytes, between subsequent color channels, pixels, and scanlines.
31  virtual void apply(float* data, int width, int height, int channels,
32  stride_t chanstride, stride_t xstride,
33  stride_t ystride) const
34  = 0;
35  // Convert a single 3-color
36  void apply(float* data)
37  {
38  apply((float*)data, 1, 1, 3, sizeof(float), 3 * sizeof(float),
39  3 * sizeof(float));
40  }
41 };
42 
43 // Preprocessor symbol to allow conditional compilation depending on
44 // whether the ColorProcessor class is exposed (it was not prior to OIIO 1.9).
45 #define OIIO_HAS_COLORPROCESSOR 1
46 
47 
48 
49 typedef std::shared_ptr<ColorProcessor> ColorProcessorHandle;
50 
51 // Preprocessor symbol to allow conditional compilation depending on
52 // whether the ColorConfig returns ColorProcessor shared pointers or raw.
53 #define OIIO_COLORCONFIG_USES_SHARED_PTR 1
54 
55 
56 
57 /// Represents the set of all color transformations that are allowed.
58 /// If OpenColorIO is enabled at build time, this configuration is loaded
59 /// at runtime, allowing the user to have complete control of all color
60 /// transformation math. ($OCIO) (See opencolorio.org for details).
61 /// If OpenColorIO is not enabled at build time, a generic color configuration
62 /// is provided for minimal color support.
63 ///
64 /// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight.
65 /// Their construction / destruction should be kept to a minimum.
66 
68 public:
69  /// Construct a ColorConfig using the named OCIO configuration file,
70  /// or if filename is empty, to the current color configuration
71  /// specified by env variable $OCIO.
72  ///
73  /// Multiple calls to this are potentially expensive. A ColorConfig
74  /// should usually be shared by an app for its entire runtime.
76 
77  ~ColorConfig();
78 
79  /// Reset the config to the named OCIO configuration file, or if
80  /// filename is empty, to the current color configuration specified
81  /// by env variable $OCIO. Return true for success, false if there
82  /// was an error.
83  ///
84  /// Multiple calls to this are potentially expensive. A ColorConfig
85  /// should usually be shared by an app for its entire runtime.
86  bool reset(string_view filename = "");
87 
88  /// Has an error string occurred?
89  /// (This will not affect the error state.)
90  bool has_error() const;
91 
92  /// DEPRECATED(2.4), old name for has_error().
93  bool error() const;
94 
95  /// This routine will return the error string (and by default, clear any
96  /// error flags). If no error has occurred since the last time
97  /// geterror() was called, it will return an empty string.
98  std::string geterror(bool clear = true) const;
99 
100  /// Get the number of ColorSpace(s) defined in this configuration
101  int getNumColorSpaces() const;
102 
103  /// Query the name of the specified ColorSpace.
104  const char* getColorSpaceNameByIndex(int index) const;
105 
106  /// Given a color space name, return the index of an equivalent color
107  /// space, or -1 if not found. It will first look for an exact match of
108  /// the name, but if not found, will match a color space that is
109  /// "equivalent" to the named color space.
110  int getColorSpaceIndex(string_view name) const;
111 
112  /// Get the name of the color space representing the named role,
113  /// or NULL if none could be identified.
114  const char* getColorSpaceNameByRole(string_view role) const;
115 
116  /// Get the data type that OCIO thinks this color space is. The name
117  /// may be either a color space name or a role.
118  OIIO::TypeDesc getColorSpaceDataType(string_view name, int* bits) const;
119 
120  /// Retrieve the full list of known color space names, as a vector
121  /// of strings.
122  std::vector<std::string> getColorSpaceNames() const;
123 
124  /// Get the name of the color space family of the named color space,
125  /// or NULL if none could be identified.
126  const char* getColorSpaceFamilyByName(string_view name) const;
127 
128  // Get the number of Roles defined in this configuration
129  int getNumRoles() const;
130 
131  /// Query the name of the specified Role.
132  const char* getRoleByIndex(int index) const;
133 
134  /// Retrieve the full list of known Roles, as a vector of strings.
135  std::vector<std::string> getRoles() const;
136 
137  /// Get the number of Looks defined in this configuration
138  int getNumLooks() const;
139 
140  /// Query the name of the specified Look.
141  const char* getLookNameByIndex(int index) const;
142 
143  /// Retrieve the full list of known look names, as a vector of strings.
144  std::vector<std::string> getLookNames() const;
145 
146  /// Is the color space known to be linear? This is very conservative, and
147  /// will return false if it's not sure.
148  bool isColorSpaceLinear(string_view name) const;
149 
150  /// Retrieve the full list of aliases for the named color space.
151  std::vector<std::string> getAliases(string_view color_space) const;
152 
153  /// Given the specified input and output ColorSpace, request a handle to
154  /// a ColorProcessor. It is possible that this will return an empty
155  /// handle, if the inputColorSpace doesn't exist, the outputColorSpace
156  /// doesn't exist, or if the specified transformation is illegal (for
157  /// example, it may require the inversion of a 3D-LUT, etc).
158  ///
159  /// The handle is actually a shared_ptr, so when you're done with a
160  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
161  /// if the ColorConfig that created them no longer exists.
162  ///
163  /// Created ColorProcessors are cached, so asking for the same color
164  /// space transformation multiple times shouldn't be very expensive.
165  ColorProcessorHandle createColorProcessor(
166  string_view inputColorSpace, string_view outputColorSpace,
167  string_view context_key = "", string_view context_value = "") const;
169  createColorProcessor(ustring inputColorSpace, ustring outputColorSpace,
170  ustring context_key = ustring(),
171  ustring context_value = ustring()) const;
172 
173  /// Given the named look(s), input and output color spaces, request a
174  /// color processor that applies an OCIO look transformation. If
175  /// inverse==true, request the inverse transformation. The
176  /// context_key and context_value can optionally be used to establish
177  /// extra key/value pairs in the OCIO context if they are comma-
178  /// separated lists of context keys and values, respectively.
179  ///
180  /// The handle is actually a shared_ptr, so when you're done with a
181  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
182  /// if the ColorConfig that created them no longer exists.
183  ///
184  /// Created ColorProcessors are cached, so asking for the same color
185  /// space transformation multiple times shouldn't be very expensive.
187  createLookTransform(string_view looks, string_view inputColorSpace,
188  string_view outputColorSpace, bool inverse = false,
189  string_view context_key = "",
190  string_view context_value = "") const;
192  createLookTransform(ustring looks, ustring inputColorSpace,
193  ustring outputColorSpace, bool inverse = false,
194  ustring context_key = ustring(),
195  ustring context_value = ustring()) const;
196 
197  /// Get the number of displays defined in this configuration
198  int getNumDisplays() const;
199 
200  /// Query the name of the specified display.
201  const char* getDisplayNameByIndex(int index) const;
202 
203  /// Retrieve the full list of known display names, as a vector of
204  /// strings.
205  std::vector<std::string> getDisplayNames() const;
206 
207  /// Get the name of the default display.
208  const char* getDefaultDisplayName() const;
209 
210  /// Get the number of views for a given display defined in this
211  /// configuration. If the display is empty or not specified, the default
212  /// display will be used.
213  int getNumViews(string_view display = "") const;
214 
215  /// Query the name of the specified view for the specified display
216  const char* getViewNameByIndex(string_view display, int index) const;
217 
218  /// Retrieve the full list of known view names for the display, as a
219  /// vector of strings. If the display is empty or not specified, the
220  /// default display will be used.
221  std::vector<std::string> getViewNames(string_view display = "") const;
222 
223  /// Query the name of the default view for the specified display. If the
224  /// display is empty or not specified, the default display will be used.
225  const char* getDefaultViewName(string_view display = "") const;
226 
227  /// Returns the colorspace attribute of the (display, view) pair. (Note
228  /// that this may be either a color space or a display color space.)
229  /// Returns nullptr for failure.
230  const char* getDisplayViewColorSpaceName(const std::string& display,
231  const std::string& view) const;
232 
233  /// Returns the looks attribute of a (display, view) pair. Returns nullptr
234  /// for failure.
235  const char* getDisplayViewLooks(const std::string& display,
236  const std::string& view) const;
237 
238  /// Construct a processor to transform from the given color space
239  /// to the color space of the given display and view. You may optionally
240  /// override the looks that are, by default, used with the display/view
241  /// combination. Looks is a potentially comma (or colon) delimited list
242  /// of lookNames, where +/- prefixes are optionally allowed to denote
243  /// forward/inverse transformation (and forward is assumed in the
244  /// absence of either). It is possible to remove all looks from the
245  /// display by passing an empty string. The context_key and context_value
246  /// can optionally be used to establish extra key/value pair in the OCIO
247  /// context if they are comma-separated lists of context keys and
248  /// values, respectively.
249  ///
250  /// It is possible that this will return an empty handle if one of the
251  /// color spaces or the display or view doesn't exist or is not allowed.
252  ///
253  /// The handle is actually a shared_ptr, so when you're done with a
254  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
255  /// if the ColorConfig that created them no longer exists.
256  ///
257  /// Created ColorProcessors are cached, so asking for the same color
258  /// space transformation multiple times shouldn't be very expensive.
260  createDisplayTransform(string_view display, string_view view,
261  string_view inputColorSpace, string_view looks = "",
262  bool inverse = false, string_view context_key = "",
263  string_view context_value = "") const;
265  createDisplayTransform(ustring display, ustring view,
266  ustring inputColorSpace, ustring looks = ustring(),
267  bool inverse = false,
268  ustring context_key = ustring(),
269  ustring context_value = ustring()) const;
270 
271  // OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
273  createDisplayTransform(string_view display, string_view view,
274  string_view inputColorSpace, string_view looks,
275  string_view context_key,
276  string_view context_value = "") const;
277  // OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
278  ColorProcessorHandle createDisplayTransform(
279  ustring display, ustring view, ustring inputColorSpace, ustring looks,
280  ustring context_key, ustring context_value = ustring()) const;
281 
282  /// Construct a processor to perform color transforms determined by an
283  /// OpenColorIO FileTransform. It is possible that this will return an
284  /// empty handle if the FileTransform doesn't exist or is not allowed.
285  ///
286  /// The handle is actually a shared_ptr, so when you're done with a
287  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
288  /// if the ColorConfig that created them no longer exists.
289  ///
290  /// Created ColorProcessors are cached, so asking for the same color
291  /// space transformation multiple times shouldn't be very expensive.
292  ColorProcessorHandle createFileTransform(string_view name,
293  bool inverse = false) const;
294  ColorProcessorHandle createFileTransform(ustring name,
295  bool inverse = false) const;
296 
297  /// Construct a processor to perform color transforms specified by a
298  /// 4x4 matrix.
299  ///
300  /// The handle is actually a shared_ptr, so when you're done with a
301  /// ColorProcess, just discard it.
302  ///
303  /// Created ColorProcessors are cached, so asking for the same color
304  /// space transformation multiple times shouldn't be very expensive.
305  ColorProcessorHandle createMatrixTransform(M44fParam M,
306  bool inverse = false) const;
307 
308  /// Given a filepath, ask OCIO what color space it thinks the file
309  /// should be, based on how the name matches file naming rules in the
310  /// OCIO config. (This is mostly a wrapper around OCIO's
311  /// ColorConfig::getColorSpaceFromSFilepath.)
312  string_view getColorSpaceFromFilepath(string_view str) const;
313 
314  /// Given a string (like a filename), look for the longest, right-most
315  /// colorspace substring that appears. Returns "" if no such color space
316  /// is found.
318 
319  /// Turn the name, which could be a color space, an alias, a role, or
320  /// an OIIO-understood universal name (like "sRGB") into a canonical
321  /// color space name. If the name is not recognized, return "".
322  string_view resolve(string_view name) const;
323 
324  /// Are the two color space names/aliases/roles equivalent?
325  bool equivalent(string_view color_space,
326  string_view other_color_space) const;
327 
328  /// Return a filename or other identifier for the config we're using.
329  std::string configname() const;
330 
331  // DEPRECATED(1.9) -- no longer necessary, because it's a shared ptr
332  OIIO_DEPRECATED("no longer necessary (1.9)")
333  static void deleteColorProcessor(const ColorProcessorHandle& /*processor*/)
334  {
335  }
336 
337  /// Return if OpenImageIO was built with OCIO support
338  static bool supportsOpenColorIO();
339 
340  /// Return the hex OCIO version (maj<<24 + min<<16 + patch), or 0 if no
341  /// OCIO support is available.
342  static int OpenColorIO_version_hex();
343 
344  /// Return a default ColorConfig, which is a singleton that will be
345  /// created the first time it is needed. It will be initialized with the
346  /// OCIO environment variable, if it exists, or the OCIO built-in config
347  /// (for OCIO >= 2.2). If neither of those is possible, it will be
348  /// initialized with a built-in minimal config.
349  static const ColorConfig& default_colorconfig();
350 
351 private:
352  ColorConfig(const ColorConfig&) = delete;
353  ColorConfig& operator=(const ColorConfig&) = delete;
354 
355  class Impl;
356  std::unique_ptr<Impl> m_impl;
357  Impl* getImpl() const { return m_impl.get(); }
358 };
359 
360 
361 
362 /// Utility -- convert sRGB value to linear transfer function, without
363 /// any change in color primaries.
364 /// http://en.wikipedia.org/wiki/SRGB
365 inline float
367 {
368  return (x <= 0.04045f) ? (x * (1.0f / 12.92f))
369  : powf((x + 0.055f) * (1.0f / 1.055f), 2.4f);
370 }
371 
372 
373 #ifndef __CUDA_ARCH__
374 inline simd::vfloat4
376 {
377  return simd::select(
378  x <= 0.04045f, x * (1.0f / 12.92f),
379  fast_pow_pos(madd(x, (1.0f / 1.055f), 0.055f * (1.0f / 1.055f)), 2.4f));
380 }
381 #endif
382 
383 /// Utility -- convert linear value to sRGB transfer function, without
384 /// any change in color primaries.
385 inline float
387 {
388  return (x <= 0.0031308f) ? (12.92f * x)
389  : (1.055f * powf(x, 1.f / 2.4f) - 0.055f);
390 }
391 
392 
393 #ifndef __CUDA_ARCH__
394 /// Utility -- convert linear value to sRGB transfer function, without
395 /// any change in color primaries.
396 inline simd::vfloat4
398 {
399  // x = simd::max (x, simd::vfloat4::Zero());
400  return simd::select(x <= 0.0031308f, 12.92f * x,
401  madd(1.055f, fast_pow_pos(x, 1.f / 2.4f), -0.055f));
402 }
403 #endif
404 
405 
406 /// Utility -- convert Rec709 value to linear transfer function, without
407 /// any change in color primaries.
408 /// http://en.wikipedia.org/wiki/Rec._709
409 inline float
411 {
412  if (x < 0.081f)
413  return x * (1.0f / 4.5f);
414  else
415  return powf((x + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
416 }
417 
418 /// Utility -- convert linear value to Rec709 transfer function, without
419 /// any change in color primaries.
420 inline float
422 {
423  if (x < 0.018f)
424  return x * 4.5f;
425  else
426  return 1.099f * powf(x, 0.45f) - 0.099f;
427 }
428 
429 
OIIO_API std::string geterror(bool clear=true)
OIIO_API bool has_error()
Is there a pending global error message waiting to be retrieved?
OIIO_FORCEINLINE OIIO_HOSTDEVICE T fast_pow_pos(const T &x, const U &y)
Definition: fmath.h:2267
int64_t stride_t
Definition: imageio.h:48
GT_API const UT_StringHolder filename
SYS_API float powf(float x, float y)
#define OIIO_DEPRECATED(msg)
Definition: platform.h:466
float sRGB_to_linear(float x)
Definition: color.h:366
float linear_to_sRGB(float x)
Definition: color.h:386
< returns > If no error
Definition: snippets.dox:2
PXL_API void getRoles(UT_StringArray &names)
Returns a list of the supported roles.
float linear_to_Rec709(float x)
Definition: color.h:421
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLfloat f
Definition: glcorearb.h:1926
GLboolean reset
Definition: glad.h:5138
virtual bool hasChannelCrosstalk() const
Definition: color.h:27
vint4 select(const vbool4 &mask, const vint4 &a, const vint4 &b)
Definition: simd.h:4983
OIIO_FORCEINLINE OIIO_HOSTDEVICE float madd(float a, float b, float c)
Fused multiply and add: (a*b + c)
Definition: fmath.h:421
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLenum GLint x
Definition: glcorearb.h:409
ColorProcessor()
Definition: color.h:24
PXL_API const char * parseColorSpaceFromString(const char *string)
virtual ~ColorProcessor(void)
Definition: color.h:25
void apply(float *data)
Definition: color.h:36
virtual bool isNoOp() const
Definition: color.h:26
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
GLint GLsizei width
Definition: glcorearb.h:103
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
std::shared_ptr< ColorProcessor > ColorProcessorHandle
Definition: color.h:49
Definition: format.h:1821
ImageBuf OIIO_API channels(const ImageBuf &src, int nchannels, cspan< int > channelorder, cspan< float > channelvalues={}, cspan< std::string > newchannelnames={}, bool shuffle_channel_names=false, int nthreads=0)
float Rec709_to_linear(float x)
Definition: color.h:410
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126
#define OIIO_API
Definition: export.h:65