Blender V4.3
fallback_impl.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <algorithm>
6#include <cstring>
7#include <vector>
8
9#include "BLI_math_color.h"
10#include "BLI_math_vector.h"
11#include "MEM_guardedalloc.h"
12
13#include "ocio_impl.h"
14
15using std::max;
16
17#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr *)1)
18
27
28#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr *)1)
29#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr *)2)
30#define COLORSPACE_DATA ((OCIO_ConstColorSpaceRcPtr *)3)
31
41
43 FallbackTransform() : type(TRANSFORM_UNKNOWN), scale(1.0f), exponent(1.0f) {}
44
45 virtual ~FallbackTransform() {}
46
47 void applyRGB(float *pixel)
48 {
49 if (type == TRANSFORM_LINEAR_TO_SRGB) {
50 pixel[0] *= scale;
51 pixel[1] *= scale;
52 pixel[2] *= scale;
53
54 linearrgb_to_srgb_v3_v3(pixel, pixel);
55
56 pixel[0] = powf(max(0.0f, pixel[0]), exponent);
57 pixel[1] = powf(max(0.0f, pixel[1]), exponent);
58 pixel[2] = powf(max(0.0f, pixel[2]), exponent);
59 }
60 else if (type == TRANSFORM_SRGB_TO_LINEAR) {
61 srgb_to_linearrgb_v3_v3(pixel, pixel);
62 }
63 else if (type == TRANSFORM_EXPONENT) {
64 pixel[0] = powf(max(0.0f, pixel[0]), exponent);
65 pixel[1] = powf(max(0.0f, pixel[1]), exponent);
66 pixel[2] = powf(max(0.0f, pixel[2]), exponent);
67 }
68 else if (type == TRANSFORM_SCALE) {
69 pixel[0] *= scale;
70 pixel[1] *= scale;
71 pixel[2] *= scale;
72 }
73 }
74
75 void applyRGBA(float *pixel)
76 {
77 applyRGB(pixel);
78 }
79
80 bool isNoOp()
81 {
82 /* Rely on the short-circuiting based on name-space comparison in the IMB_colormanagement. */
83 return false;
84 }
85
87 /* Scale transform. */
88 float scale;
89 /* Exponent transform. */
90 float exponent;
91
92 MEM_CXX_CLASS_ALLOC_FUNCS("FallbackTransform");
93};
94
96 FallbackProcessor(const FallbackTransform &transform) : transform(transform) {}
97
98 void applyRGB(float *pixel)
99 {
100 transform.applyRGB(pixel);
101 }
102
103 void applyRGBA(float *pixel)
104 {
105 transform.applyRGBA(pixel);
106 }
107
108 bool isNoOp()
109 {
110 return transform.isNoOp();
111 }
112
114
115 MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
116};
117
118OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig()
119{
120 return CONFIG_DEFAULT;
121}
122
123void FallbackImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr * /*config*/) {}
124
125OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromEnv()
126{
127 return NULL;
128}
129
130OCIO_ConstConfigRcPtr *FallbackImpl::configCreateFromFile(const char * /*filename*/)
131{
132 return CONFIG_DEFAULT;
133}
134
135void FallbackImpl::configRelease(OCIO_ConstConfigRcPtr * /*config*/) {}
136
137int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/)
138{
139 return 2;
140}
141
142const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
143 int index)
144{
145 if (index == 0) {
146 return "Linear";
147 }
148 else if (index == 1) {
149 return "sRGB";
150 }
151
152 return NULL;
153}
154
155OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
156 const char *name)
157{
158 if (strcmp(name, "scene_linear") == 0) {
159 return COLORSPACE_LINEAR;
160 }
161 else if (strcmp(name, "color_picking") == 0) {
162 return COLORSPACE_SRGB;
163 }
164 else if (strcmp(name, "texture_paint") == 0) {
165 return COLORSPACE_LINEAR;
166 }
167 else if (strcmp(name, "default_byte") == 0) {
168 return COLORSPACE_SRGB;
169 }
170 else if (strcmp(name, "default_float") == 0) {
171 return COLORSPACE_LINEAR;
172 }
173 else if (strcmp(name, "default_sequencer") == 0) {
174 return COLORSPACE_SRGB;
175 }
176 else if (strcmp(name, "Linear") == 0) {
177 return COLORSPACE_LINEAR;
178 }
179 else if (strcmp(name, "sRGB") == 0) {
180 return COLORSPACE_SRGB;
181 }
182 else if (strcmp(name, "data") == 0) {
183 return COLORSPACE_DATA;
184 }
185
186 return NULL;
187}
188
189int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
190{
191 OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name);
192
193 if (cs == COLORSPACE_LINEAR) {
194 return 0;
195 }
196 else if (cs == COLORSPACE_SRGB) {
197 return 1;
198 }
199 else if (cs == COLORSPACE_DATA) {
200 return 2;
201 }
202 return -1;
203}
204
205const char *FallbackImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr * /*config*/)
206{
207 return "sRGB";
208}
209
210int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/)
211{
212 return 1;
213}
214
215const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index)
216{
217 if (index == 0) {
218 return "sRGB";
219 }
220 return NULL;
221}
222
223const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/,
224 const char * /*display*/)
225{
226 return "Standard";
227}
228
229int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
230{
231 return 1;
232}
233
234const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/,
235 const char * /*display*/,
236 int index)
237{
238 if (index == 0) {
239 return "Standard";
240 }
241 return NULL;
242}
243
244const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/,
245 const char * /*display*/,
246 const char * /*view*/)
247{
248 return "sRGB";
249}
250
251void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb)
252{
253 /* Here we simply use the older Blender assumed primaries of
254 * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
255 * force stupid, but only plausible option given no color management
256 * system in place.
257 */
258
259 rgb[0] = 0.2126f;
260 rgb[1] = 0.7152f;
261 rgb[2] = 0.0722f;
262}
263
264void FallbackImpl::configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr * /*config*/,
265 float xyz_to_scene_linear[3][3])
266{
267 /* Default to ITU-BT.709. */
268 memcpy(xyz_to_scene_linear, OCIO_XYZ_TO_REC709, sizeof(OCIO_XYZ_TO_REC709));
269}
270
271int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/)
272{
273 return 0;
274}
275
276const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
277 int /*index*/)
278{
279 return "";
280}
281
282OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/,
283 const char * /*name*/)
284{
285 return NULL;
286}
287
288const char *FallbackImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr * /*look*/)
289{
290 return NULL;
291}
292
293void FallbackImpl::lookRelease(OCIO_ConstLookRcPtr * /*look*/) {}
294
295int FallbackImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr * /*cs*/)
296{
297 return 1;
298}
299
300int FallbackImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr * /*cs*/)
301{
302 return 0;
303}
304
305void FallbackImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr * /*config*/,
306 OCIO_ConstColorSpaceRcPtr *cs,
307 bool &is_scene_linear,
308 bool &is_srgb)
309{
310 if (cs == COLORSPACE_LINEAR) {
311 is_scene_linear = true;
312 is_srgb = false;
313 }
314 else if (cs == COLORSPACE_SRGB) {
315 is_scene_linear = false;
316 is_srgb = true;
317 }
318 else {
319 is_scene_linear = false;
320 is_srgb = false;
321 }
322}
323
324void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/) {}
325
326OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
327 const char *srcName,
328 const char *dstName)
329{
330 OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
331 OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
333 if (cs_src == COLORSPACE_DATA || cs_dst == COLORSPACE_DATA) {
334 transform.type = TRANSFORM_NONE;
335 }
336 else if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
337 transform.type = TRANSFORM_LINEAR_TO_SRGB;
338 }
339 else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
340 transform.type = TRANSFORM_SRGB_TO_LINEAR;
341 }
342 else {
343 transform.type = TRANSFORM_UNKNOWN;
344 }
345 return (OCIO_ConstProcessorRcPtr *)new FallbackProcessor(transform);
346}
347
349 OCIO_ConstProcessorRcPtr *processor)
350{
351 /* Just make a copy of the processor so that we are compatible with OCIO
352 * which does need it as a separate object. */
353 FallbackProcessor *fallback_processor = (FallbackProcessor *)processor;
354 return (OCIO_ConstCPUProcessorRcPtr *)new FallbackProcessor(*fallback_processor);
355}
356
357void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
358{
359 delete (FallbackProcessor *)(processor);
360}
361
363{
364 return ((FallbackProcessor *)cpu_processor)->isNoOp();
365}
366
368 OCIO_PackedImageDesc *img)
369{
370 /* OCIO_TODO stride not respected, channels must be 3 or 4 */
372 int channels = desc->numChannels;
373 float *pixels = desc->data;
374 int width = desc->width;
375 int height = desc->height;
376 int x, y;
377
378 for (y = 0; y < height; y++) {
379 for (x = 0; x < width; x++) {
380 float *pixel = pixels + channels * (y * width + x);
381
382 if (channels == 4) {
383 cpuProcessorApplyRGBA(cpu_processor, pixel);
384 }
385 else if (channels == 3) {
386 cpuProcessorApplyRGB(cpu_processor, pixel);
387 }
388 }
389 }
390}
391
393 OCIO_PackedImageDesc *img)
394{
395 /* OCIO_TODO stride not respected, channels must be 3 or 4 */
397 int channels = desc->numChannels;
398 float *pixels = desc->data;
399 int width = desc->width;
400 int height = desc->height;
401 int x, y;
402
403 for (y = 0; y < height; y++) {
404 for (x = 0; x < width; x++) {
405 float *pixel = pixels + channels * (y * width + x);
406
407 if (channels == 4) {
408 cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
409 }
410 else if (channels == 3) {
411 cpuProcessorApplyRGB(cpu_processor, pixel);
412 }
413 }
414 }
415}
416
418{
419 ((FallbackProcessor *)cpu_processor)->applyRGB(pixel);
420}
421
423{
424 ((FallbackProcessor *)cpu_processor)->applyRGBA(pixel);
425}
426
428 float *pixel)
429{
430 if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
431 cpuProcessorApplyRGBA(cpu_processor, pixel);
432 }
433 else {
434 float alpha, inv_alpha;
435
436 alpha = pixel[3];
437 inv_alpha = 1.0f / alpha;
438
439 pixel[0] *= inv_alpha;
440 pixel[1] *= inv_alpha;
441 pixel[2] *= inv_alpha;
442
443 cpuProcessorApplyRGBA(cpu_processor, pixel);
444
445 pixel[0] *= alpha;
446 pixel[1] *= alpha;
447 pixel[2] *= alpha;
448 }
449}
450
452{
453 delete (FallbackProcessor *)(cpu_processor);
454}
455
456const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
457{
458 if (cs == COLORSPACE_LINEAR) {
459 return "Linear";
460 }
461 else if (cs == COLORSPACE_SRGB) {
462 return "sRGB";
463 }
464 else if (cs == COLORSPACE_DATA) {
465 return "data";
466 }
467 return NULL;
468}
469
470const char *FallbackImpl::colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr * /*cs*/)
471{
472 return "";
473}
474
475const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr * /*cs*/)
476{
477 return "";
478}
479
480int FallbackImpl::colorSpaceGetNumAliases(OCIO_ConstColorSpaceRcPtr * /*cs*/)
481{
482 return 0;
483}
484const char *FallbackImpl::colorSpaceGetAlias(OCIO_ConstColorSpaceRcPtr * /*cs*/,
485 const int /*index*/)
486{
487 return "";
488}
489
490OCIO_ConstProcessorRcPtr *FallbackImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr * /*config*/,
491 const char * /*input*/,
492 const char * /*view*/,
493 const char * /*display*/,
494 const char * /*look*/,
495 const float scale,
496 const float exponent,
497 const float /*temperature*/,
498 const float /*tint*/,
499 const bool /*use_white_balance*/,
500 const bool inverse)
501{
504 transform.scale = (inverse && scale != 0.0f) ? 1.0f / scale : scale;
505 transform.exponent = (inverse && exponent != 0.0f) ? 1.0f / exponent : exponent;
506
507 return (OCIO_ConstProcessorRcPtr *)new FallbackProcessor(transform);
508}
509
510OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data,
511 long width,
512 long height,
513 long numChannels,
514 long chanStrideBytes,
515 long xStrideBytes,
516 long yStrideBytes)
517{
518 OCIO_PackedImageDescription *desc = MEM_cnew<OCIO_PackedImageDescription>(
519 "OCIO_PackedImageDescription");
520 desc->data = data;
521 desc->width = width;
522 desc->height = height;
523 desc->numChannels = numChannels;
524 desc->chanStrideBytes = chanStrideBytes;
525 desc->xStrideBytes = xStrideBytes;
526 desc->yStrideBytes = yStrideBytes;
527 return (OCIO_PackedImageDesc *)desc;
528}
529
530void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
531{
532 MEM_freeN(id);
533}
534
536{
537 return "fallback";
538}
539
541{
542 return 0;
543}
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
struct OCIO_ConstCPUProcessorRc * OCIO_ConstCPUProcessorRcPtr
Read Guarded memory(de)allocation.
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
btMatrix3x3 inverse() const
Return the inverse of the matrix.
const char * colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
int configGetNumDisplays(OCIO_ConstConfigRcPtr *config)
const char * configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index)
int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
const char * configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config)
void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
const char * configGetDisplay(OCIO_ConstConfigRcPtr *config, int index)
void configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config, float xyz_to_scene_linear[3][3])
void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
int colorSpaceGetNumAliases(OCIO_ConstColorSpaceRcPtr *cs)
const char * getVersionString(void)
OCIO_ConstProcessorRcPtr * createDisplayProcessor(OCIO_ConstConfigRcPtr *config, const char *input, const char *view, const char *display, const char *look, const float scale, const float exponent, const float temperature, const float tint, const bool use_white_balance, const bool inverse)
void processorRelease(OCIO_ConstProcessorRcPtr *processor)
void setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
int getVersionHex(void)
OCIO_PackedImageDesc * createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, long chanStrideBytes, long xStrideBytes, long yStrideBytes)
OCIO_ConstConfigRcPtr * configCreateFromEnv(void)
OCIO_ConstConfigRcPtr * getCurrentConfig(void)
const char * configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display)
void configRelease(OCIO_ConstConfigRcPtr *config)
void lookRelease(OCIO_ConstLookRcPtr *look)
OCIO_ConstColorSpaceRcPtr * configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
const char * colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
const char * configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config, const char *display, const char *view)
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p)
void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img)
void cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
const char * colorSpaceGetAlias(OCIO_ConstColorSpaceRcPtr *cs, const int index)
int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs)
const char * colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs)
void cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
void cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img)
const char * lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
void colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config, OCIO_ConstColorSpaceRcPtr *cs, bool &is_scene_linear, bool &is_srgb)
int configGetNumLooks(OCIO_ConstConfigRcPtr *config)
OCIO_ConstConfigRcPtr * configCreateFromFile(const char *filename)
const char * configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
void cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
OCIO_ConstCPUProcessorRcPtr * processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor)
OCIO_ConstProcessorRcPtr * configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display)
OCIO_ConstLookRcPtr * configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
const char * configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index)
bool cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
#define powf(x, y)
#define NULL
#define COLORSPACE_LINEAR
#define CONFIG_DEFAULT
#define COLORSPACE_DATA
TransformType
@ TRANSFORM_NONE
@ TRANSFORM_UNKNOWN
@ TRANSFORM_SRGB_TO_LINEAR
@ TRANSFORM_SCALE
@ TRANSFORM_LINEAR_TO_SRGB
@ TRANSFORM_EXPONENT
#define COLORSPACE_SRGB
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
static const float OCIO_XYZ_TO_REC709[3][3]
Definition ocio_capi.h:35
MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor")
FallbackTransform transform
void applyRGB(float *pixel)
void applyRGBA(float *pixel)
FallbackProcessor(const FallbackTransform &transform)
virtual ~FallbackTransform()
void applyRGBA(float *pixel)
MEM_CXX_CLASS_ALLOC_FUNCS("FallbackTransform")
void applyRGB(float *pixel)
TransformType type
float max