Blender  V3.3
ocio_impl.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2012 Blender Foundation. All rights reserved. */
3 
4 #include <cassert>
5 #include <iostream>
6 #include <math.h>
7 #include <sstream>
8 #include <string.h>
9 
10 #ifdef _MSC_VER
11 # pragma warning(push)
12 # pragma warning(disable : 4251 4275)
13 #endif
14 #include <OpenColorIO/OpenColorIO.h>
15 #ifdef _MSC_VER
16 # pragma warning(pop)
17 #endif
18 
19 using namespace OCIO_NAMESPACE;
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_math.h"
24 #include "BLI_math_color.h"
25 #include "BLI_math_matrix.h"
26 
27 #include "ocio_impl.h"
28 
29 #if !defined(WITH_ASSERT_ABORT)
30 # define OCIO_abort()
31 #else
32 # include <stdlib.h>
33 # define OCIO_abort() abort()
34 #endif
35 
36 #if defined(_MSC_VER)
37 # define __func__ __FUNCTION__
38 #endif
39 
40 static void OCIO_reportError(const char *err)
41 {
42  std::cerr << "OpenColorIO Error: " << err << std::endl;
43 
44  OCIO_abort();
45 }
46 
47 static void OCIO_reportException(Exception &exception)
48 {
49  OCIO_reportError(exception.what());
50 }
51 
52 OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
53 {
54  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
55 
56  try {
57  *config = GetCurrentConfig();
58 
59  if (*config)
60  return (OCIO_ConstConfigRcPtr *)config;
61  }
62  catch (Exception &exception) {
63  OCIO_reportException(exception);
64  }
65 
66  MEM_delete(config);
67 
68  return NULL;
69 }
70 
71 void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
72 {
73  try {
74  SetCurrentConfig(*(ConstConfigRcPtr *)config);
75  }
76  catch (Exception &exception) {
77  OCIO_reportException(exception);
78  }
79 }
80 
81 OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
82 {
83  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
84 
85  try {
86  *config = Config::CreateFromEnv();
87 
88  if (*config)
89  return (OCIO_ConstConfigRcPtr *)config;
90  }
91  catch (Exception &exception) {
92  OCIO_reportException(exception);
93  }
94 
95  MEM_delete(config);
96 
97  return NULL;
98 }
99 
100 OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
101 {
102  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
103 
104  try {
105  *config = Config::CreateFromFile(filename);
106 
107  if (*config)
108  return (OCIO_ConstConfigRcPtr *)config;
109  }
110  catch (Exception &exception) {
111  OCIO_reportException(exception);
112  }
113 
114  MEM_delete(config);
115 
116  return NULL;
117 }
118 
119 void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
120 {
121  MEM_delete((ConstConfigRcPtr *)config);
122 }
123 
124 int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
125 {
126  try {
127  return (*(ConstConfigRcPtr *)config)->getNumColorSpaces();
128  }
129  catch (Exception &exception) {
130  OCIO_reportException(exception);
131  }
132 
133  return 0;
134 }
135 
136 const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
137 {
138  try {
139  return (*(ConstConfigRcPtr *)config)->getColorSpaceNameByIndex(index);
140  }
141  catch (Exception &exception) {
142  OCIO_reportException(exception);
143  }
144 
145  return NULL;
146 }
147 
148 OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config,
149  const char *name)
150 {
151  ConstColorSpaceRcPtr *cs = MEM_new<ConstColorSpaceRcPtr>(__func__);
152 
153  try {
154  *cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
155 
156  if (*cs)
157  return (OCIO_ConstColorSpaceRcPtr *)cs;
158  }
159  catch (Exception &exception) {
160  OCIO_reportException(exception);
161  }
162 
163  MEM_delete(cs);
164 
165  return NULL;
166 }
167 
168 int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
169 {
170  try {
171  return (*(ConstConfigRcPtr *)config)->getIndexForColorSpace(name);
172  }
173  catch (Exception &exception) {
174  OCIO_reportException(exception);
175  }
176 
177  return -1;
178 }
179 
180 const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config)
181 {
182  try {
183  return (*(ConstConfigRcPtr *)config)->getDefaultDisplay();
184  }
185  catch (Exception &exception) {
186  OCIO_reportException(exception);
187  }
188 
189  return NULL;
190 }
191 
192 int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr *config)
193 {
194  try {
195  return (*(ConstConfigRcPtr *)config)->getNumDisplays();
196  }
197  catch (Exception &exception) {
198  OCIO_reportException(exception);
199  }
200 
201  return 0;
202 }
203 
204 const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index)
205 {
206  try {
207  return (*(ConstConfigRcPtr *)config)->getDisplay(index);
208  }
209  catch (Exception &exception) {
210  OCIO_reportException(exception);
211  }
212 
213  return NULL;
214 }
215 
216 const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display)
217 {
218  try {
219  return (*(ConstConfigRcPtr *)config)->getDefaultView(display);
220  }
221  catch (Exception &exception) {
222  OCIO_reportException(exception);
223  }
224 
225  return NULL;
226 }
227 
228 int OCIOImpl::configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display)
229 {
230  try {
231  return (*(ConstConfigRcPtr *)config)->getNumViews(display);
232  }
233  catch (Exception &exception) {
234  OCIO_reportException(exception);
235  }
236 
237  return 0;
238 }
239 
240 const char *OCIOImpl::configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index)
241 {
242  try {
243  return (*(ConstConfigRcPtr *)config)->getView(display, index);
244  }
245  catch (Exception &exception) {
246  OCIO_reportException(exception);
247  }
248 
249  return NULL;
250 }
251 
252 const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
253  const char *display,
254  const char *view)
255 {
256  try {
257  const char *name = (*(ConstConfigRcPtr *)config)->getDisplayViewColorSpaceName(display, view);
258  /* OpenColorIO does not resolve this token for us, so do it ourselves. */
259  if (strcasecmp(name, "<USE_DISPLAY_NAME>") == 0) {
260  return display;
261  }
262  return name;
263  }
264  catch (Exception &exception) {
265  OCIO_reportException(exception);
266  }
267 
268  return NULL;
269 }
270 
271 void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
272 {
273  try {
274  double rgb_double[3];
275  (*(ConstConfigRcPtr *)config)->getDefaultLumaCoefs(rgb_double);
276  rgb[0] = rgb_double[0];
277  rgb[1] = rgb_double[1];
278  rgb[2] = rgb_double[2];
279  }
280  catch (Exception &exception) {
281  OCIO_reportException(exception);
282  }
283 }
284 
285 static bool to_scene_linear_matrix(ConstConfigRcPtr &config,
286  const char *colorspace,
287  float to_scene_linear[3][3])
288 {
289  ConstProcessorRcPtr processor;
290  try {
291  processor = config->getProcessor(colorspace, ROLE_SCENE_LINEAR);
292  }
293  catch (Exception &exception) {
294  OCIO_reportException(exception);
295  return false;
296  }
297 
298  if (!processor) {
299  return false;
300  }
301 
302  ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
303  if (!cpu_processor) {
304  return false;
305  }
306 
307  unit_m3(to_scene_linear);
308  cpu_processor->applyRGB(to_scene_linear[0]);
309  cpu_processor->applyRGB(to_scene_linear[1]);
310  cpu_processor->applyRGB(to_scene_linear[2]);
311  return true;
312 }
313 
314 void OCIOImpl::configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config_,
315  float xyz_to_scene_linear[3][3])
316 {
317  ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
318 
319  /* Default to ITU-BT.709 in case no appropriate transform found.
320  * Note XYZ is defined here as having a D65 white point. */
321  memcpy(xyz_to_scene_linear, OCIO_XYZ_TO_REC709, sizeof(OCIO_XYZ_TO_REC709));
322 
323  /* Get from OpenColorO config if it has the required roles. */
324  if (!config->hasRole(ROLE_SCENE_LINEAR)) {
325  return;
326  }
327 
328  if (config->hasRole("aces_interchange")) {
329  /* Standard OpenColorIO role, defined as ACES AP0 (ACES2065-1). */
330  float aces_to_scene_linear[3][3];
331  if (to_scene_linear_matrix(config, "aces_interchange", aces_to_scene_linear)) {
332  float xyz_to_aces[3][3];
333  invert_m3_m3(xyz_to_aces, OCIO_ACES_TO_XYZ);
334 
335  mul_m3_m3m3(xyz_to_scene_linear, aces_to_scene_linear, xyz_to_aces);
336  }
337  }
338  else if (config->hasRole("XYZ")) {
339  /* Custom role used before the standard existed. */
340  to_scene_linear_matrix(config, "XYZ", xyz_to_scene_linear);
341  }
342 }
343 
344 int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config)
345 {
346  try {
347  return (*(ConstConfigRcPtr *)config)->getNumLooks();
348  }
349  catch (Exception &exception) {
350  OCIO_reportException(exception);
351  }
352 
353  return 0;
354 }
355 
356 const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
357 {
358  try {
359  return (*(ConstConfigRcPtr *)config)->getLookNameByIndex(index);
360  }
361  catch (Exception &exception) {
362  OCIO_reportException(exception);
363  }
364 
365  return NULL;
366 }
367 
368 OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
369 {
370  ConstLookRcPtr *look = MEM_new<ConstLookRcPtr>(__func__);
371 
372  try {
373  *look = (*(ConstConfigRcPtr *)config)->getLook(name);
374 
375  if (*look)
376  return (OCIO_ConstLookRcPtr *)look;
377  }
378  catch (Exception &exception) {
379  OCIO_reportException(exception);
380  }
381 
382  MEM_delete(look);
383 
384  return NULL;
385 }
386 
387 const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
388 {
389  return (*(ConstLookRcPtr *)look)->getProcessSpace();
390 }
391 
392 void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
393 {
394  MEM_delete((ConstLookRcPtr *)look);
395 }
396 
397 int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
398 {
399  ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *)cs_;
400  const char *family = (*cs)->getFamily();
401 
402  if (!strcmp(family, "rrt") || !strcmp(family, "display")) {
403  /* assume display and rrt transformations are not invertible in fact some of them could be,
404  * but it doesn't make much sense to allow use them as invertible. */
405  return false;
406  }
407 
408  if ((*cs)->isData()) {
409  /* data color spaces don't have transformation at all */
410  return true;
411  }
412 
413  if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) {
414  /* if there's defined transform to reference space,
415  * color space could be converted to scene linear. */
416  return true;
417  }
418 
419  return true;
420 }
421 
422 int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
423 {
424  return (*(ConstColorSpaceRcPtr *)cs)->isData();
425 }
426 
427 static float compare_floats(float a, float b, float abs_diff, int ulp_diff)
428 {
429  /* Returns true if the absolute difference is smaller than abs_diff (for numbers near zero)
430  * or their relative difference is less than ulp_diff ULPs. Based on:
431  * https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ */
432  if (fabsf(a - b) < abs_diff) {
433  return true;
434  }
435 
436  if ((a < 0.0f) != (b < 0.0f)) {
437  return false;
438  }
439 
440  return (abs((*(int *)&a) - (*(int *)&b)) < ulp_diff);
441 }
442 
443 void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
444  OCIO_ConstColorSpaceRcPtr *cs_,
445  bool &is_scene_linear,
446  bool &is_srgb)
447 {
448  ConstConfigRcPtr *config = (ConstConfigRcPtr *)config_;
449  ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *)cs_;
450  ConstProcessorRcPtr processor;
451 
452  try {
453  processor = (*config)->getProcessor((*cs)->getName(), "scene_linear");
454  }
455  catch (Exception &) {
456  /* Silently ignore if no conversion possible, then it's not scene linear or sRGB. */
457  is_scene_linear = false;
458  is_srgb = false;
459  return;
460  }
461 
462  ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
463 
464  is_scene_linear = true;
465  is_srgb = true;
466  for (int i = 0; i < 256; i++) {
467  float v = i / 255.0f;
468 
469  float cR[3] = {v, 0, 0};
470  float cG[3] = {0, v, 0};
471  float cB[3] = {0, 0, v};
472  float cW[3] = {v, v, v};
473  cpu_processor->applyRGB(cR);
474  cpu_processor->applyRGB(cG);
475  cpu_processor->applyRGB(cB);
476  cpu_processor->applyRGB(cW);
477 
478  /* Make sure that there is no channel crosstalk. */
479  if (fabsf(cR[1]) > 1e-5f || fabsf(cR[2]) > 1e-5f || fabsf(cG[0]) > 1e-5f ||
480  fabsf(cG[2]) > 1e-5f || fabsf(cB[0]) > 1e-5f || fabsf(cB[1]) > 1e-5f) {
481  is_scene_linear = false;
482  is_srgb = false;
483  break;
484  }
485  /* Make sure that the three primaries combine linearly. */
486  if (!compare_floats(cR[0], cW[0], 1e-6f, 64) || !compare_floats(cG[1], cW[1], 1e-6f, 64) ||
487  !compare_floats(cB[2], cW[2], 1e-6f, 64)) {
488  is_scene_linear = false;
489  is_srgb = false;
490  break;
491  }
492  /* Make sure that the three channels behave identically. */
493  if (!compare_floats(cW[0], cW[1], 1e-6f, 64) || !compare_floats(cW[1], cW[2], 1e-6f, 64)) {
494  is_scene_linear = false;
495  is_srgb = false;
496  break;
497  }
498 
499  float out_v = (cW[0] + cW[1] + cW[2]) * (1.0f / 3.0f);
500  if (!compare_floats(v, out_v, 1e-6f, 64)) {
501  is_scene_linear = false;
502  }
503  if (!compare_floats(srgb_to_linearrgb(v), out_v, 1e-6f, 64)) {
504  is_srgb = false;
505  }
506  }
507 }
508 
509 void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
510 {
511  MEM_delete((ConstColorSpaceRcPtr *)cs);
512 }
513 
514 OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
515  const char *srcName,
516  const char *dstName)
517 {
518  ConstProcessorRcPtr *processor = MEM_new<ConstProcessorRcPtr>(__func__);
519 
520  try {
521  *processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
522 
523  if (*processor)
524  return (OCIO_ConstProcessorRcPtr *)processor;
525  }
526  catch (Exception &exception) {
527  OCIO_reportException(exception);
528  }
529 
530  MEM_delete(processor);
531 
532  return 0;
533 }
534 
535 void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
536 {
537  MEM_delete(processor);
538 }
539 
540 OCIO_ConstCPUProcessorRcPtr *OCIOImpl::processorGetCPUProcessor(
541  OCIO_ConstProcessorRcPtr *processor)
542 {
543  ConstCPUProcessorRcPtr *cpu_processor = MEM_new<ConstCPUProcessorRcPtr>(__func__);
544  *cpu_processor = (*(ConstProcessorRcPtr *)processor)->getDefaultCPUProcessor();
545  return (OCIO_ConstCPUProcessorRcPtr *)cpu_processor;
546 }
547 
548 void OCIOImpl::cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
549  OCIO_PackedImageDesc *img)
550 {
551  try {
552  (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*(PackedImageDesc *)img);
553  }
554  catch (Exception &exception) {
555  OCIO_reportException(exception);
556  }
557 }
558 
559 void OCIOImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
560  OCIO_PackedImageDesc *img_)
561 {
562  try {
563  PackedImageDesc *img = (PackedImageDesc *)img_;
564  int channels = img->getNumChannels();
565 
566  if (channels == 4) {
567  assert(img->isFloat());
568  float *pixels = (float *)img->getData();
569 
570  size_t width = img->getWidth();
571  size_t height = img->getHeight();
572 
573  for (int y = 0; y < height; y++) {
574  for (int x = 0; x < width; x++) {
575  float *pixel = pixels + 4 * (y * width + x);
576 
577  cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
578  }
579  }
580  }
581  else {
582  (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*img);
583  }
584  }
585  catch (Exception &exception) {
586  OCIO_reportException(exception);
587  }
588 }
589 
590 void OCIOImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
591 {
592  (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGB(pixel);
593 }
594 
595 void OCIOImpl::cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
596 {
597  (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
598 }
599 
600 void OCIOImpl::cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
601  float *pixel)
602 {
603  if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
604  (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
605  }
606  else {
607  float alpha, inv_alpha;
608 
609  alpha = pixel[3];
610  inv_alpha = 1.0f / alpha;
611 
612  pixel[0] *= inv_alpha;
613  pixel[1] *= inv_alpha;
614  pixel[2] *= inv_alpha;
615 
616  (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
617 
618  pixel[0] *= alpha;
619  pixel[1] *= alpha;
620  pixel[2] *= alpha;
621  }
622 }
623 
624 void OCIOImpl::cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
625 {
626  MEM_delete(cpu_processor);
627 }
628 
629 const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
630 {
631  return (*(ConstColorSpaceRcPtr *)cs)->getName();
632 }
633 
634 const char *OCIOImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs)
635 {
636  return (*(ConstColorSpaceRcPtr *)cs)->getDescription();
637 }
638 
639 const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
640 {
641  return (*(ConstColorSpaceRcPtr *)cs)->getFamily();
642 }
643 
644 int OCIOImpl::colorSpaceGetNumAliases(OCIO_ConstColorSpaceRcPtr *cs)
645 {
646  return (*(ConstColorSpaceRcPtr *)cs)->getNumAliases();
647 }
648 const char *OCIOImpl::colorSpaceGetAlias(OCIO_ConstColorSpaceRcPtr *cs, const int index)
649 {
650  return (*(ConstColorSpaceRcPtr *)cs)->getAlias(index);
651 }
652 
653 OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr *config_,
654  const char *input,
655  const char *view,
656  const char *display,
657  const char *look,
658  const float scale,
659  const float exponent,
660  const bool inverse)
661 
662 {
663  ConstConfigRcPtr config = *(ConstConfigRcPtr *)config_;
664  GroupTransformRcPtr group = GroupTransform::Create();
665 
666  /* Exposure. */
667  if (scale != 1.0f) {
668  /* Always apply exposure in scene linear. */
669  ColorSpaceTransformRcPtr ct = ColorSpaceTransform::Create();
670  ct->setSrc(input);
671  ct->setDst(ROLE_SCENE_LINEAR);
672  group->appendTransform(ct);
673 
674  /* Make further transforms aware of the color space change. */
675  input = ROLE_SCENE_LINEAR;
676 
677  /* Apply scale. */
678  MatrixTransformRcPtr mt = MatrixTransform::Create();
679  const double matrix[16] = {
680  scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, 1.0};
681  mt->setMatrix(matrix);
682  group->appendTransform(mt);
683  }
684 
685  /* Add look transform. */
686  bool use_look = (look != nullptr && look[0] != 0);
687  if (use_look) {
688  const char *look_output = LookTransform::GetLooksResultColorSpace(
689  config, config->getCurrentContext(), look);
690 
691  if (look_output != nullptr && look_output[0] != 0) {
692  LookTransformRcPtr lt = LookTransform::Create();
693  lt->setSrc(input);
694  lt->setDst(look_output);
695  lt->setLooks(look);
696  group->appendTransform(lt);
697 
698  /* Make further transforms aware of the color space change. */
699  input = look_output;
700  }
701  else {
702  /* For empty looks, no output color space is returned. */
703  use_look = false;
704  }
705  }
706 
707  /* Add view and display transform. */
708  DisplayViewTransformRcPtr dvt = DisplayViewTransform::Create();
709  dvt->setSrc(input);
710  dvt->setLooksBypass(use_look);
711  dvt->setView(view);
712  dvt->setDisplay(display);
713  group->appendTransform(dvt);
714 
715  /* Gamma. */
716  if (exponent != 1.0f) {
717  ExponentTransformRcPtr et = ExponentTransform::Create();
718  const double value[4] = {exponent, exponent, exponent, 1.0};
719  et->setValue(value);
720  group->appendTransform(et);
721  }
722 
723  if (inverse) {
724  group->setDirection(TRANSFORM_DIR_INVERSE);
725  }
726 
727  /* Create processor from transform. This is the moment were OCIO validates
728  * the entire transform, no need to check for the validity of inputs above. */
729  ConstProcessorRcPtr *p = MEM_new<ConstProcessorRcPtr>(__func__);
730 
731  try {
732  *p = config->getProcessor(group);
733 
734  if (*p)
735  return (OCIO_ConstProcessorRcPtr *)p;
736  }
737  catch (Exception &exception) {
738  OCIO_reportException(exception);
739  }
740 
741  MEM_delete(p);
742  return NULL;
743 }
744 
745 OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data,
746  long width,
747  long height,
748  long numChannels,
749  long chanStrideBytes,
750  long xStrideBytes,
751  long yStrideBytes)
752 {
753  try {
754  void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
755  PackedImageDesc *id = new (mem) PackedImageDesc(data,
756  width,
757  height,
758  numChannels,
759  BIT_DEPTH_F32,
760  chanStrideBytes,
761  xStrideBytes,
762  yStrideBytes);
763 
764  return (OCIO_PackedImageDesc *)id;
765  }
766  catch (Exception &exception) {
767  OCIO_reportException(exception);
768  }
769 
770  return NULL;
771 }
772 
773 void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
774 {
775  MEM_delete((PackedImageDesc *)id);
776 }
777 
778 const char *OCIOImpl::getVersionString(void)
779 {
780  return GetVersion();
781 }
782 
783 int OCIOImpl::getVersionHex(void)
784 {
785  return GetVersionHex();
786 }
float srgb_to_linearrgb(float c)
Definition: math_color.c:403
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
static AppView * view
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 y
_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
Read Guarded memory(de)allocation.
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
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btTransform.h:182
ccl_global KernelShaderEvalInput * input
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned a[3]
Definition: RandGen.cpp:78
T abs(const T &a)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken rgb("rgb", pxr::TfToken::Immortal)
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
Definition: ocio_capi.cc:272
static const float OCIO_XYZ_TO_REC709[3][3]
Definition: ocio_capi.h:35
static const float OCIO_ACES_TO_XYZ[3][3]
Definition: ocio_capi.h:40
static void OCIO_reportException(Exception &exception)
Definition: ocio_impl.cc:47
static bool to_scene_linear_matrix(ConstConfigRcPtr &config, const char *colorspace, float to_scene_linear[3][3])
Definition: ocio_impl.cc:285
static void OCIO_reportError(const char *err)
Definition: ocio_impl.cc:40
static float compare_floats(float a, float b, float abs_diff, int ulp_diff)
Definition: ocio_impl.cc:427
#define OCIO_abort()
Definition: ocio_impl.cc:30
static FT_Error err