13# pragma warning(disable : 4251 4275)
15#include <OpenColorIO/OpenColorIO.h>
20using namespace OCIO_NAMESPACE;
31#if !defined(WITH_ASSERT_ABORT)
35# define OCIO_abort() abort()
39# define __func__ __FUNCTION__
48 std::cerr <<
"OpenColorIO Error: " << err << std::endl;
58OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(
void)
60 ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
63 *config = GetCurrentConfig();
66 return (OCIO_ConstConfigRcPtr *)config;
69 catch (Exception &exception) {
78void OCIOImpl::setCurrentConfig(
const OCIO_ConstConfigRcPtr *config)
81 SetCurrentConfig(*(ConstConfigRcPtr *)config);
83 catch (Exception &exception) {
88OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(
void)
90 ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
93 *config = Config::CreateFromEnv();
96 return (OCIO_ConstConfigRcPtr *)config;
99 catch (Exception &exception) {
108OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(
const char *filename)
110 ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
113 *config = Config::CreateFromFile(filename);
116 return (OCIO_ConstConfigRcPtr *)config;
119 catch (Exception &exception) {
128void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
130 MEM_delete((ConstConfigRcPtr *)config);
133int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
136 return (*(ConstConfigRcPtr *)config)->getNumColorSpaces();
138 catch (Exception &exception) {
145const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config,
int index)
148 return (*(ConstConfigRcPtr *)config)->getColorSpaceNameByIndex(index);
150 catch (Exception &exception) {
157OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config,
160 ConstColorSpaceRcPtr *cs = MEM_new<ConstColorSpaceRcPtr>(__func__);
163 *cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
166 return (OCIO_ConstColorSpaceRcPtr *)cs;
169 catch (Exception &exception) {
178int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config,
const char *name)
181 return (*(ConstConfigRcPtr *)config)->getIndexForColorSpace(name);
183 catch (Exception &exception) {
190const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config)
193 return (*(ConstConfigRcPtr *)config)->getDefaultDisplay();
195 catch (Exception &exception) {
202int OCIOImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr *config)
205 return (*(ConstConfigRcPtr *)config)->getNumDisplays();
207 catch (Exception &exception) {
214const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config,
int index)
217 return (*(ConstConfigRcPtr *)config)->getDisplay(index);
219 catch (Exception &exception) {
226const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config,
const char *display)
229 return (*(ConstConfigRcPtr *)config)->getDefaultView(display);
231 catch (Exception &exception) {
238int OCIOImpl::configGetNumViews(OCIO_ConstConfigRcPtr *config,
const char *display)
241 return (*(ConstConfigRcPtr *)config)->getNumViews(display);
243 catch (Exception &exception) {
250const char *OCIOImpl::configGetView(OCIO_ConstConfigRcPtr *config,
const char *display,
int index)
253 return (*(ConstConfigRcPtr *)config)->getView(display, index);
255 catch (Exception &exception) {
262const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
267 const char *name = (*(ConstConfigRcPtr *)config)->getDisplayViewColorSpaceName(display, view);
269 if (strcasecmp(name,
"<USE_DISPLAY_NAME>") == 0) {
274 catch (Exception &exception) {
281void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config,
float *rgb)
284 double rgb_double[3];
285 (*(ConstConfigRcPtr *)config)->getDefaultLumaCoefs(rgb_double);
286 rgb[0] = rgb_double[0];
287 rgb[1] = rgb_double[1];
288 rgb[2] = rgb_double[2];
290 catch (Exception &exception) {
296 const char *colorspace,
297 float to_scene_linear[3][3])
299 ConstProcessorRcPtr processor;
301 processor = config->getProcessor(colorspace, ROLE_SCENE_LINEAR);
303 catch (Exception &exception) {
312 ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
313 if (!cpu_processor) {
318 cpu_processor->applyRGB(to_scene_linear[0]);
319 cpu_processor->applyRGB(to_scene_linear[1]);
320 cpu_processor->applyRGB(to_scene_linear[2]);
324void OCIOImpl::configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config_,
325 float xyz_to_scene_linear[3][3])
327 ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
334 if (!config->hasRole(ROLE_SCENE_LINEAR)) {
338 if (config->hasRole(
"aces_interchange")) {
340 float aces_to_scene_linear[3][3];
342 float xyz_to_aces[3][3];
345 mul_m3_m3m3(xyz_to_scene_linear, aces_to_scene_linear, xyz_to_aces);
348 else if (config->hasRole(
"XYZ")) {
354int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config)
357 return (*(ConstConfigRcPtr *)config)->getNumLooks();
359 catch (Exception &exception) {
366const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config,
int index)
369 return (*(ConstConfigRcPtr *)config)->getLookNameByIndex(index);
371 catch (Exception &exception) {
378OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config,
const char *name)
380 ConstLookRcPtr *look = MEM_new<ConstLookRcPtr>(__func__);
383 *look = (*(ConstConfigRcPtr *)config)->getLook(name);
386 return (OCIO_ConstLookRcPtr *)look;
389 catch (Exception &exception) {
398const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
400 return (*(ConstLookRcPtr *)look)->getProcessSpace();
403void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
405 MEM_delete((ConstLookRcPtr *)look);
408int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
410 ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *)cs_;
411 const char *family = (*cs)->getFamily();
413 if (!strcmp(family,
"rrt") || !strcmp(family,
"display")) {
419 if ((*cs)->isData()) {
424 if ((*cs)->getTransform(COLORSPACE_DIR_TO_REFERENCE)) {
433int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
435 return (*(ConstColorSpaceRcPtr *)cs)->isData();
443 if (
fabsf(a -
b) < abs_diff) {
447 if ((a < 0.0f) != (
b < 0.0f)) {
451 return (
abs((*(
int *)&a) - (*(
int *)&
b)) < ulp_diff);
454void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
455 OCIO_ConstColorSpaceRcPtr *cs_,
456 bool &is_scene_linear,
459 ConstConfigRcPtr *config = (ConstConfigRcPtr *)config_;
460 ConstColorSpaceRcPtr *cs = (ConstColorSpaceRcPtr *)cs_;
461 ConstProcessorRcPtr processor;
464 processor = (*config)->getProcessor((*cs)->getName(),
"scene_linear");
466 catch (Exception &) {
468 is_scene_linear =
false;
473 ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
475 is_scene_linear =
true;
477 for (
int i = 0; i < 256; i++) {
478 float v = i / 255.0f;
480 float cR[3] = {
v, 0, 0};
481 float cG[3] = {0,
v, 0};
482 float cB[3] = {0, 0,
v};
483 float cW[3] = {
v,
v,
v};
484 cpu_processor->applyRGB(cR);
485 cpu_processor->applyRGB(cG);
486 cpu_processor->applyRGB(cB);
487 cpu_processor->applyRGB(cW);
490 if (
fabsf(cR[1]) > 1e-5f ||
fabsf(cR[2]) > 1e-5f ||
fabsf(cG[0]) > 1e-5f ||
493 is_scene_linear =
false;
501 is_scene_linear =
false;
507 is_scene_linear =
false;
512 float out_v = (cW[0] + cW[1] + cW[2]) * (1.0f / 3.0f);
514 is_scene_linear =
false;
522void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
524 MEM_delete((ConstColorSpaceRcPtr *)cs);
527OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
531 ConstProcessorRcPtr *processor = MEM_new<ConstProcessorRcPtr>(__func__);
534 *processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
537 return (OCIO_ConstProcessorRcPtr *)processor;
540 catch (Exception &exception) {
544 MEM_delete(processor);
549void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
551 MEM_delete(processor);
555 OCIO_ConstProcessorRcPtr *processor)
557 ConstCPUProcessorRcPtr *cpu_processor = MEM_new<ConstCPUProcessorRcPtr>(__func__);
558 *cpu_processor = (*(ConstProcessorRcPtr *)processor)->getDefaultCPUProcessor();
563 OCIO_PackedImageDesc *img)
566 (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*(PackedImageDesc *)img);
568 catch (Exception &exception) {
574 OCIO_PackedImageDesc *img_)
577 PackedImageDesc *img = (PackedImageDesc *)img_;
578 int channels = img->getNumChannels();
582 assert(img->isFloat());
583 float *pixel = (
float *)img->getData();
584 size_t pixel_count = img->getWidth() * img->getHeight();
585 for (
size_t i = 0; i < pixel_count; i++, pixel += 4) {
586 float alpha = pixel[3];
587 if (alpha != 0.0f && alpha != 1.0f) {
588 float inv_alpha = 1.0f / alpha;
589 pixel[0] *= inv_alpha;
590 pixel[1] *= inv_alpha;
591 pixel[2] *= inv_alpha;
596 (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*img);
600 assert(img->isFloat());
601 float *pixel = (
float *)img->getData();
602 size_t pixel_count = img->getWidth() * img->getHeight();
603 for (
size_t i = 0; i < pixel_count; i++, pixel += 4) {
604 float alpha = pixel[3];
605 if (alpha != 0.0f && alpha != 1.0f) {
613 catch (Exception &exception) {
620 return (*(ConstCPUProcessorRcPtr *)cpu_processor)->isNoOp();
625 (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGB(pixel);
630 (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
636 if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
637 (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
640 float alpha, inv_alpha;
643 inv_alpha = 1.0f / alpha;
645 pixel[0] *= inv_alpha;
646 pixel[1] *= inv_alpha;
647 pixel[2] *= inv_alpha;
649 (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
659 MEM_delete(cpu_processor);
662const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
664 return (*(ConstColorSpaceRcPtr *)cs)->getName();
667const char *OCIOImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs)
669 return (*(ConstColorSpaceRcPtr *)cs)->getDescription();
672const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
674 return (*(ConstColorSpaceRcPtr *)cs)->getFamily();
677int OCIOImpl::colorSpaceGetNumAliases(OCIO_ConstColorSpaceRcPtr *cs)
679 return (*(ConstColorSpaceRcPtr *)cs)->getNumAliases();
681const char *OCIOImpl::colorSpaceGetAlias(OCIO_ConstColorSpaceRcPtr *cs,
const int index)
683 return (*(ConstColorSpaceRcPtr *)cs)->getAlias(index);
686OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr *config_,
692 const float exponent,
693 const float temperature,
695 const bool use_white_balance,
699 ConstConfigRcPtr config = *(ConstConfigRcPtr *)config_;
700 GroupTransformRcPtr group = GroupTransform::Create();
703 if (scale != 1.0f || use_white_balance) {
705 ColorSpaceTransformRcPtr ct = ColorSpaceTransform::Create();
707 ct->setDst(ROLE_SCENE_LINEAR);
708 group->appendTransform(ct);
711 input = ROLE_SCENE_LINEAR;
714 MatrixTransformRcPtr mt = MatrixTransform::Create();
715 float3x3 matrix = float3x3::identity() * scale;
718 if (use_white_balance) {
721 configGetXYZtoSceneLinear(config_, xyz_to_scene.ptr());
728 matrix *= xyz_to_scene;
731 matrix *= scene_to_xyz;
735 group->appendTransform(mt);
739 bool use_look = (look !=
nullptr && look[0] != 0);
741 const char *look_output = LookTransform::GetLooksResultColorSpace(
742 config, config->getCurrentContext(), look);
744 if (look_output !=
nullptr && look_output[0] != 0) {
745 LookTransformRcPtr lt = LookTransform::Create();
747 lt->setDst(look_output);
749 group->appendTransform(lt);
761 DisplayViewTransformRcPtr dvt = DisplayViewTransform::Create();
763 dvt->setLooksBypass(use_look);
765 dvt->setDisplay(display);
766 group->appendTransform(dvt);
769 if (exponent != 1.0f) {
770 ExponentTransformRcPtr et = ExponentTransform::Create();
771 const double value[4] = {exponent, exponent, exponent, 1.0};
773 group->appendTransform(et);
777 group->setDirection(TRANSFORM_DIR_INVERSE);
782 ConstProcessorRcPtr *p = MEM_new<ConstProcessorRcPtr>(__func__);
785 *p = config->getProcessor(group);
788 return (OCIO_ConstProcessorRcPtr *)p;
791 catch (Exception &exception) {
799OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(
float *data,
803 long chanStrideBytes,
808 void *mem =
MEM_mallocN(
sizeof(PackedImageDesc), __func__);
809 PackedImageDesc *
id =
new (mem) PackedImageDesc(data,
818 return (OCIO_PackedImageDesc *)id;
820 catch (Exception &exception) {
827void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *
id)
829 MEM_delete((PackedImageDesc *)
id);
832const char *OCIOImpl::getVersionString(
void)
837int OCIOImpl::getVersionHex(
void)
839 return GetVersionHex();
float srgb_to_linearrgb(float c)
void unit_m3(float m[3][3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
struct OCIO_ConstCPUProcessorRc * OCIO_ConstCPUProcessorRcPtr
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
btMatrix3x3 inverse() const
Return the inverse of the matrix.
local_group_size(16, 16) .push_constant(Type b
void *(* MEM_mallocN)(size_t len, const char *str)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
float3 whitepoint_from_temp_tint(float temperature, float tint)
CartesianBasis invert(const CartesianBasis &basis)
float3x3 chromatic_adaption_matrix(const float3 &from_XYZ, const float3 &to_XYZ)
MatBase< float, 3, 3 > float3x3
MatBase< double, 4, 4 > double4x4
static const float OCIO_XYZ_TO_REC709[3][3]
static const float OCIO_ACES_TO_XYZ[3][3]
static void OCIO_reportException(Exception &exception)
static bool to_scene_linear_matrix(ConstConfigRcPtr &config, const char *colorspace, float to_scene_linear[3][3])
static void OCIO_reportError(const char *err)
static float compare_floats(float a, float b, float abs_diff, int ulp_diff)
ccl_device_inline int abs(int x)