87static std::unique_ptr<ocio::Config>
g_config =
nullptr;
91#define DISPLAY_BUFFER_CHANNELS 4
331 cache_view_settings->
look = look;
334 cache_view_settings->
gamma = view_settings->
gamma;
337 cache_view_settings->
tint = view_settings->
tint;
338 cache_view_settings->
flag = view_settings->
flag;
348 cache_display_settings->
display = display;
372 *cache_handle =
nullptr;
376 *cache_handle = cache_ibuf;
388 int view_flag = 1 << view_settings->
view;
390 int curve_mapping_timestamp = curve_mapping ? curve_mapping->
changed_timestamp : 0;
414 if (cache_data->
look != view_settings->
look ||
418 cache_data->
tint != view_settings->
tint || cache_data->
flag != view_settings->
flag ||
422 *cache_handle =
nullptr;
438 uchar *display_buffer,
444 int view_flag = 1 << view_settings->
view;
447 int curve_mapping_timestamp = curve_mapping ? curve_mapping->
changed_timestamp : 0;
461 cache_data->
look = view_settings->
look;
466 cache_data->
tint = view_settings->
tint;
467 cache_data->
flag = view_settings->
flag;
473 *cache_handle = cache_ibuf;
480 ImBuf *cache_ibuf =
static_cast<ImBuf *
>(cache_handle);
492 char *colorspace_name,
494 const char *backup_role,
495 const bool optional =
false)
499 if (ociocs ==
nullptr && backup_role) {
503 if (ociocs ==
nullptr) {
508 if (ociocs ==
nullptr) {
512 colorspace_name[0] =
'\0';
577 if (
g_config->get_num_displays() == 0) {
582 if (
g_config->get_num_looks() == 0) {
590 if (num_views <= 0) {
621 const char *blender_ocio_env =
BLI_getenv(
"BLENDER_OCIO");
622 if (blender_ocio_env) {
629 if (ocio_env && ocio_env[0] !=
'\0') {
633 &
LOG,
"Using %s=%s", (blender_ocio_env) ?
"BLENDER_OCIO" :
"OCIO", ocio_env);
650 if (configdir.has_value()) {
699 if (look->
view() == view_name) {
705 const int64_t separator_offset = view_name.
find(
" - ");
706 if (separator_offset == -1) {
713 if (look->
view() == view_short_name) {
714 return view_short_name;
777 if (sima && sima->
image) {
779 *r_view_settings =
nullptr;
799 const char *view_transform,
800 const float exposure,
802 const float temperature,
804 const bool use_white_balance,
805 const char *from_colorspace,
811 display_parameters.
view = view_transform;
814 display_parameters.
scale = (exposure == 0.0f) ? 1.0f :
powf(2.0f, exposure);
815 display_parameters.
exponent = (gamma == 1.0f) ? 1.0f : 1.0f /
max_ff(FLT_EPSILON, gamma);
817 display_parameters.
tint = tint;
828 return g_config->get_display_cpu_processor(display_parameters);
840 view_settings->
flag = 0;
841 view_settings->
gamma = 1.0f;
844 view_settings->
tint = 10.0f;
855 else if (channels == 2) {
876 const char *from_colorspace,
881 if (colorspace && colorspace->
is_data()) {
897 if (image_colorspace) {
898 from_colorspace = image_colorspace->
name().
c_str();
940 display =
g_config->get_display_by_index(display_index);
942 new_display_name = display->
name();
948 "Display \"%s\" used by %s not found, setting to \"%s\".",
951 new_display_name.
c_str());
961 if (view_name ==
"Standard" && display->
get_view_by_name(
"Un-tone-mapped")) {
962 return "Un-tone-mapped";
964 if (view_name ==
"Un-tone-mapped" && display->
get_view_by_name(
"Standard")) {
977 const int64_t separator_offset = view_name.
find(
" - ");
978 if (separator_offset != -1) {
979 const StringRef view_short_name = view_name.
substr(0, separator_offset);
982 if (
view->name().startswith(view_short_name)) {
1021 "%s view \"%s\" not found, setting to \"%s\".",
1024 new_view_name.
c_str());
1031 if (view_settings->
look[0] ==
'\0') {
1036 if (look ==
nullptr) {
1038 "%s look \"%s\" not found, setting default \"%s\".",
1040 view_settings->
look,
1048 "%s look \"%s\" is not compatible with view \"%s\", setting "
1052 view_settings->
look,
1062 if (view_settings->
exposure == 0.0f && view_settings->
gamma == 0.0f) {
1064 view_settings->
gamma = 1.0f;
1073 if (
name[0] ==
'\0') {
1080 CLOG_WARN(&
LOG,
"%s colorspace \"%s\" not found, will use default instead.", what,
name);
1099 if (!default_display) {
1105 bool is_missing_opencolorio_config =
false;
1115 &scene->display_settings, &scene->view_settings,
"scene");
1118 &scene->r.im_format.display_settings,
"scene output", default_display);
1120 &scene->r.im_format.display_settings, &scene->r.im_format.view_settings,
"scene output");
1122 sequencer_colorspace_settings = &scene->sequencer_colorspace_settings;
1126 if (sequencer_colorspace_settings->
name[0] ==
'\0') {
1131 if (scene->ed !=
nullptr) {
1134 ok &= colormanage_check_colorspace_settings(&strip->data->colorspace_settings,
1141 is_missing_opencolorio_config |= (!ok && !
ID_IS_LINKED(&scene->id));
1147 is_missing_opencolorio_config |= (!ok && !
ID_IS_LINKED(&image->id));
1152 is_missing_opencolorio_config |= (!ok && !
ID_IS_LINKED(&clip->id));
1173 is_missing_opencolorio_config |= (!ok && !
ID_IS_LINKED(&ntree->id));
1180 if (bmain->filepath[0] !=
'\0' && is_missing_opencolorio_config) {
1181 bmain->colorspace.is_missing_opencolorio_config =
true;
1228 CLOG_WARN(&
LOG,
"Unknown role was passed to %s", __func__);
1240 if (colorspace && colorspace->
is_data()) {
1271 if (colorspace && colorspace->
is_data()) {
1285 if (colorspace && colorspace->
is_data()) {
1313 return g_config->get_color_space_from_filepath(filepath);
1323 return (colorspace && colorspace->
is_data());
1333 return (colorspace && colorspace->
is_srgb());
1339 return (colorspace && colorspace->
is_data());
1357 const char *names[] = {
"sRGB Encoded Rec.709 (sRGB)",
1358 "srgb_rec709_scene",
1359 "Utility - sRGB - Texture",
1363 for (
int i = 0; names[
i];
i++) {
1386 if (!dir.has_value()) {
1391 STRNCPY(icc_filename, (interop_id +
".icc").c_str());
1395 BLI_path_join(icc_filepath,
sizeof(icc_filepath), dir->c_str(),
"icc", icc_filename);
1397 blender::fstream f(icc_filepath, std::ios::binary | std::ios::in | std::ios::ate);
1400 StringRef icc_filepath_ref = icc_filepath;
1401 if (icc_filepath_ref.
endswith(
"_scene.icc")) {
1402 std::string icc_filepath_display = icc_filepath_ref.
drop_suffix(strlen(
"_scene.icc")) +
1404 f.
open(icc_filepath_display, std::ios::binary | std::ios::in | std::ios::ate);
1412 std::streamsize
size = f.tellg();
1418 f.seekg(0, std::ios::beg);
1419 if (!f.read(icc_profile.
data(), icc_profile.
size())) {
1420 icc_profile.
clear();
1446 const bool rgb_matrix,
1459 if (interop_id ==
"pq_rec2020_display") {
1466 if (interop_id ==
"hlg_rec2020_display") {
1473 if (interop_id ==
"pq_p3d65_display") {
1481 if (interop_id ==
"g26_p3d65_display") {
1489 if (interop_id ==
"g22_rec709_display") {
1496 if (interop_id ==
"g24_rec2020_display") {
1504 if (interop_id ==
"g24_rec709_display") {
1512 if (
ELEM(interop_id,
"srgb_p3d65_display",
"srgbe_p3d65_display")) {
1522 if (interop_id ==
"srgb_rec709_display") {
1539 interop_id =
"pq_rec2020_display";
1542 interop_id =
"hlg_rec2020_display";
1545 interop_id =
"pq_p3d65_display";
1548 interop_id =
"g26_p3d65_display";
1551 interop_id =
"g22_rec709_display";
1554 interop_id =
"g24_rec2020_display";
1560 interop_id =
"srgb_rec709_display";
1563 interop_id =
"g24_rec709_display";
1567 interop_id =
"srgb_p3d65_display";
1570 interop_id =
"srgb_rec709_display";
1583 return g_config->get_color_space_by_interop_id(interop_id);
1604 float whitepoint[3])
1668 float dither = ibuf->
dither;
1671 size_t offset = size_t(channels) * start_line * ibuf->
x;
1710 float *linear_buffer,
1711 bool *is_straight_alpha)
1714 int width = handle->
width;
1716 size_t buffer_size = size_t(channels) * width * height;
1718 bool is_data = handle->
is_data;
1730 const size_t i_last = size_t(width) * height;
1734 for (
i = 0, fp = linear_buffer, cp = byte_buffer;
i != i_last;
1735 i++, fp += channels, cp += channels)
1737 if (channels == 3) {
1740 else if (channels == 4) {
1744 BLI_assert_msg(0,
"Buffers of 3 or 4 channels are only supported here");
1748 if (!is_data && !is_data_display) {
1751 linear_buffer, width, height, channels, from_colorspace, to_colorspace,
false);
1754 *is_straight_alpha =
true;
1766 memcpy(linear_buffer, handle->
buffer, buffer_size *
sizeof(
float));
1768 if (!is_data && !is_data_display) {
1770 linear_buffer, width, height, channels, from_colorspace, to_colorspace, predivide);
1773 *is_straight_alpha =
false;
1782 memcpy(linear_buffer, handle->
buffer, buffer_size *
sizeof(
float));
1784 *is_straight_alpha =
false;
1790 const int width = handle->
width;
1791 const int height = handle->
tot_line;
1804 else if (handle->
buffer) {
1850 if (cm_processor ==
nullptr) {
1858 int width = handle->
width;
1861 size_t(channels) *
size_t(width) *
size_t(height),
"color conversion linear buffer");
1863 bool is_straight_alpha;
1866 bool predivide = handle->
predivide && (is_straight_alpha ==
false);
1871 cm_processor, linear_buffer, width, height, channels, predivide);
1875 if (display_buffer_byte) {
1891 if (display_buffer) {
1892 memcpy(display_buffer, linear_buffer,
size_t(width) * height * channels *
sizeof(
float));
1894 if (is_straight_alpha && channels == 4) {
1895 const size_t i_last = size_t(width) * height;
1899 for (
i = 0, fp = display_buffer;
i != i_last;
i++, fp += channels) {
1909 const float *buffer,
1911 float *display_buffer,
1912 uchar *display_buffer_byte,
1922 init_data.display_buffer = display_buffer;
1923 init_data.display_buffer_byte = display_buffer_byte;
1944 DisplayBufferThread handle;
1945 display_buffer_init_handle(&handle, y_range.first(), y_range.size(), &init_data);
1946 do_display_buffer_apply_thread(&handle);
1959 view_settings->
exposure != 0.0f || view_settings->
gamma != 1.0f)
1970 view_settings, display_settings);
1977 return untonemapped_view && untonemapped_view->
name() == view_settings->
view_transform;
2010 float *display_buffer,
2011 uchar *display_buffer_byte,
2017 ibuf, view_settings, display_settings, display_space);
2022 display_buffer_byte,
2031 uchar *display_buffer,
2037 ibuf,
nullptr, display_buffer, view_settings, display_settings, display_space);
2074 const int channels =
init_data->channels;
2076 const bool predivide =
init_data->predivide;
2077 const bool float_from_byte =
init_data->float_from_byte;
2079 const size_t offset = size_t(channels) * start_line * width;
2085 if (
init_data->byte_buffer !=
nullptr) {
2089 if (
init_data->float_buffer !=
nullptr) {
2093 handle->
width = width;
2107 const int channels = handle->
channels;
2108 const int width = handle->
width;
2109 const int height = handle->
tot_line;
2110 const bool predivide = handle->
predivide;
2113 if (float_from_byte) {
2124 handle->
cm_processor, float_buffer, width, height, channels, predivide);
2128 if (byte_buffer !=
nullptr) {
2130 handle->
cm_processor, byte_buffer, width, height, channels);
2132 if (float_buffer !=
nullptr) {
2134 handle->
cm_processor, float_buffer, width, height, channels, predivide);
2140 float *float_buffer,
2145 const bool predivide,
2146 const bool float_from_byte)
2158 init_data.float_from_byte = float_from_byte;
2176 float *float_buffer,
2180 const char *from_colorspace,
2181 const char *to_colorspace,
2184 if (from_colorspace[0] ==
'\0') {
2188 if (
STREQ(from_colorspace, to_colorspace)) {
2194 from_colorspace, to_colorspace);
2201 byte_buffer, float_buffer, width, height, channels, cm_processor, predivide,
false);
2209 const char *from_colorspace,
2210 const char *to_colorspace,
2214 nullptr, buffer, width, height, channels, from_colorspace, to_colorspace, predivide);
2221 const char *from_colorspace,
2222 const char *to_colorspace)
2225 buffer,
nullptr, width, height, channels, from_colorspace, to_colorspace,
false);
2233 const char *from_colorspace,
2234 const char *to_colorspace)
2238 if (from_colorspace ==
nullptr || from_colorspace[0] ==
'\0') {
2241 if (
STREQ(from_colorspace, to_colorspace) && channels == 4) {
2245 float *dst_ptr = float_buffer + pix_range.
first() * channels;
2246 uchar *src_ptr = byte_buffer + pix_range.
first() * channels;
2247 for ([[maybe_unused]]
const int i : pix_range) {
2249 float cr =
float(src_ptr[0]) * (1.0f / 255.0f);
2250 float cg =
float(src_ptr[1]) * (1.0f / 255.0f);
2251 float cb =
float(src_ptr[2]) * (1.0f / 255.0f);
2252 float ca =
float(src_ptr[3]) * (1.0f / 255.0f);
2253 dst_ptr[0] = cr * ca;
2254 dst_ptr[1] = cg * ca;
2255 dst_ptr[2] = cb * ca;
2265 byte_buffer, float_buffer, width, height, channels, cm_processor,
false,
true);
2270 const char *from_colorspace,
2271 const char *to_colorspace)
2275 if (from_colorspace[0] ==
'\0') {
2279 if (
STREQ(from_colorspace, to_colorspace)) {
2297 printf(
"%s: perform conversion from unknown color space\n", __func__);
2301 if (processor ==
nullptr) {
2311 printf(
"%s: perform conversion from unknown color space\n", __func__);
2315 if (processor ==
nullptr) {
2322 const bool predivide,
2326 printf(
"%s: perform conversion from unknown color space\n", __func__);
2330 if (processor ==
nullptr) {
2346 const bool predivide)
2349 printf(
"%s: perform conversion from unknown color space\n", __func__);
2353 if (processor ==
nullptr) {
2362 size_t(channels) *
sizeof(
float),
2363 size_t(channels) *
sizeof(
float) * width);
2369 processor->
apply(img);
2380 printf(
"%s: perform conversion from unknown color space\n", __func__);
2384 if (processor ==
nullptr) {
2393 size_t(channels) *
sizeof(
float),
2394 size_t(channels) *
sizeof(
float) * width);
2395 processor->
apply(img);
2404 const bool store_premultiplied)
2417 for (
int y = 0;
y < height;
y++) {
2418 const size_t in_offset = (offset_y +
y) * ibuf->
x + offset_x;
2419 const size_t out_offset =
y * width;
2420 const uchar *
in = in_buffer + in_offset * 4;
2421 uchar *
out = out_buffer + out_offset * 4;
2423 if (use_premultiply) {
2425 for (
int x = 0;
x < width;
x++,
in += 4,
out += 4) {
2426 out[0] = (
in[0] *
in[3]) >> 8;
2427 out[1] = (
in[1] *
in[3]) >> 8;
2428 out[2] = (
in[2] *
in[3]) >> 8;
2434 for (
int x = 0;
x < width;
x++,
in += 4,
out += 4) {
2450 const bool store_premultiplied)
2459 const int in_channels = ibuf->
channels;
2462 for (
int y = 0;
y < height;
y++) {
2463 const size_t in_offset = (offset_y +
y) * ibuf->
x + offset_x;
2464 const size_t out_offset =
y * width;
2465 const float *
in = in_buffer + in_offset * in_channels;
2466 float *
out = out_buffer + out_offset * 4;
2468 if (in_channels == 1) {
2470 for (
int x = 0;
x < width;
x++,
in += 1,
out += 4) {
2477 else if (in_channels == 3) {
2479 for (
int x = 0;
x < width;
x++,
in += 3,
out += 4) {
2486 else if (in_channels == 4) {
2488 if (use_unpremultiply) {
2489 for (
int x = 0;
x < width;
x++,
in += 4,
out += 4) {
2494 memcpy(
out,
in,
sizeof(
float[4]) * width);
2510 for (
const int y : y_range) {
2511 const size_t in_offset = (offset_y +
y) * ibuf->
x + offset_x;
2512 const size_t out_offset =
y * width;
2513 const uchar *
in = in_buffer + in_offset * 4;
2514 float *
out = out_buffer + out_offset * 4;
2515 for (
int x = 0;
x < width;
x++,
in += 4,
out += 4) {
2525 if (use_premultiply) {
2536 const float scene_linear[3])
2543 std::shared_ptr<const ocio::CPUProcessor> cpu_processor =
g_config->get_cpu_processor(
2546 if (cpu_processor) {
2565 const float color_picking[3])
2572 std::shared_ptr<const ocio::CPUProcessor> cpu_processor =
g_config->get_cpu_processor(
2575 if (cpu_processor) {
2599 if (processor !=
nullptr) {
2610 if (processor !=
nullptr) {
2617 const float pixel[4],
2627 view_settings, display_settings, display_space);
2658 ibuf, view_settings, display_settings, display_space,
false);
2663 if (colormanaged_ibuf != ibuf) {
2665 return colormanaged_ibuf;
2668 if (allocate_result) {
2672 return colormanaged_ibuf;
2685 bool save_as_render,
2686 bool allocate_result,
2689 ImBuf *colormanaged_ibuf = ibuf;
2719 float color[3] = {0, 0, 0};
2734 if (save_as_render && !linear_float_output) {
2776 const ColorSpace *image_colorspace =
g_config->get_color_space_for_hdr_image(to_colorspace);
2777 if (image_colorspace) {
2778 to_colorspace = image_colorspace->
name().
c_str();
2783 if (to_colorspace[0] ==
'\0' ||
STREQ(from_colorspace, to_colorspace)) {
2801 colormanaged_ibuf->
x,
2802 colormanaged_ibuf->
y,
2825 colormanaged_ibuf->
x,
2826 colormanaged_ibuf->
y,
2839 return colormanaged_ibuf;
2851 void **cache_handle)
2853 uchar *display_buffer;
2859 *cache_handle =
nullptr;
2861 if (!ibuf->
x || !ibuf->
y) {
2865 if (view_settings) {
2866 applied_view_settings = view_settings;
2873 applied_view_settings = &untonemapped_view_settings;
2896 applied_view_settings,
2912 "imbuf display_buffer_flags");
2924 ibuf, &cache_view_settings, &cache_display_settings, cache_handle);
2926 if (display_buffer) {
2928 return display_buffer;
2938 ibuf, &cache_view_settings, &cache_display_settings, display_buffer, cache_handle);
2942 return display_buffer;
2956 float *linear_buffer,
2969 "display transform temp buffer");
2970 memcpy(buffer, linear_buffer,
size_t(channels) * width * height *
sizeof(
float));
3012 return display->
index;
3039 if (
g_config->get_display_by_name(
"None") !=
nullptr) {
3049 if (!default_view) {
3072 g_config->get_display_view_color_space(
3074 untonemapped_view->
name()) :
3076 return (untonemapped_colorspace) ? untonemapped_colorspace :
colorspace;
3080 const char *view_name)
3083 if (display ==
nullptr) {
3087 return (
view) ?
view->is_hdr() :
false;
3091 const char *view_name)
3094 if (display ==
nullptr) {
3105 if (display ==
nullptr) {
3109 return (
view) ?
view->support_emulation() :
false;
3148 return view->name().c_str();
3172 return view->name().c_str();
3197 return g_config->get_num_color_spaces();
3211 if (index ==
g_config->get_num_color_spaces()) {
3240 if (type !=
nullptr) {
3241 if (type->
save !=
nullptr) {
3283 const char *look_name)
3345 if (!working_spaces.
contains(scene_linear)) {
3346 working_spaces.
prepend(scene_linear);
3417 interop_id =
"lin_ap1_scene";
3423 interop_id =
"lin_rec709_scene";
3429 interop_id =
"lin_rec2020_scene";
3449 &
LOG,
"Unknown scene linear working space '%s'. Missing OpenColorIO configuration?",
name);
3457 const bool for_undo,
3458 const bool have_editable_assets)
3465 "Blend file has unknown scene linear working color space, setting to default");
3473 if (!working_space_changed) {
3479 if (!(for_undo || have_editable_assets)) {
3485 current_scene_linear_to_xyz,
3489 !for_undo && have_editable_assets);
3493 const bool is_smaller_gamut,
3498 for (
int i = 0;
i < 3;
i++) {
3500 rgb[
i] = 1e-5f *
roundf(rgb[
i] * 1e5f);
3505 else if (
fabsf(1.0f - rgb[
i]) < 5
e-5) {
3510 if (is_smaller_gamut) {
3519 const bool is_smaller_gamut,
3532 const bool depsgraph_tag,
3533 const bool linked_only,
3534 const bool editable_assets_only)
3540 current_scene_linear_to_xyz;
3542 float3x3 M = new_xyz_to_scene_linear * bmain_scene_linear_to_xyz;
3550 CLOG_ERROR(&
LOG,
"Working space conversion matrix is not invertible");
3556 bool is_smaller_gamut =
false;
3557 for (
int i = 0;
i < 3;
i++) {
3558 for (
int j = 0; j < 3; j++) {
3559 if (
M[
i][j] < 0.0f) {
3560 is_smaller_gamut =
true;
3566 const auto single = [&
M, is_smaller_gamut](
float rgb[3]) {
3574 struct ColorArrayInfo {
3583 const auto implicit_sharing_array =
3586 if (!sharing_info) {
3592 [&](ColorArrayInfo *value) {
3593 new (value) ColorArrayInfo();
3594 value->data_ptrs.append(&data);
3595 value->sharing_info_ptrs.append(&sharing_info);
3596 value->max_size = size;
3598 [&](ColorArrayInfo *value) {
3599 BLI_assert(data == *value->data_ptrs.last());
3600 value->data_ptrs.append(&data);
3601 value->sharing_info_ptrs.append(&sharing_info);
3602 value->max_size = std::max(value->max_size, size);
3614 if (!id_iter->
lib) {
3618 if (editable_assets_only) {
3627 if (depsgraph_tag) {
3646 for (const int item_index : range) {
3647 const auto &item = color_array_items[item_index];
3649 if (item.value.data_ptrs.size() == item.key->strong_users()) {
3652 item.key->tag_ensured_mutable();
3653 MutableSpan<ColorGeometry4f> data(*item.value.data_ptrs.first(), item.value.max_size);
3654 threading::parallel_for(data.index_range(), 1024, [&](const IndexRange range) {
3655 for (const int64_t i : range) {
3656 data[i] = imb_working_space_convert(M, is_smaller_gamut, data[i]);
3663 const Span<ColorGeometry4f> src_data(*item.value.data_ptrs.first(), item.value.max_size);
3665 auto *dst_data = MEM_malloc_arrayN<ColorGeometry4f>(
3666 src_data.size(),
"IMB_colormanagement_working_space_convert");
3667 const ImplicitSharingPtr<> sharing_ptr(implicit_sharing::info_for_mem_free(dst_data));
3669 threading::parallel_for(src_data.index_range(), 1024, [&](const IndexRange range) {
3670 for (const int64_t i : range) {
3671 dst_data[i] = imb_working_space_convert(M, is_smaller_gamut, src_data[i]);
3677 for (ColorGeometry4f **pointer : item.value.data_ptrs) {
3678 *pointer = dst_data;
3680 for (ImplicitSharingPtr<> *pointer : item.value.sharing_info_ptrs) {
3681 *pointer = sharing_ptr;
3729 for (
const bool hdr : {
false,
true}) {
3735 if (display->
is_hdr() != hdr) {
3742 item.
name = (hdr) ?
"HDR" :
"SDR";
3766 const char *display_name)
3790 const char *view_name)
3837 item.
name =
"Working Space";
3840 item.
description =
"Working color space of the current file";
3863 uchar *display_buffer,
3864 const float *linear_buffer,
3865 const uchar *byte_buffer,
3868 int linear_offset_x,
3869 int linear_offset_y,
3878 float dither = ibuf->
dither;
3880 float *display_buffer_float =
nullptr;
3881 const int width = xmax - xmin;
3882 const int height = ymax - ymin;
3885 if (dither != 0.0f) {
3893 if (!cm_processor) {
3898 size_t(channels) *
size_t(width) *
size_t(height),
"display buffer for dither");
3902 for (
y = ymin;
y < ymax;
y++) {
3903 for (
x = xmin;
x < xmax;
x++) {
3904 size_t display_index = (size_t(
y) * display_stride +
x) * 4;
3905 size_t linear_index = (size_t(
y - linear_offset_y) * linear_stride +
3906 (
x - linear_offset_x)) *
3910 if (linear_buffer) {
3911 if (channels == 4) {
3912 copy_v4_v4(pixel, (
float *)linear_buffer + linear_index);
3914 else if (channels == 3) {
3915 copy_v3_v3(pixel, (
float *)linear_buffer + linear_index);
3918 else if (channels == 1) {
3919 pixel[0] = linear_buffer[linear_index];
3922 BLI_assert_msg(0,
"Unsupported number of channels in partial buffer update");
3925 else if (byte_buffer) {
3935 if (display_buffer_float) {
3936 size_t index = (size_t(
y - ymin) * width + (
x - xmin)) * channels;
3938 if (channels == 4) {
3939 copy_v4_v4(display_buffer_float + index, pixel);
3941 else if (channels == 3) {
3942 copy_v3_v3(display_buffer_float + index, pixel);
3945 display_buffer_float[index] = pixel[0];
3949 if (channels == 4) {
3950 float pixel_straight[4];
3954 else if (channels == 3) {
3956 display_buffer[display_index + 3] = 255;
3959 display_buffer[display_index] = display_buffer[display_index + 1] =
3960 display_buffer[display_index + 2] = display_buffer[display_index + 3] =
3968 if (display_buffer_float) {
3983 for (
i = ymin;
i < ymax;
i++) {
3984 size_t byte_offset = (size_t(linear_stride) *
i + xmin) * 4;
3985 size_t display_offset = (size_t(display_stride) *
i + xmin) * 4;
3988 display_buffer + display_offset, byte_buffer + byte_offset,
sizeof(
char[4]) * width);
3993 if (display_buffer_float) {
3994 size_t display_index = (size_t(ymin) * display_stride + xmin) * channels;
3997 display_buffer_float,
4015 const float *linear_buffer,
4016 const uchar *byte_buffer,
4031 void *cache_handle =
nullptr;
4032 uchar *display_buffer =
nullptr;
4033 int buffer_width = ibuf->
x;
4036 int view_flag, display_index;
4041 view_flag = 1 << cache_view_settings.
view;
4042 display_index = cache_display_settings.
display;
4048 ibuf, &cache_view_settings, &cache_display_settings, &cache_handle);
4055 buffer_width = ibuf->
x;
4064 if (display_buffer) {
4066 bool skip_transform =
false;
4073 if (linear_buffer ==
nullptr && byte_buffer !=
nullptr) {
4077 if (byte_buffer ==
nullptr && linear_buffer !=
nullptr) {
4082 if (!skip_transform) {
4087 do_threads ? 64 : ymax - ymin,
4113 const float *linear_buffer,
4114 const uchar *byte_buffer,
4142 const float *linear_buffer,
4143 const uchar *byte_buffer,
4154 int width = xmax - xmin;
4155 int height = ymax - ymin;
4156 bool do_threads = (size_t(width) * height >= 64 * 64);
4201 cm_processor = MEM_new<ColormanageProcessor>(
"colormanagement processor");
4203 if (view_settings) {
4204 applied_view_settings = view_settings;
4209 applied_view_settings = &untonemapped_view_settings;
4214 if (display_colorspace) {
4220 applied_view_settings->
look,
4223 applied_view_settings->
gamma,
4225 applied_view_settings->
tint,
4236 return cm_processor;
4240 const char *to_colorspace)
4244 cm_processor = MEM_new<ColormanageProcessor>(
"colormanagement processor");
4249 return cm_processor;
4316 if (channels == 4) {
4319 else if (channels == 3) {
4322 else if (channels == 1) {
4329 false,
"Incorrect number of channels passed to IMB_colormanagement_processor_apply_pixel");
4344 for (
y = 0;
y < height;
y++) {
4345 for (
x = 0;
x < width;
x++) {
4346 float *pixel = buffer + channels * (size_t(
y) * width +
x);
4361 size_t(channels) *
sizeof(
float),
4362 size_t(channels) *
sizeof(
float) * width);
4381 for (
int y = 0;
y < height;
y++) {
4382 for (
int x = 0;
x < width;
x++) {
4383 size_t offset = channels * (size_t(
y) * width +
x);
4397 MEM_delete(cm_processor);
4406 if (!use_curve_mapping) {
4443 bool do_overlay_merge)
4448 if (view_settings) {
4449 applied_view_settings = view_settings;
4456 applied_view_settings = &untonemapped_view_settings;
4465 const float exposure = applied_view_settings->
exposure;
4466 const float gamma = applied_view_settings->
gamma;
4474 display_parameters.
look = (use_look) ? applied_view_settings->
look :
"";
4476 display_parameters.
scale = (exposure == 0.0f) ? 1.0f :
powf(2.0f, exposure);
4477 display_parameters.
exponent = (gamma == 1.0f) ? 1.0f : 1.0f /
max_ff(FLT_EPSILON, gamma);
4478 display_parameters.
dither = dither;
4480 display_parameters.
tint = applied_view_settings->
tint;
4487 display_settings, display_parameters.
view.
c_str());
4492 display_parameters);
4503 view_settings, display_settings,
nullptr, dither, predivide,
false);
4517 view_settings, display_settings, from_colorspace, dither, predivide,
false);
4526 const bool predivide)
4529 from_colorspace_name, predivide);
4536 g_config->get_gpu_shader_binder().unbind();
4554 {2.48845471e+03f, -1.11330907e-03f, 3.22621544e+00f},
4555 {3.34143193e+03f, -4.86551192e-04f, 1.76486769e+00f},
4556 {4.09461742e+03f, -1.27446582e-04f, 7.25731635e-01f},
4557 {4.67028036e+03f, 2.91258199e-05f, 1.26703442e-01f},
4558 {4.59509185e+03f, 2.87495649e-05f, 1.50345020e-01f},
4559 {3.78717450e+03f, 9.35907826e-06f, 3.99075871e-01f}};
4562 {-4.88999748e+02f, 6.04330754e-04f, -7.55807526e-02f},
4563 {-7.55994277e+02f, 3.16730098e-04f, 4.78306139e-01f},
4564 {-1.02363977e+03f, 1.20223470e-04f, 9.36662319e-01f},
4565 {-1.26571316e+03f, 4.87340896e-06f, 1.27054498e+00f},
4566 {-1.42529332e+03f, -4.01150431e-05f, 1.43972784e+00f},
4567 {-1.17554822e+03f, -2.16378048e-05f, 1.30408023e+00f},
4568 {-5.00799571e+02f, -4.59832026e-06f, 1.09098763e+00f}};
4571 {5.96945309e-11f, -4.85742887e-08f, -9.70622247e-05f, -4.07936148e-03f},
4572 {2.40430366e-11f, 5.55021075e-08f, -1.98503712e-04f, 2.89312858e-02f},
4573 {-1.40949732e-11f, 1.89878968e-07f, -3.56632824e-04f, 9.10767778e-02f},
4574 {-3.61460868e-11f, 2.84822009e-07f, -4.93211319e-04f, 1.56723440e-01f},
4575 {-1.97075738e-11f, 1.75359352e-07f, -2.50542825e-04f, -2.22783266e-02f},
4576 {-1.61997957e-13f, -1.64216008e-08f, 3.86216271e-04f, -7.38077418e-01f},
4577 {6.72650283e-13f, -2.73078809e-08f, 4.24098264e-04f, -7.52335691e-01f}};
4581 if (t >= 12000.0f) {
4582 rec709[0] = 0.8262954810464208f;
4583 rec709[1] = 0.9945080501520986f;
4584 rec709[2] = 1.566307710274283f;
4586 else if (t < 800.0f) {
4587 rec709[0] = 5.413294490189271f;
4588 rec709[1] = -0.20319390035873933f;
4589 rec709[2] = -0.0822535242887164f;
4592 int i = (t >= 6365.0f) ? 6 :
4593 (t >= 3315.0f) ? 5 :
4594 (t >= 1902.0f) ? 4 :
4595 (t >= 1449.0f) ? 3 :
4596 (t >= 1167.0f) ? 2 :
4604 const float t_inv = 1.0f / t;
4605 rec709[0] = r[0] * t_inv + r[1] * t + r[2];
4606 rec709[1] = g[0] * t_inv + g[1] * t + g[2];
4607 rec709[2] = ((
b[0] * t +
b[1]) * t +
b[2]) * t +
b[3];
4629 for (
int i = 0;
i < width;
i++) {
4648 {0.0014f, 0.0000f, 0.0065f}, {0.0022f, 0.0001f, 0.0105f}, {0.0042f, 0.0001f, 0.0201f},
4649 {0.0076f, 0.0002f, 0.0362f}, {0.0143f, 0.0004f, 0.0679f}, {0.0232f, 0.0006f, 0.1102f},
4650 {0.0435f, 0.0012f, 0.2074f}, {0.0776f, 0.0022f, 0.3713f}, {0.1344f, 0.0040f, 0.6456f},
4651 {0.2148f, 0.0073f, 1.0391f}, {0.2839f, 0.0116f, 1.3856f}, {0.3285f, 0.0168f, 1.6230f},
4652 {0.3483f, 0.0230f, 1.7471f}, {0.3481f, 0.0298f, 1.7826f}, {0.3362f, 0.0380f, 1.7721f},
4653 {0.3187f, 0.0480f, 1.7441f}, {0.2908f, 0.0600f, 1.6692f}, {0.2511f, 0.0739f, 1.5281f},
4654 {0.1954f, 0.0910f, 1.2876f}, {0.1421f, 0.1126f, 1.0419f}, {0.0956f, 0.1390f, 0.8130f},
4655 {0.0580f, 0.1693f, 0.6162f}, {0.0320f, 0.2080f, 0.4652f}, {0.0147f, 0.2586f, 0.3533f},
4656 {0.0049f, 0.3230f, 0.2720f}, {0.0024f, 0.4073f, 0.2123f}, {0.0093f, 0.5030f, 0.1582f},
4657 {0.0291f, 0.6082f, 0.1117f}, {0.0633f, 0.7100f, 0.0782f}, {0.1096f, 0.7932f, 0.0573f},
4658 {0.1655f, 0.8620f, 0.0422f}, {0.2257f, 0.9149f, 0.0298f}, {0.2904f, 0.9540f, 0.0203f},
4659 {0.3597f, 0.9803f, 0.0134f}, {0.4334f, 0.9950f, 0.0087f}, {0.5121f, 1.0000f, 0.0057f},
4660 {0.5945f, 0.9950f, 0.0039f}, {0.6784f, 0.9786f, 0.0027f}, {0.7621f, 0.9520f, 0.0021f},
4661 {0.8425f, 0.9154f, 0.0018f}, {0.9163f, 0.8700f, 0.0017f}, {0.9786f, 0.8163f, 0.0014f},
4662 {1.0263f, 0.7570f, 0.0011f}, {1.0567f, 0.6949f, 0.0010f}, {1.0622f, 0.6310f, 0.0008f},
4663 {1.0456f, 0.5668f, 0.0006f}, {1.0026f, 0.5030f, 0.0003f}, {0.9384f, 0.4412f, 0.0002f},
4664 {0.8544f, 0.3810f, 0.0002f}, {0.7514f, 0.3210f, 0.0001f}, {0.6424f, 0.2650f, 0.0000f},
4665 {0.5419f, 0.2170f, 0.0000f}, {0.4479f, 0.1750f, 0.0000f}, {0.3608f, 0.1382f, 0.0000f},
4666 {0.2835f, 0.1070f, 0.0000f}, {0.2187f, 0.0816f, 0.0000f}, {0.1649f, 0.0610f, 0.0000f},
4667 {0.1212f, 0.0446f, 0.0000f}, {0.0874f, 0.0320f, 0.0000f}, {0.0636f, 0.0232f, 0.0000f},
4668 {0.0468f, 0.0170f, 0.0000f}, {0.0329f, 0.0119f, 0.0000f}, {0.0227f, 0.0082f, 0.0000f},
4669 {0.0158f, 0.0057f, 0.0000f}, {0.0114f, 0.0041f, 0.0000f}, {0.0081f, 0.0029f, 0.0000f},
4670 {0.0058f, 0.0021f, 0.0000f}, {0.0041f, 0.0015f, 0.0000f}, {0.0029f, 0.0010f, 0.0000f},
4671 {0.0020f, 0.0007f, 0.0000f}, {0.0014f, 0.0005f, 0.0000f}, {0.0010f, 0.0004f, 0.0000f},
4672 {0.0007f, 0.0002f, 0.0000f}, {0.0005f, 0.0002f, 0.0000f}, {0.0003f, 0.0001f, 0.0000f},
4673 {0.0002f, 0.0001f, 0.0000f}, {0.0002f, 0.0001f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f},
4674 {0.0001f, 0.0000f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f}, {0.0000f, 0.0000f, 0.0000f}};
4678 float ii = (lambda_nm - 380.0f) * (1.0f / 5.0f);
4689 xyz[0] = c[0] + ii * (c[3] - c[0]);
4690 xyz[1] = c[1] + ii * (c[4] - c[1]);
4691 xyz[2] = c[2] + ii * (c[5] - c[2]);
4710 for (
int i = 0;
i < width;
i++) {
4711 float wavelength = 380 + 400 /
float(width) *
float(
i);
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
SpaceImage * CTX_wm_space_image(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
#define FOREACH_MAIN_ID_END
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
#define CMP_NODE_CONVERT_COLOR_SPACE
#define CMP_NODE_CONVERT_TO_DISPLAY
blender::ocio::ColorSpace ColorSpace
#define BLI_assert_msg(a, msg)
File and directory operations.
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_ff(float a, float b)
MINLINE void straight_to_premul_v4(float color[4])
MINLINE void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
void BLI_init_srgb_conversion(void)
MINLINE void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
MINLINE void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
MINLINE void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4])
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void clamp_v3(float vec[3], float min, float max)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void BLI_setenv(const char *env, const char *val) ATTR_NONNULL(1)
#define BLI_path_join(...)
const char * BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_make_safe_filename(char *filename) ATTR_NONNULL(1)
void BLI_rcti_union(struct rcti *rct_a, const struct rcti *rct_b)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
char * STRNCPY(char(&dst)[N], const char *src)
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
void BLI_thread_unlock(int type)
void BLI_thread_lock(int type)
#define BLI_MUTEX_INITIALIZER
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_DEBUG(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_STR_INFO_NOCHECK(clg_ref, str)
#define CLOG_INFO_NOCHECK(clg_ref, format,...)
#define CLOG_INFO(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
ID and Library types, which are fundamental for SDNA.
#define ID_IS_LINKED(_id)
@ COLORMANAGE_VIEW_USE_WHITE_BALANCE
@ COLORMANAGE_VIEW_USE_CURVES
@ COLORMANAGE_DISPLAY_EMULATION_OFF
@ COLORMANAGE_DISPLAY_EMULATION_AUTO
@ DISPLAY_SPACE_VIDEO_OUTPUT
@ DISPLAY_SPACE_IMAGE_OUTPUT
bool IMB_colormanagement_space_is_scene_linear(const ColorSpace *colorspace)
bool IMB_colormanagement_space_is_data(const ColorSpace *colorspace)
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_ACES_INTERCHANGE
@ COLOR_ROLE_DEFAULT_BYTE
@ COLOR_ROLE_SCENE_LINEAR
@ COLOR_ROLE_COLOR_PICKING
@ COLOR_ROLE_DEFAULT_SEQUENCER
@ COLOR_ROLE_TEXTURE_PAINTING
BLI_INLINE void IMB_colormanagement_xyz_to_scene_linear(float scene_linear[3], const float xyz[3])
BLI_INLINE void IMB_colormanagement_rec709_to_scene_linear(float scene_linear[3], const float rec709[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_xyz(float xyz[3], const float scene_linear[3])
#define MAX_COLORSPACE_NAME
Function declarations for filter.cc.
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
void IMB_make_writable_byte_buffer(ImBuf *ibuf)
void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from, int channels_from, float dither, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from, int start_y=0)
bool IMB_alpha_affects_rgb(const ImBuf *ibuf)
bool IMB_alloc_byte_pixels(ImBuf *ibuf, bool initialize_pixels=true)
void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
void IMB_byte_from_float(ImBuf *ibuf)
void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, int channels_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
void IMB_make_writable_float_buffer(ImBuf *ibuf)
void IMB_freeImBuf(ImBuf *ibuf)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
void IMB_free_byte_pixels(ImBuf *ibuf)
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
void IMB_assign_byte_buffer(ImBuf *ibuf, uint8_t *buffer_data, ImBufOwnership ownership)
void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, const float backcol[3])
void IMB_float_from_byte(ImBuf *ibuf)
@ IB_DISPLAY_BUFFER_INVALID
@ IMB_COLORMANAGE_IS_DATA
@ IB_alphamode_channel_packed
void IMB_moviecache_free(MovieCache *cache)
ImBuf * IMB_moviecache_get(MovieCache *cache, void *userkey, bool *r_is_cached_empty)
void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
MovieCache * IMB_moviecache_create(const char *name, int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp)
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
#define OCIO_ROLE_COLOR_PICKING
#define OCIO_ROLE_TEXTURE_PAINT
#define OCIO_ROLE_DEFAULT_FLOAT
#define OCIO_ROLE_DEFAULT_SEQUENCER
#define OCIO_ROLE_DEFAULT_BYTE
#define OCIO_ROLE_ACES_INTERCHANGE
#define OCIO_ROLE_SCENE_LINEAR
blender::ocio::Display ColorManagedDisplay
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr int64_t size() const
SubIterator begin() const
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
ItemIterator items() const &
IndexRange index_range() const
constexpr int64_t find(char c, int64_t pos=0) const
constexpr bool is_empty() const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr bool startswith(StringRef prefix) const
constexpr bool endswith(StringRef suffix) const
constexpr const char * c_str() const
constexpr StringRef drop_suffix(int64_t n) const
void prepend(const T &value)
bool contains(const T &value) const
void resize(const int64_t new_size)
void open(StringRefNull filepath, ios_base::openmode mode=ios_base::in|ios_base::out)
virtual void apply_rgba_predivide(float rgba[4]) const =0
virtual void apply_predivide(const PackedImage &image) const =0
virtual void apply_rgb(float rgb[3]) const =0
virtual void apply(const PackedImage &image) const =0
virtual void apply_rgba(float rgba[4]) const =0
virtual StringRefNull name() const =0
virtual const CPUProcessor * get_to_scene_linear_cpu_processor() const =0
virtual bool is_data() const =0
virtual bool is_scene_linear() const =0
virtual bool is_srgb() const =0
virtual StringRefNull interop_id() const =0
static std::unique_ptr< Config > create_fallback()
virtual const ColorSpace * get_color_space(StringRefNull name) const =0
static std::unique_ptr< Config > create_from_environment()
static std::unique_ptr< Config > create_from_file(StringRefNull filename)
virtual StringRefNull name() const =0
virtual const View * get_view_by_name(StringRefNull name) const =0
virtual const CPUProcessor * get_to_scene_linear_cpu_processor(bool use_display_emulation) const =0
virtual const CPUProcessor * get_from_scene_linear_cpu_processor(bool use_display_emulation) const =0
virtual const View * get_default_view() const =0
virtual bool is_hdr() const =0
virtual int get_num_views() const =0
virtual StringRefNull ui_name() const =0
virtual const View * get_untonemapped_view() const =0
virtual StringRefNull description() const =0
virtual const View * get_view_by_index(int index) const =0
virtual StringRefNull view() const =0
virtual StringRefNull description() const =0
virtual StringRefNull name() const =0
virtual StringRefNull ui_name() const =0
virtual StringRefNull process_space() const =0
virtual StringRefNull name() const =0
static void partial_buffer_update_rect(ImBuf *ibuf, uchar *display_buffer, const float *linear_buffer, const uchar *byte_buffer, int display_stride, int linear_stride, int linear_offset_x, int linear_offset_y, ColormanageProcessor *cm_processor, const int xmin, const int ymin, const int xmax, const int ymax)
static char global_role_data[MAX_COLORSPACE_NAME]
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], const ColorSpace *colorspace)
bool IMB_colormanagement_display_support_emulation(const ColorManagedDisplaySettings *display_settings, const char *view_name)
bool IMB_colormanagement_working_space_set_from_name(const char *name)
static CurveMapping * update_glsl_curve_mapping(const ColorManagedViewSettings *view_settings)
static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, int height, float *linear_buffer, bool *is_straight_alpha)
static std::shared_ptr< const ocio::CPUProcessor > get_display_buffer_processor(const ColorManagedDisplaySettings &display_settings, const char *look, const char *view_transform, const float exposure, const float gamma, const float temperature, const float tint, const bool use_white_balance, const char *from_colorspace, const ColorManagedDisplaySpace target, const bool inverse=false)
static const float blackbody_table_r[7][3]
void IMB_colormanagement_assign_byte_colorspace(ImBuf *ibuf, const char *name)
static const float imb_working_space_compare_threshold
const char * IMB_colormanagement_get_rect_colorspace(const ImBuf *ibuf)
static void blackbody_temperature_to_rec709(float rec709[3], float t)
static uint colormanage_hashhash(const void *key_v)
void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], const ColorSpace *colorspace)
static bool colormanage_check_colorspace_settings(ColorManagedColorspaceSettings *settings, const char *what)
void IMB_colormanagement_colorspace_items_add(EnumPropertyItem **items, int *totitem)
bool IMB_colormanagement_set_whitepoint(const float whitepoint[3], float &temperature, float &tint)
const char * IMB_colormanagement_colorspace_get_indexed_name(const int index)
void colormanage_cache_free(ImBuf *ibuf)
static float cie_color_match[81][3]
ColormanageProcessor * IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace)
static bool colormanage_check_view_settings(ColorManagedDisplaySettings *display_settings, ColorManagedViewSettings *view_settings, const char *what)
static const int CICP_TRC_BT709
static const int CICP_TRC_SRGB
static blender::VectorSet< blender::StringRefNull > g_all_view_names
static bool g_config_is_custom
void IMB_colormanagement_assign_float_colorspace(ImBuf *ibuf, const char *name)
void IMB_colormanagement_wavelength_to_rgb(float r_dest[4], float value)
const char * IMB_colormanagement_display_get_none_name()
const ColorSpace * IMB_colormanagement_space_get_named(const char *name)
uchar * IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, void **cache_handle)
bool IMB_colormanagement_display_is_hdr(const ColorManagedDisplaySettings *display_settings, const char *view_name)
void IMB_colormanagement_transform_byte(uchar *buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace)
static const int CICP_TRC_G26
static void colormanage_cachedata_set(ImBuf *ibuf, ColormanageCacheData *data)
int IMB_colormanagement_working_space_get_named_index(const char *name)
blender::float3x3 IMB_colormanagement_get_scene_linear_to_xyz()
static std::unique_ptr< ocio::Config > g_config
bool IMB_colormanagement_space_is_scene_linear(const ColorSpace *colorspace)
const ColorSpace * colormanage_colorspace_get_roled(const int role)
static const int CICP_TRC_PQ
void IMB_colormanagement_processor_apply_byte(ColormanageProcessor *cm_processor, uchar *buffer, int width, int height, int channels)
const ColorSpace * colormanage_colorspace_get_named(const char *name)
void IMB_colormanagement_color_picking_to_scene_linear_v3(float scene_linear[3], const float color_picking[3])
uchar * IMB_display_buffer_acquire_ctx(const bContext *C, ImBuf *ibuf, void **cache_handle)
void IMB_colormanagement_view_items_add(EnumPropertyItem **items, int *totitem, const char *display_name)
const char * IMB_colormanagement_view_get_raw_or_default_name(const char *display_name)
static ImBuf * colormanage_cache_get_ibuf(ImBuf *ibuf, ColormanageCacheKey *key, void **cache_handle)
static char global_role_default_sequencer[MAX_COLORSPACE_NAME]
void colormanagement_exit()
const char * IMB_colormanagement_look_get_default_name()
void IMB_colormanagement_check_is_data(ImBuf *ibuf, const char *name)
void colormanagement_init()
static StringRefNull colormanage_find_matching_view_name(const ocio::Display *display, StringRefNull view_name)
bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, float dither, bool predivide)
void IMB_colormanagement_pixel_to_display_space_v4(float result[4], const float pixel[4], const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space)
bool IMB_colormanagement_space_name_is_srgb(const char *name)
static const int CICP_MATRIX_BT709
bool IMB_colormanagement_space_name_is_scene_linear(const char *name)
const char * IMB_colormanagement_look_validate_for_view(const char *view_name, const char *look_name)
void IMB_colormanagement_working_space_init_startup(Main *bmain)
static pthread_mutex_t processor_lock
static char global_role_scene_linear_default[MAX_COLORSPACE_NAME]
ColormanageProcessor * IMB_colormanagement_display_processor_new(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space, const bool inverse)
static const int CICP_TRC_G22
void IMB_colormanagement_transform_byte_to_float(float *float_buffer, uchar *byte_buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace)
static void colormanage_display_buffer_process(ImBuf *ibuf, uchar *display_buffer, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space)
void IMB_display_buffer_transform_apply(uchar *display_buffer, float *linear_buffer, int width, int height, int channels, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, bool predivide)
void IMB_colormanagement_transform_float(float *buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace, bool predivide)
bool IMB_colormanagement_space_is_data(const ColorSpace *colorspace)
void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const uchar *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, int xmin, int ymin, int xmax, int ymax)
static const int CICP_MATRIX_RGB
bool IMB_colormanagement_processor_is_noop(ColormanageProcessor *cm_processor)
static MovieCache * colormanage_moviecache_get(const ImBuf *ibuf)
void IMB_colormanagement_check_file_config(Main *bmain)
static struct GlobalColorPickingState global_color_picking_state
static void colormanage_update_matrices()
static ColormanageCacheData * colormanage_cachedata_get(const ImBuf *ibuf)
bool IMB_colormanagement_setup_glsl_draw_to_scene_linear(const char *from_colorspace_name, const bool predivide)
ImBuf * IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, bool allocate_result, const ImageFormatData *image_format)
static struct GlobalGPUState global_gpu_state
bool IMB_colormanagement_space_name_is_data(const char *name)
bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const bContext *C, const ColorSpace *from_colorspace, float dither, bool predivide)
static bool colormanage_compatible_look(const ocio::Look *look, StringRef view_filter)
void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, const int offset_x, const int offset_y, const int width, const int height, const ImBuf *ibuf, const bool store_premultiplied)
bool IMB_colormanagement_display_processor_needed(const ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
const char * IMB_colormanagement_display_get_indexed_name(const int index)
const ColorSpace * IMB_colormanagement_space_from_interop_id(StringRefNull interop_id)
void IMB_colormanagement_init_untonemapped_view_settings(ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *)
static bool colormanage_hashcmp(const void *av, const void *bv)
const char * IMB_colormanagement_working_space_get()
bool IMB_colormanagement_space_to_cicp(const ColorSpace *colorspace, const ColorManagedFileOutput output, const bool rgb_matrix, int cicp[4])
const char * IMB_colormanagement_srgb_colorspace_name_get()
static bool is_colorspace_same_as_display(const ColorSpace *colorspace, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
static bool imb_colormanagement_working_space_set_from_matrix(Main *bmain, const char *name, const blender::float3x3 &scene_linear_to_xyz)
const char * IMB_colormanagement_look_get_indexed_name(const int index)
void IMB_colormanagement_validate_settings(const ColorManagedDisplaySettings *display_settings, ColorManagedViewSettings *view_settings)
void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], const bool predivide, const ColorSpace *colorspace)
static void do_processor_transform_thread(ProcessorTransformThread *handle)
void IMB_colormanagement_wavelength_to_rgb_table(float *r_table, const int width)
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], const ColorManagedDisplay *display, const ColorManagedDisplaySpace display_space)
void IMB_colormanagement_colorspace_from_ibuf_ftype(ColorManagedColorspaceSettings *colorspace_settings, ImBuf *ibuf)
void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, float pixel[3])
static const float blackbody_table_g[7][3]
void IMB_colormanagegent_copy_settings(ImBuf *ibuf_src, ImBuf *ibuf_dst)
static void processor_transform_apply_threaded(uchar *byte_buffer, float *float_buffer, const int width, const int height, const int channels, ColormanageProcessor *cm_processor, const bool predivide, const bool float_from_byte)
static void colormanagement_transform_ex(uchar *byte_buffer, float *float_buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace, bool predivide)
void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, float *buffer, int width, int height, int channels, bool predivide)
const char * IMB_colormanagement_colorspace_get_name(const ColorSpace *colorspace)
const char * IMB_colormanagement_space_from_filepath_rules(const char *filepath)
bool IMB_colormanagement_setup_glsl_draw_ctx(const bContext *C, float dither, bool predivide)
const char * IMB_colormanagement_view_get_name_by_id(const int index)
static void colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space, bool make_byte)
blender::Vector< char > IMB_colormanagement_space_to_icc_profile(const ColorSpace *colorspace)
void IMB_colormanagement_working_space_convert(Main *bmain, const blender::float3x3 ¤t_scene_linear_to_xyz, const blender::float3x3 &new_xyz_to_scene_linear, const bool depsgraph_tag, const bool linked_only, const bool editable_assets_only)
void IMB_display_buffer_release(void *cache_handle)
void IMB_colormanagement_get_whitepoint(const float temperature, const float tint, float whitepoint[3])
int IMB_colormanagement_view_get_id_by_name(const char *name)
static const int CICP_TRC_HLG
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_display_settings_from_ctx(const bContext *C, ColorManagedViewSettings **r_view_settings, ColorManagedDisplaySettings **r_display_settings)
const char * IMB_colormanagement_get_float_colorspace(const ImBuf *ibuf)
blender::float3x3 IMB_colormanagement_get_xyz_to_scene_linear()
static bool colormanage_load_config(ocio::Config &config)
void IMB_colormanagement_scene_linear_to_colorspace(float *buffer, const int width, const int height, const int channels, const ColorSpace *colorspace)
void IMB_partial_display_buffer_update_threaded(ImBuf *ibuf, const float *linear_buffer, const uchar *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, int xmin, int ymin, int xmax, int ymax)
static blender::float3 imb_working_space_convert(const blender::float3x3 &m, const bool is_smaller_gamut, const blender::float3 in_rgb)
const char * IMB_colormanagement_view_get_default_name(const char *display_name)
const ColorSpace * IMB_colormanagement_space_from_cicp(const int cicp[4], const ColorManagedFileOutput output)
static void colormanage_cache_handle_release(void *cache_handle)
static void do_display_buffer_apply_no_processor(DisplayBufferThread *handle)
static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_buffer, uchar *display_buffer_byte, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space)
static void do_display_buffer_apply_thread(DisplayBufferThread *handle)
static void processor_transform_init_handle(ProcessorTransformThread *handle, int start_line, int tot_line, ProcessorTransformInitData *init_data)
#define DISPLAY_BUFFER_CHANNELS
void IMB_colormanagement_finish_glsl_draw()
static bool colormanage_check_colorspace_name(char *name, const char *what)
void IMB_colormanagement_imbuf_to_byte_texture(uchar *out_buffer, const int offset_x, const int offset_y, const int width, const int height, const ImBuf *ibuf, const bool store_premultiplied)
void colormanage_imbuf_set_default_spaces(ImBuf *ibuf)
static const float blackbody_table_b[7][4]
int IMB_colormanagement_look_get_named_index(const char *name)
static ImBuf * imbuf_ensure_editable(ImBuf *ibuf, ImBuf *colormanaged_ibuf, bool allocate_result)
const char * IMB_colormanagement_display_get_default_view_transform_name(const ColorManagedDisplay *display)
static void colormanage_display_settings_to_cache(ColormanageCacheDisplaySettings *cache_display_settings, const ColorManagedDisplaySettings *display_settings)
static void display_buffer_apply_threaded(ImBuf *ibuf, const float *buffer, uchar *byte_buffer, float *display_buffer, uchar *display_buffer_byte, ColormanageProcessor *cm_processor)
void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, const int width, const int height, const int channels, const ColorSpace *colorspace, const bool predivide)
void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space)
ColormanageProcessor * IMB_colormanagement_display_processor_for_imbuf(const ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySpace display_space)
void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], const ColorManagedDisplay *display, const ColorManagedDisplaySpace display_space)
static void imb_partial_display_buffer_update_ex(ImBuf *ibuf, const float *linear_buffer, const uchar *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, int xmin, int ymin, int xmax, int ymax, bool do_threads)
static const int CICP_PRI_REC2020
static const int CICP_PRI_P3D65
const char * IMB_colormanagement_working_space_get_default()
float3x3 global_scene_linear_to_xyz_default
static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSettings *view_settings, const ColormanageCacheDisplaySettings *display_settings, uchar *display_buffer, void **cache_handle)
void IMB_colormanagement_display_items_add(EnumPropertyItem **items, int *totitem)
const ColorManagedDisplay * IMB_colormanagement_display_get_named(const char *name)
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, const int width, const float min, const float max)
void IMB_colormanagement_scene_linear_to_color_picking_v3(float color_picking[3], const float scene_linear[3])
StringRefNull IMB_colormanagement_space_get_interop_id(const ColorSpace *colorspace)
static char global_role_scene_linear[MAX_COLORSPACE_NAME]
void IMB_colormanagement_working_space_init_default(Main *bmain)
void IMB_colormanagement_blackbody_temperature_to_rgb(float r_dest[4], float value)
static StringRef view_filter_for_look(StringRefNull view_name)
int IMB_colormanagement_colorspace_get_named_index(const char *name)
static bool get_display_emulation(const ColorManagedDisplaySettings &display_settings)
static bool colormanage_role_color_space_name_get(ocio::Config &config, char *colorspace_name, const char *role, const char *backup_role, const bool optional=false)
static char global_role_texture_painting[MAX_COLORSPACE_NAME]
static char global_role_default_float_default[MAX_COLORSPACE_NAME]
static void colormanage_settings_to_key(ColormanageCacheKey *key, const ColormanageCacheViewSettings *view_settings, const ColormanageCacheDisplaySettings *display_settings)
static void curve_mapping_apply_pixel(const CurveMapping *curve_mapping, float *pixel, int channels)
void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_processor, float pixel[4])
void IMB_colormanagement_look_items_add(EnumPropertyItem **items, int *totitem, const char *view_name)
static bool colormanage_use_look(const char *look_name, const char *view_name)
static char global_role_aces_interchange[MAX_COLORSPACE_NAME]
const ColorSpace * IMB_colormangement_display_get_color_space(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
void IMB_colormanagement_working_space_items_add(EnumPropertyItem **items, int *totitem)
static char global_role_default_byte[MAX_COLORSPACE_NAME]
static char global_role_default_float[MAX_COLORSPACE_NAME]
void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
void IMB_partial_display_buffer_update_delayed(ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax)
static bool colormanage_check_display_settings(ColorManagedDisplaySettings *display_settings, const char *what, const ocio::Display *default_display)
static void colormanage_free_config()
void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace)
static const int CICP_PRI_REC709
void IMB_colormanagement_working_space_check(Main *bmain, const bool for_undo, const bool have_editable_assets)
static void colormanage_view_settings_to_cache(ImBuf *ibuf, ColormanageCacheViewSettings *cache_view_settings, const ColorManagedViewSettings *view_settings)
void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor, float pixel[4])
int IMB_colormanagement_display_get_named_index(const char *name)
static char global_role_color_picking[MAX_COLORSPACE_NAME]
static uchar * colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheViewSettings *view_settings, const ColormanageCacheDisplaySettings *display_settings, void **cache_handle)
static void wavelength_to_xyz(float xyz[3], float lambda_nm)
static const int CICP_MATRIX_REC2020_NCL
static const int CICP_RANGE_FULL
const char * IMB_colormanagement_display_get_default_name()
static MovieCache * colormanage_moviecache_ensure(ImBuf *ibuf)
void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace, const ColorManagedFileOutput output)
bool IMB_colormanagement_space_is_srgb(const ColorSpace *colorspace)
bool IMB_colormanagement_display_is_wide_gamut(const ColorManagedDisplaySettings *display_settings, const char *view_name)
bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const ColorSpace *from_colorspace, float dither, bool predivide, bool do_overlay_merge)
void IMB_colormanagement_processor_apply_pixel(ColormanageProcessor *cm_processor, float *pixel, int channels)
const char * IMB_colormanagement_working_space_get_indexed_name(int index)
static void display_buffer_init_handle(DisplayBufferThread *handle, int start_line, int tot_line, DisplayBufferInitData *init_data)
const ImFileType * IMB_file_type_from_ibuf(const ImBuf *ibuf)
void IMB_premultiply_rect_float(float *rect_float, int channels, int w, int h)
MatBase< C, R > inverse(MatBase< C, R >) RET
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
bNodeTree * node_tree_from_id(ID *id)
ColorSceneLinear4f< eAlpha::Straight > unpremultiply_alpha(const ColorSceneLinear4f< Alpha > &color)
ColorSceneLinear4f< eAlpha::Premultiplied > premultiply_alpha(const ColorSceneLinear4f< Alpha > &color)
bool scene_linear_is_rec709
float3x3 rec2020_to_scene_linear
float3x3 acescg_to_scene_linear
float3x3 aces_to_scene_linear
float3x3 scene_linear_to_rec2020
float3x3 rec709_to_scene_linear
float3x3 scene_linear_to_xyz
float3x3 scene_linear_to_rec709
float3x3 scene_linear_to_acescg
float3x3 scene_linear_to_aces
float3x3 xyz_to_scene_linear
T clamp(const T &a, const T &min, const T &max)
float3 whitepoint_from_temp_tint(float temperature, float tint)
bool whitepoint_to_temp_tint(const float3 &white, float &temperature, float &tint)
CartesianBasis invert(const CartesianBasis &basis)
bool is_equal(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, const T epsilon=T(0))
T determinant(const MatBase< T, Size, Size > &mat)
static const float3x3 ACES_TO_XYZ
static const float3x3 XYZ_TO_REC2020
static const float3x3 ACESCG_TO_XYZ
static const float3x3 XYZ_TO_REC709
void foreach_strip(ListBase *seqbase, ForEachFunc callback, void *user_data)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 3, 3 > float3x3
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
struct CurveMapping * curve_mapping
int curve_mapping_timestamp
CurveMapping * curve_mapping
CurveMapping * curve_mapping
ColormanageCacheData * data
CurveMapping * curve_mapping
std::shared_ptr< const ocio::CPUProcessor > cpu_processor
ColormanageProcessor * cm_processor
const char * float_colorspace
const char * byte_colorspace
uchar * display_buffer_byte
const char * byte_colorspace
uchar * display_buffer_byte
ColormanageProcessor * cm_processor
const char * float_colorspace
GlobalColorPickingState()=default
std::shared_ptr< const ocio::CPUProcessor > cpu_processor_to
std::shared_ptr< const ocio::CPUProcessor > cpu_processor_from
CurveMapping * curve_mapping
int curve_mapping_timestamp
CurveMapping * orig_curve_mapping
IDTypeForeachColorFunction foreach_working_space_color
const ColorSpace * colorspace
const ColorSpace * colorspace
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
unsigned int * display_buffer_flags
ColormanageCache * colormanage_cache
bool(* save)(ImBuf *ibuf, const char *filepath, int flags)
LibraryRuntimeHandle * runtime
char scene_linear_name[64]
bool is_missing_opencolorio_config
blender::float3x3 scene_linear_to_xyz
MainColorspace colorspace
char from_color_space[64]
ColorManagedDisplaySettings display_settings
ColorManagedViewSettings view_settings
ColorManagedViewSettings view_settings
ColorManagedDisplaySettings display_settings
static MatBase identity()
StringRefNull from_colorspace
bool use_display_emulation
bool use_display_emulation
CurveMapping * curve_mapping
StringRefNull from_colorspace