HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
color.h
Go to the documentation of this file.
1 /*
2  Copyright 2010 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 #pragma once
32 
33 #include <memory>
34 
35 #include <OpenImageIO/export.h>
36 #include <OpenImageIO/fmath.h>
37 #include <OpenImageIO/imageio.h>
39 #include <OpenImageIO/typedesc.h>
40 #include <OpenImageIO/ustring.h>
41 
42 #include <OpenEXR/ImathMatrix.h> /* because we need M44f */
43 
44 
46 
47 /// The ColorProcessor encapsulates a baked color transformation, suitable for
48 /// application to raw pixels, or ImageBuf(s). These are generated using
49 /// ColorConfig::createColorProcessor, and referenced in ImageBufAlgo
50 /// (amongst other places)
52 public:
54  virtual ~ColorProcessor(void) {};
55  virtual bool isNoOp() const { return false; }
56  virtual bool hasChannelCrosstalk() const { return false; }
57 
58  // Convert an array/image of color values. The strides are the distance,
59  // in bytes, between subsequent color channels, pixels, and scanlines.
60  virtual void apply(float* data, int width, int height, int channels,
61  stride_t chanstride, stride_t xstride,
62  stride_t ystride) const = 0;
63  // Convert a single 3-color
64  void apply(float* data)
65  {
66  apply((float*)data, 1, 1, 3, sizeof(float), 0, 0);
67  }
68 };
69 
70 // Preprocessor symbol to allow conditional compilation depending on
71 // whether the ColorProcesor class is exposed (it was not prior to OIIO 1.9).
72 #define OIIO_HAS_COLORPROCESSOR 1
73 
74 
75 
76 typedef std::shared_ptr<ColorProcessor> ColorProcessorHandle;
77 
78 // Preprocessor symbol to allow conditional compilation depending on
79 // whether the ColorConfig returns ColorProcessor shared pointers or raw.
80 #define OIIO_COLORCONFIG_USES_SHARED_PTR 1
81 
82 
83 
84 /// Represents the set of all color transformations that are allowed.
85 /// If OpenColorIO is enabled at build time, this configuration is loaded
86 /// at runtime, allowing the user to have complete control of all color
87 /// transformation math. ($OCIO) (See opencolorio.org for details).
88 /// If OpenColorIO is not enabled at build time, a generic color configuration
89 /// is provided for minimal color support.
90 ///
91 /// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight.
92 /// Their construction / destruction should be kept to a minimum.
93 
95 public:
96  /// Construct a ColorConfig using the named OCIO configuration file,
97  /// or if filename is empty, to the current color configuration
98  /// specified by env variable $OCIO.
99  ///
100  /// Multiple calls to this are potentially expensive. A ColorConfig
101  /// should usually be shared by an app for its entire runtime.
103 
104  ~ColorConfig();
105 
106  /// Reset the config to the named OCIO configuration file, or if
107  /// filename is empty, to the current color configuration specified
108  /// by env variable $OCIO. Return true for success, false if there
109  /// was an error.
110  ///
111  /// Multiple calls to this are potentially expensive. A ColorConfig
112  /// should usually be shared by an app for its entire runtime.
113  bool reset(string_view filename = "");
114 
115  /// Has an error string occurred?
116  /// (This will not affect the error state.)
117  bool error() const;
118 
119  /// This routine will return the error string (and clear any error
120  /// flags). If no error has occurred since the last time geterror()
121  /// was called, it will return an empty string.
123 
124  /// Get the number of ColorSpace(s) defined in this configuration
125  int getNumColorSpaces() const;
126 
127  /// Query the name of the specified ColorSpace.
128  const char* getColorSpaceNameByIndex(int index) const;
129 
130  /// Get the name of the color space representing the named role,
131  /// or NULL if none could be identified.
132  const char* getColorSpaceNameByRole(string_view role) const;
133 
134  /// Get the data type that OCIO thinks this color space is. The name
135  /// may be either a color space name or a role.
136  OIIO::TypeDesc getColorSpaceDataType(string_view name, int* bits) const;
137 
138  /// Retrieve the full list of known color space names, as a vector
139  /// of strings.
140  std::vector<std::string> getColorSpaceNames() const;
141 
142  /// Get the name of the color space family of the named color space,
143  /// or NULL if none could be identified.
144  const char* getColorSpaceFamilyByName(string_view name) const;
145 
146  /// Get the number of Looks defined in this configuration
147  int getNumLooks() const;
148 
149  /// Query the name of the specified Look.
150  const char* getLookNameByIndex(int index) const;
151 
152  /// Retrieve the full list of known look names, as a vector of strings.
153  std::vector<std::string> getLookNames() const;
154 
155  /// Given the specified input and output ColorSpace, request a handle to
156  /// a ColorProcessor. It is possible that this will return an empty
157  /// handle, if the inputColorSpace doesnt exist, the outputColorSpace
158  /// doesn't exist, or if the specified transformation is illegal (for
159  /// example, it may require the inversion of a 3D-LUT, etc).
160  ///
161  /// The handle is actually a shared_ptr, so when you're done with a
162  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
163  /// if the ColorConfig that created them no longer exists.
164  ///
165  /// Created ColorProcessors are cached, so asking for the same color
166  /// space transformation multiple times shouldn't be very expensive.
167  ColorProcessorHandle createColorProcessor(
168  string_view inputColorSpace, string_view outputColorSpace,
169  string_view context_key = "", string_view context_value = "") const;
171  createColorProcessor(ustring inputColorSpace, ustring outputColorSpace,
172  ustring context_key = ustring(),
173  ustring context_value = ustring()) const;
174 
175  /// Given the named look(s), input and output color spaces, request a
176  /// color processor that applies an OCIO look transformation. If
177  /// inverse==true, request the inverse transformation. The
178  /// context_key and context_value can optionally be used to establish
179  /// extra key/value pairs in the OCIO context if they are comma-
180  /// separated lists of ontext keys and values, respectively.
181  ///
182  /// The handle is actually a shared_ptr, so when you're done with a
183  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
184  /// if the ColorConfig that created them no longer exists.
185  ///
186  /// Created ColorProcessors are cached, so asking for the same color
187  /// space transformation multiple times shouldn't be very expensive.
189  createLookTransform(string_view looks, string_view inputColorSpace,
190  string_view outputColorSpace, bool inverse = false,
191  string_view context_key = "",
192  string_view context_value = "") const;
194  createLookTransform(ustring looks, ustring inputColorSpace,
195  ustring outputColorSpace, bool inverse = false,
196  ustring context_key = ustring(),
197  ustring context_value = ustring()) const;
198 
199  /// Get the number of displays defined in this configuration
200  int getNumDisplays() const;
201 
202  /// Query the name of the specified display.
203  const char* getDisplayNameByIndex(int index) const;
204 
205  /// Retrieve the full list of known display names, as a vector of
206  /// strings.
207  std::vector<std::string> getDisplayNames() const;
208 
209  /// Get the name of the default display.
210  const char* getDefaultDisplayName() const;
211 
212  /// Get the number of views for a given display defined in this
213  /// configuration. If the display is empty or not specified, the default
214  /// display will be used.
215  int getNumViews(string_view display = "") const;
216 
217  /// Query the name of the specified view for the specified display
218  const char* getViewNameByIndex(string_view display, int index) const;
219 
220  /// Retrieve the full list of known view names for the display, as a
221  /// vector of strings. If the display is empty or not specified, the
222  /// default display will be used.
223  std::vector<std::string> getViewNames(string_view display = "") const;
224 
225  /// Query the name of the default view for the specified display. If the
226  /// display is empty or not specified, the default display will be used.
227  const char* getDefaultViewName(string_view display = "") const;
228 
229  /// Construct a processor to transform from the given color space
230  /// to the color space of the given display and view. You may optionally
231  /// override the looks that are, by default, used with the display/view
232  /// combination. Looks is a potentially comma (or colon) delimited list
233  /// of lookNames, where +/- prefixes are optionally allowed to denote
234  /// forward/inverse transformation (and forward is assumed in the
235  /// absence of either). It is possible to remove all looks from the
236  /// display by passing an empty string. The context_key and context_value
237  /// can optionally be used to establish extra key/value pair in the OCIO
238  /// context if they are comma-separated lists of context keys and
239  /// values, respectively.
240  ///
241  /// It is possible that this will return an empty handle if one of the
242  /// color spaces or the display or view doesn't exist or is not allowed.
243  ///
244  /// The handle is actually a shared_ptr, so when you're done with a
245  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
246  /// if the ColorConfig that created them no longer exists.
247  ///
248  /// Created ColorProcessors are cached, so asking for the same color
249  /// space transformation multiple times shouldn't be very expensive.
251  createDisplayTransform(string_view display, string_view view,
252  string_view inputColorSpace, string_view looks = "",
253  string_view context_key = "",
254  string_view context_value = "") const;
256  createDisplayTransform(ustring display, ustring view,
257  ustring inputColorSpace, ustring looks = ustring(),
258  ustring context_key = ustring(),
259  ustring context_value = ustring()) const;
260 
261  /// Construct a processor to perform color transforms determined by an
262  /// OpenColorIO FileTransform. It is possible that this will return an
263  /// empty handle if the FileTransform doesn't exist or is not allowed.
264  ///
265  /// The handle is actually a shared_ptr, so when you're done with a
266  /// ColorProcess, just discard it. ColorProcessor(s) remain valid even
267  /// if the ColorConfig that created them no longer exists.
268  ///
269  /// Created ColorProcessors are cached, so asking for the same color
270  /// space transformation multiple times shouldn't be very expensive.
271  ColorProcessorHandle createFileTransform(string_view name,
272  bool inverse = false) const;
273  ColorProcessorHandle createFileTransform(ustring name,
274  bool inverse = false) const;
275 
276  /// Construct a processor to perform color transforms specified by a
277  /// 4x4 matrix.
278  ///
279  /// The handle is actually a shared_ptr, so when you're done with a
280  /// ColorProcess, just discard it.
281  ///
282  /// Created ColorProcessors are cached, so asking for the same color
283  /// space transformation multiple times shouldn't be very expensive.
284  ColorProcessorHandle createMatrixTransform(const Imath::M44f& M,
285  bool inverse = false) const;
286 
287  /// Given a string (like a filename), look for the longest, right-most
288  /// colorspace substring that appears. Returns "" if no such color space
289  /// is found. (This is just a wrapper around OCIO's
290  /// ColorConfig::parseColorSpaceFromString.)
291  string_view parseColorSpaceFromString(string_view str) const;
292 
293  /// Return a filename or other identifier for the config we're using.
294  std::string configname() const;
295 
296  // DEPRECATED(1.9) -- no longer necessary, because it's a shared ptr
297  static void deleteColorProcessor(const ColorProcessorHandle& processor) {}
298 
299  /// Return if OpenImageIO was built with OCIO support
300  static bool supportsOpenColorIO();
301 
302 private:
303  ColorConfig(const ColorConfig&) = delete;
304  ColorConfig& operator=(const ColorConfig&) = delete;
305 
306  class Impl;
307  std::unique_ptr<Impl> m_impl;
308  Impl* getImpl() const { return m_impl.get(); }
309 };
310 
311 
312 
313 /// Utility -- convert sRGB value to linear
314 /// http://en.wikipedia.org/wiki/SRGB
315 inline float
317 {
318  return (x <= 0.04045f) ? (x * (1.0f / 12.92f))
319  : powf((x + 0.055f) * (1.0f / 1.055f), 2.4f);
320 }
321 
322 
323 #ifndef __CUDA_ARCH__
324 inline simd::vfloat4
326 {
327  return simd::select(
328  x <= 0.04045f, x * (1.0f / 12.92f),
329  fast_pow_pos(madd(x, (1.0f / 1.055f), 0.055f * (1.0f / 1.055f)), 2.4f));
330 }
331 #endif
332 
333 /// Utility -- convert linear value to sRGB
334 inline float
336 {
337  return (x <= 0.0031308f) ? (12.92f * x)
338  : (1.055f * powf(x, 1.f / 2.4f) - 0.055f);
339 }
340 
341 
342 #ifndef __CUDA_ARCH__
343 /// Utility -- convert linear value to sRGB
344 inline simd::vfloat4
346 {
347  // x = simd::max (x, simd::vfloat4::Zero());
348  return simd::select(x <= 0.0031308f, 12.92f * x,
349  madd(1.055f, fast_pow_pos(x, 1.f / 2.4f), -0.055f));
350 }
351 #endif
352 
353 
354 /// Utility -- convert Rec709 value to linear
355 /// http://en.wikipedia.org/wiki/Rec._709
356 inline float
358 {
359  if (x < 0.081f)
360  return x * (1.0f / 4.5f);
361  else
362  return powf((x + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
363 }
364 
365 /// Utility -- convert linear value to Rec709
366 inline float
368 {
369  if (x < 0.018f)
370  return x * 4.5f;
371  else
372  return 1.099f * powf(x, 0.45f) - 0.099f;
373 }
374 
375 
GT_API const UT_StringHolder filename
Matrix44< float > M44f
Definition: ImathMatrix.h:865
GLuint const GLchar * name
Definition: glew.h:1814
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1252
GLuint index
Definition: glew.h:1814
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1252
float linear_to_Rec709(float x)
Utility – convert linear value to Rec709.
Definition: color.h:367
SYS_API float powf(float x, float y)
GLboolean reset
Definition: glew.h:4959
OIIO_API std::string geterror()
OIIO_HOSTDEVICE float madd(float a, float b, float c)
Fused multiply and add: (a*b + c)
Definition: fmath.h:267
static void deleteColorProcessor(const ColorProcessorHandle &processor)
Definition: color.h:297
float Rec709_to_linear(float x)
Definition: color.h:357
GLclampf f
Definition: glew.h:3499
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
virtual bool hasChannelCrosstalk() const
Definition: color.h:56
vint4 select(const vbool4 &mask, const vint4 &a, const vint4 &b)
Definition: simd.h:4678
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
std::shared_ptr< ColorProcessor > ColorProcessorHandle
Definition: color.h:76
float linear_to_sRGB(float x)
Utility – convert linear value to sRGB.
Definition: color.h:335
ptrdiff_t stride_t
Definition: imageio.h:69
ColorProcessor()
Definition: color.h:53
float sRGB_to_linear(float x)
Definition: color.h:316
GLsizei const GLchar *const * string
Definition: glew.h:1844
virtual ~ColorProcessor(void)
Definition: color.h:54
void apply(float *data)
Definition: color.h:64
virtual bool isNoOp() const
Definition: color.h:55
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
OIIO_HOSTDEVICE T fast_pow_pos(const T &x, const U &y)
Definition: fmath.h:1756
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:65
#define OIIO_API
Definition: export.h:91