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 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio
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 = 0;
34  // Convert a single 3-color
35  void apply(float* data)
36  {
37  apply((float*)data, 1, 1, 3, sizeof(float), 3 * sizeof(float),
38  3 * sizeof(float));
39  }
40 };
41 
42 // Preprocessor symbol to allow conditional compilation depending on
43 // whether the ColorProcessor class is exposed (it was not prior to OIIO 1.9).
44 #define OIIO_HAS_COLORPROCESSOR 1
45 
46 
47 
48 typedef std::shared_ptr<ColorProcessor> ColorProcessorHandle;
49 
50 // Preprocessor symbol to allow conditional compilation depending on
51 // whether the ColorConfig returns ColorProcessor shared pointers or raw.
52 #define OIIO_COLORCONFIG_USES_SHARED_PTR 1
53 
54 
55 
56 /// Represents the set of all color transformations that are allowed.
57 /// If OpenColorIO is enabled at build time, this configuration is loaded
58 /// at runtime, allowing the user to have complete control of all color
59 /// transformation math. ($OCIO) (See opencolorio.org for details).
60 /// If OpenColorIO is not enabled at build time, a generic color configuration
61 /// is provided for minimal color support.
62 ///
63 /// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight.
64 /// Their construction / destruction should be kept to a minimum.
65 
67 public:
68  /// Construct a ColorConfig using the named OCIO configuration file,
69  /// or if filename is empty, to the current color configuration
70  /// specified by env variable $OCIO.
71  ///
72  /// Multiple calls to this are potentially expensive. A ColorConfig
73  /// should usually be shared by an app for its entire runtime.
75 
76  ~ColorConfig();
77 
78  /// Reset the config to the named OCIO configuration file, or if
79  /// filename is empty, to the current color configuration specified
80  /// by env variable $OCIO. Return true for success, false if there
81  /// was an error.
82  ///
83  /// Multiple calls to this are potentially expensive. A ColorConfig
84  /// should usually be shared by an app for its entire runtime.
85  bool reset(string_view filename = "");
86 
87  /// Has an error string occurred?
88  /// (This will not affect the error state.)
89  bool has_error() const;
90 
91  /// DEPRECATED(2.4), old name for has_error().
92  bool error() const;
93 
94  /// This routine will return the error string (and by default, clear any
95  /// error flags). If no error has occurred since the last time
96  /// geterror() was called, it will return an empty string.
97  std::string geterror(bool clear = true);
98 
99  /// Get the number of ColorSpace(s) defined in this configuration
100  int getNumColorSpaces() const;
101 
102  /// Query the name of the specified ColorSpace.
103  const char* getColorSpaceNameByIndex(int index) const;
104 
105  /// Get the name of the color space representing the named role,
106  /// or NULL if none could be identified.
107  const char* getColorSpaceNameByRole(string_view role) const;
108 
109  /// Get the data type that OCIO thinks this color space is. The name
110  /// may be either a color space name or a role.
111  OIIO::TypeDesc getColorSpaceDataType(string_view name, int* bits) const;
112 
113  /// Retrieve the full list of known color space names, as a vector
114  /// of strings.
115  std::vector<std::string> getColorSpaceNames() const;
116 
117  /// Get the name of the color space family of the named color space,
118  /// or NULL if none could be identified.
119  const char* getColorSpaceFamilyByName(string_view name) const;
120 
121  // Get the number of Roles defined in this configuration
122  int getNumRoles() const;
123 
124  /// Query the name of the specified Role.
125  const char* getRoleByIndex(int index) const;
126 
127  /// Retrieve the full list of known Roles, as a vector of strings.
128  std::vector<std::string> getRoles() const;
129 
130  /// Get the number of Looks defined in this configuration
131  int getNumLooks() const;
132 
133  /// Query the name of the specified Look.
134  const char* getLookNameByIndex(int index) const;
135 
136  /// Retrieve the full list of known look names, as a vector of strings.
137  std::vector<std::string> getLookNames() const;
138 
139  /// Given the specified input and output ColorSpace, request a handle to
140  /// a ColorProcessor. It is possible that this will return an empty
141  /// handle, if the inputColorSpace doesn't exist, the outputColorSpace
142  /// doesn't exist, or if the specified transformation is illegal (for
143  /// example, it may require the inversion of a 3D-LUT, etc).
144  ///
145  /// The handle is actually a shared_ptr, so when you're done with a
146  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
147  /// if the ColorConfig that created them no longer exists.
148  ///
149  /// Created ColorProcessors are cached, so asking for the same color
150  /// space transformation multiple times shouldn't be very expensive.
151  ColorProcessorHandle createColorProcessor(
152  string_view inputColorSpace, string_view outputColorSpace,
153  string_view context_key = "", string_view context_value = "") const;
155  createColorProcessor(ustring inputColorSpace, ustring outputColorSpace,
156  ustring context_key = ustring(),
157  ustring context_value = ustring()) const;
158 
159  /// Given the named look(s), input and output color spaces, request a
160  /// color processor that applies an OCIO look transformation. If
161  /// inverse==true, request the inverse transformation. The
162  /// context_key and context_value can optionally be used to establish
163  /// extra key/value pairs in the OCIO context if they are comma-
164  /// separated lists of ontext keys and values, respectively.
165  ///
166  /// The handle is actually a shared_ptr, so when you're done with a
167  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
168  /// if the ColorConfig that created them no longer exists.
169  ///
170  /// Created ColorProcessors are cached, so asking for the same color
171  /// space transformation multiple times shouldn't be very expensive.
173  createLookTransform(string_view looks, string_view inputColorSpace,
174  string_view outputColorSpace, bool inverse = false,
175  string_view context_key = "",
176  string_view context_value = "") const;
178  createLookTransform(ustring looks, ustring inputColorSpace,
179  ustring outputColorSpace, bool inverse = false,
180  ustring context_key = ustring(),
181  ustring context_value = ustring()) const;
182 
183  /// Get the number of displays defined in this configuration
184  int getNumDisplays() const;
185 
186  /// Query the name of the specified display.
187  const char* getDisplayNameByIndex(int index) const;
188 
189  /// Retrieve the full list of known display names, as a vector of
190  /// strings.
191  std::vector<std::string> getDisplayNames() const;
192 
193  /// Get the name of the default display.
194  const char* getDefaultDisplayName() const;
195 
196  /// Get the number of views for a given display defined in this
197  /// configuration. If the display is empty or not specified, the default
198  /// display will be used.
199  int getNumViews(string_view display = "") const;
200 
201  /// Query the name of the specified view for the specified display
202  const char* getViewNameByIndex(string_view display, int index) const;
203 
204  /// Retrieve the full list of known view names for the display, as a
205  /// vector of strings. If the display is empty or not specified, the
206  /// default display will be used.
207  std::vector<std::string> getViewNames(string_view display = "") const;
208 
209  /// Query the name of the default view for the specified display. If the
210  /// display is empty or not specified, the default display will be used.
211  const char* getDefaultViewName(string_view display = "") const;
212 
213  /// Construct a processor to transform from the given color space
214  /// to the color space of the given display and view. You may optionally
215  /// override the looks that are, by default, used with the display/view
216  /// combination. Looks is a potentially comma (or colon) delimited list
217  /// of lookNames, where +/- prefixes are optionally allowed to denote
218  /// forward/inverse transformation (and forward is assumed in the
219  /// absence of either). It is possible to remove all looks from the
220  /// display by passing an empty string. The context_key and context_value
221  /// can optionally be used to establish extra key/value pair in the OCIO
222  /// context if they are comma-separated lists of context keys and
223  /// values, respectively.
224  ///
225  /// It is possible that this will return an empty handle if one of the
226  /// color spaces or the display or view doesn't exist or is not allowed.
227  ///
228  /// The handle is actually a shared_ptr, so when you're done with a
229  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
230  /// if the ColorConfig that created them no longer exists.
231  ///
232  /// Created ColorProcessors are cached, so asking for the same color
233  /// space transformation multiple times shouldn't be very expensive.
235  createDisplayTransform(string_view display, string_view view,
236  string_view inputColorSpace, string_view looks = "",
237  string_view context_key = "",
238  string_view context_value = "") const;
240  createDisplayTransform(ustring display, ustring view,
241  ustring inputColorSpace, ustring looks = ustring(),
242  ustring context_key = ustring(),
243  ustring context_value = ustring()) const;
244 
245  /// Construct a processor to perform color transforms determined by an
246  /// OpenColorIO FileTransform. It is possible that this will return an
247  /// empty handle if the FileTransform doesn't exist or is not allowed.
248  ///
249  /// The handle is actually a shared_ptr, so when you're done with a
250  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
251  /// if the ColorConfig that created them no longer exists.
252  ///
253  /// Created ColorProcessors are cached, so asking for the same color
254  /// space transformation multiple times shouldn't be very expensive.
255  ColorProcessorHandle createFileTransform(string_view name,
256  bool inverse = false) const;
257  ColorProcessorHandle createFileTransform(ustring name,
258  bool inverse = false) const;
259 
260  /// Construct a processor to perform color transforms specified by a
261  /// 4x4 matrix.
262  ///
263  /// The handle is actually a shared_ptr, so when you're done with a
264  /// ColorProcess, just discard it.
265  ///
266  /// Created ColorProcessors are cached, so asking for the same color
267  /// space transformation multiple times shouldn't be very expensive.
268  ColorProcessorHandle createMatrixTransform(const Imath::M44f& M,
269  bool inverse = false) const;
270 
271  /// Given a filepath, ask OCIO what color space it thinks the file
272  /// should be, based on how the name matches file naming rules in the
273  /// OCIO config. (This is mostly a wrapper around OCIO's
274  /// ColorConfig::getColorSpaceFromSFilepath.)
275  string_view getColorSpaceFromFilepath(string_view str) const;
276 
277  /// Given a string (like a filename), look for the longest, right-most
278  /// colorspace substring that appears. Returns "" if no such color space
279  /// is found.
281 
282  /// Return a filename or other identifier for the config we're using.
283  std::string configname() const;
284 
285  // DEPRECATED(1.9) -- no longer necessary, because it's a shared ptr
286  OIIO_DEPRECATED("no longer necessary (1.9)")
287  static void deleteColorProcessor(const ColorProcessorHandle& /*processor*/)
288  {
289  }
290 
291  /// Return if OpenImageIO was built with OCIO support
292  static bool supportsOpenColorIO();
293 
294  /// Return the hex OCIO version (maj<<24 + min<<16 + patch), or 0 if no
295  /// OCIO support is available.
296  static int OpenColorIO_version_hex();
297 
298 private:
299  ColorConfig(const ColorConfig&) = delete;
300  ColorConfig& operator=(const ColorConfig&) = delete;
301 
302  class Impl;
303  std::unique_ptr<Impl> m_impl;
304  Impl* getImpl() const { return m_impl.get(); }
305 };
306 
307 
308 
309 /// Utility -- convert sRGB value to linear
310 /// http://en.wikipedia.org/wiki/SRGB
311 inline float
313 {
314  return (x <= 0.04045f) ? (x * (1.0f / 12.92f))
315  : powf((x + 0.055f) * (1.0f / 1.055f), 2.4f);
316 }
317 
318 
319 #ifndef __CUDA_ARCH__
320 inline simd::vfloat4
322 {
323  return simd::select(
324  x <= 0.04045f, x * (1.0f / 12.92f),
325  fast_pow_pos(madd(x, (1.0f / 1.055f), 0.055f * (1.0f / 1.055f)), 2.4f));
326 }
327 #endif
328 
329 /// Utility -- convert linear value to sRGB
330 inline float
332 {
333  return (x <= 0.0031308f) ? (12.92f * x)
334  : (1.055f * powf(x, 1.f / 2.4f) - 0.055f);
335 }
336 
337 
338 #ifndef __CUDA_ARCH__
339 /// Utility -- convert linear value to sRGB
340 inline simd::vfloat4
342 {
343  // x = simd::max (x, simd::vfloat4::Zero());
344  return simd::select(x <= 0.0031308f, 12.92f * x,
345  madd(1.055f, fast_pow_pos(x, 1.f / 2.4f), -0.055f));
346 }
347 #endif
348 
349 
350 /// Utility -- convert Rec709 value to linear
351 /// http://en.wikipedia.org/wiki/Rec._709
352 inline float
354 {
355  if (x < 0.081f)
356  return x * (1.0f / 4.5f);
357  else
358  return powf((x + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
359 }
360 
361 /// Utility -- convert linear value to Rec709
362 inline float
364 {
365  if (x < 0.018f)
366  return x * 4.5f;
367  else
368  return 1.099f * powf(x, 0.45f) - 0.099f;
369 }
370 
371 
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:2215
int64_t stride_t
Definition: imageio.h:48
GT_API const UT_StringHolder filename
Matrix44< float > M44f
4x4 matrix of float
Definition: ImathMatrix.h:1137
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
float linear_to_Rec709(float x)
Utility – convert linear value to Rec709.
Definition: color.h:363
SYS_API float powf(float x, float y)
#define OIIO_DEPRECATED(msg)
Definition: platform.h:458
< returns > If no error
Definition: snippets.dox:2
PXL_API void getRoles(UT_StringArray &names)
Returns a list of the supported roles.
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLfloat f
Definition: glcorearb.h:1926
float Rec709_to_linear(float x)
Definition: color.h:353
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:4816
std::shared_ptr< ColorProcessor > ColorProcessorHandle
Definition: color.h:48
float linear_to_sRGB(float x)
Utility – convert linear value to sRGB.
Definition: color.h:331
OIIO_FORCEINLINE OIIO_HOSTDEVICE float madd(float a, float b, float c)
Fused multiply and add: (a*b + c)
Definition: fmath.h:413
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)
float sRGB_to_linear(float x)
Definition: color.h:312
virtual ~ColorProcessor(void)
Definition: color.h:25
void apply(float *data)
Definition: color.h:35
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
Definition: core.h:982
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
Definition: format.h:895
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)
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93
#define OIIO_API
Definition: export.h:65