6 #include "util/color.h"
15 # include <OpenColorIO/OpenColorIO.h>
16 namespace OCIO = OCIO_NAMESPACE;
30 static unordered_map<ustring, ustring, ustringHash> cached_colorspaces;
31 static unordered_map<ustring, OCIO::ConstProcessorRcPtr, ustringHash> cached_processors;
44 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
52 if (cached_processors.find(colorspace) == cached_processors.end()) {
54 cached_processors[colorspace] = config->getProcessor(colorspace.c_str(),
"scene_linear");
56 catch (OCIO::Exception &exception) {
57 cached_processors[colorspace] = OCIO::ConstProcessorRcPtr();
59 <<
" can't be converted to scene_linear: " << exception.what();
63 const OCIO::Processor *processor = cached_processors[colorspace].get();
64 return (ColorSpaceProcessor *)processor;
80 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
86 OCIO::ConstColorSpaceRcPtr space = config->getColorSpace(colorspace.c_str());
87 return space && space->isData();
89 catch (OCIO::Exception &) {
98 const char *file_format,
104 bool srgb = (colorspace ==
"sRGB" || colorspace ==
"GammaCorrected" ||
105 (colorspace.empty() &&
106 (strcmp(file_format,
"png") == 0 || strcmp(file_format,
"tiff") == 0 ||
107 strcmp(file_format,
"dpx") == 0 || strcmp(file_format,
"jpeg2000") == 0)));
124 if (cached_colorspaces.find(colorspace) != cached_colorspaces.end()) {
125 return cached_colorspaces[colorspace];
130 bool is_scene_linear, is_srgb;
131 is_builtin_colorspace(colorspace, is_scene_linear, is_srgb);
134 if (is_scene_linear) {
135 VLOG_INFO <<
"Colorspace " << colorspace.string() <<
" is no-op";
140 VLOG_INFO <<
"Colorspace " << colorspace.string() <<
" is sRGB";
147 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
148 if (!config || !config->getColorSpace(colorspace.c_str())) {
149 VLOG_WARNING <<
"Colorspace " << colorspace.c_str() <<
" not found, using raw instead";
153 <<
" can't be converted to scene_linear, using raw instead";
160 VLOG_INFO <<
"Colorspace " << colorspace.string() <<
" handled through OpenColorIO";
161 cached_colorspaces[colorspace] = colorspace;
165 <<
" not available, built without OpenColorIO";
171 void ColorSpaceManager::is_builtin_colorspace(ustring colorspace,
172 bool &is_scene_linear,
176 const OCIO::Processor *processor = (
const OCIO::Processor *)
get_processor(colorspace);
178 is_scene_linear =
false;
183 OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
184 is_scene_linear =
true;
186 for (
int i = 0; i < 256; i++) {
187 float v = i / 255.0f;
189 float cR[3] = {
v, 0, 0};
190 float cG[3] = {0,
v, 0};
191 float cB[3] = {0, 0,
v};
192 float cW[3] = {
v,
v,
v};
193 device_processor->applyRGB(cR);
194 device_processor->applyRGB(cG);
195 device_processor->applyRGB(cB);
196 device_processor->applyRGB(cW);
199 if (
fabsf(cR[1]) > 1e-5f ||
fabsf(cR[2]) > 1e-5f ||
fabsf(cG[0]) > 1e-5f ||
200 fabsf(cG[2]) > 1e-5f ||
fabsf(cB[0]) > 1e-5f ||
fabsf(cB[1]) > 1e-5f) {
201 is_scene_linear =
false;
208 is_scene_linear =
false;
214 is_scene_linear =
false;
221 is_scene_linear =
false;
229 is_scene_linear =
false;
236 template<
typename T>
inline float4 cast_to_float4(
T *
data)
244 template<
typename T>
inline void cast_from_float4(
T *
data,
float4 value)
246 data[0] = util_image_cast_from_float<T>(value.x);
247 data[1] = util_image_cast_from_float<T>(value.y);
248 data[2] = util_image_cast_from_float<T>(value.z);
249 data[3] = util_image_cast_from_float<T>(value.w);
253 template<
typename T,
bool compress_as_srgb = false>
254 inline void processor_apply_pixels_rgba(
const OCIO::Processor *processor,
261 OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
270 for (
size_t i = 0; i <
width; i++) {
271 float4 value = cast_to_float4(pixels + 4 * (j + i));
273 if (!(value.w <= 0.0f || value.w == 1.0f)) {
274 float inv_alpha = 1.0f / value.w;
275 value.x *= inv_alpha;
276 value.y *= inv_alpha;
277 value.z *= inv_alpha;
280 float_pixels[i] = value;
283 OCIO::PackedImageDesc desc((
float *)float_pixels.data(),
width, 1, 4);
284 device_processor->apply(desc);
286 for (
size_t i = 0; i <
width; i++) {
287 float4 value = float_pixels[i];
289 if (compress_as_srgb) {
293 if (!(value.w <= 0.0f || value.w == 1.0f)) {
299 cast_from_float4(pixels + 4 * (j + i), value);
304 template<
typename T,
bool compress_as_srgb = false>
305 inline void processor_apply_pixels_grayscale(
const OCIO::Processor *processor,
309 OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
320 const T *pixel = pixels + j;
321 float *fpixel = float_pixels.data();
322 for (
size_t i = 0; i <
width; i++, pixel++, fpixel += 3) {
323 const float f = util_image_cast_to_float<T>(*pixel);
330 OCIO::PackedImageDesc desc((
float *)float_pixels.data(),
width, 1, 3);
331 device_processor->apply(desc);
334 T *pixel = pixels + j;
335 const float *fpixel = float_pixels.data();
336 for (
size_t i = 0; i <
width; i++, pixel++, fpixel += 3) {
338 if (compress_as_srgb) {
341 *pixel = util_image_cast_from_float<T>(f);
351 ustring colorspace,
T *pixels,
size_t num_pixels,
bool is_rgba,
bool compress_as_srgb)
354 const OCIO::Processor *processor = (
const OCIO::Processor *)
get_processor(colorspace);
358 if (compress_as_srgb) {
360 processor_apply_pixels_rgba<T, true>(processor, pixels,
num_pixels);
364 processor_apply_pixels_rgba<T>(processor, pixels,
num_pixels);
368 if (compress_as_srgb) {
370 processor_apply_pixels_grayscale<T, true>(processor, pixels,
num_pixels);
374 processor_apply_pixels_grayscale<T>(processor, pixels,
num_pixels);
383 (
void)compress_as_srgb;
392 const OCIO::Processor *processor = (
const OCIO::Processor *)processor_;
395 OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
398 device_processor->applyRGB(&
rgb.x);
402 device_processor->applyRGB(pixel);
405 if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
407 device_processor->applyRGB(pixel);
412 float alpha = pixel[3];
413 float inv_alpha = 1.0f / alpha;
415 pixel[0] *= inv_alpha;
416 pixel[1] *= inv_alpha;
417 pixel[2] *= inv_alpha;
419 device_processor->applyRGB(pixel);
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
ATTR_WARN_UNUSED_RESULT const BMVert * v
static bool colorspace_is_data(ustring colorspace)
static void to_scene_linear(ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb)
static void free_memory()
static ColorSpaceProcessor * get_processor(ustring colorspace)
static ustring detect_known_colorspace(ustring colorspace, const char *file_format, bool is_float)
ustring u_colorspace_srgb("__builtin_srgb")
CCL_NAMESPACE_BEGIN ustring u_colorspace_auto
ustring u_colorspace_raw("__builtin_raw")
#define CCL_NAMESPACE_END
float util_image_cast_to_float(T value)
static void map_free_memory(T &data)
SyclQueue void void size_t num_bytes void
ccl_gpu_kernel_postfix ccl_global float int num_pixels
ccl_device_inline float average(const float2 &a)
static const int chunk_size
static const pxr::TfToken rgb("rgb", pxr::TfToken::Immortal)
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
ccl_device float color_linear_to_srgb(float c)
ccl_device float4 color_linear_to_srgb_v4(float4 c)
ccl_device float color_srgb_to_linear(float c)
ccl_device_inline bool compare_floats(float a, float b, float abs_diff, int ulp_diff)