23using PixelSpaceProcessor3 = void (*)(
float dst[3],
const float src[3]);
27 static std::shared_ptr<const CPUProcessor>
get()
29 static auto processor = std::make_shared<NOOPDisplayCPUProcessor>();
33 bool is_noop()
const override
38 void apply_rgb(
float [3])
const override {}
39 void apply_rgba(
float [4])
const override {}
41 void apply_rgba_predivide(
float [4])
const override {}
43 void apply(
const PackedImage & )
const override {}
44 void apply_predivide(
const PackedImage & )
const override {}
55 float exponent = 1.0f;
58template<PixelSpaceProcessor3 pixel_space_processor,
bool is_inverse>
59class DisplayCPUProcessor :
public BaseDisplayCPUProcessor {
61 bool is_noop()
const override
66 void apply_rgb(
float rgb[3])
const override
70 void apply_rgba(
float rgba[4])
const override
75 void apply_rgba_predivide(
float rgba[4])
const override
77 if (
ELEM(rgba[3], 1.0f, 0.0f)) {
82 const float alpha = rgba[3];
83 const float inv_alpha = 1.0f / alpha;
96 void apply(
const PackedImage &image)
const override
103 const int num_channels = image.get_num_channels();
104 const size_t width = image.get_width();
105 const size_t height = image.get_height();
107 float *pixels =
static_cast<float *
>(image.get_data());
109 for (
size_t y = 0;
y < height;
y++) {
110 for (
size_t x = 0;
x < width;
x++) {
111 float *pixel = pixels + num_channels * (
y * width +
x);
117 void apply_predivide(
const PackedImage &image)
const override
124 const int num_channels = image.get_num_channels();
125 if (num_channels < 4) {
130 const size_t width = image.get_width();
131 const size_t height = image.get_height();
133 float *pixels =
static_cast<float *
>(image.get_data());
135 for (
size_t y = 0;
y < height;
y++) {
136 for (
size_t x = 0;
x < width;
x++) {
137 float *pixel = pixels + num_channels * (
y * width +
x);
138 apply_rgba_predivide(pixel);
144 void process_rgb(
float rgb[3])
const
146 if constexpr (is_inverse) {
148 const float inv_exponent = 1.0f / exponent;
149 rgb[0] = rgb[0] != 0.0f ?
math::pow(rgb[0], inv_exponent) : 0.0f;
150 rgb[1] = rgb[1] != 0.0f ?
math::pow(rgb[1], inv_exponent) : 0.0f;
151 rgb[2] = rgb[2] != 0.0f ?
math::pow(rgb[2], inv_exponent) : 0.0f;
159 pixel_space_processor(rgb, rgb);
166 pixel_space_processor(rgb, rgb);
180 if (display_parameters.
display !=
"sRGB") {
181 return NOOPDisplayCPUProcessor::get();
184 if (display_parameters.
view !=
"Standard") {
185 return NOOPDisplayCPUProcessor::get();
187 if (!
ELEM(display_parameters.
look,
"",
"None")) {
188 return NOOPDisplayCPUProcessor::get();
192 return NOOPDisplayCPUProcessor::get();
195 std::shared_ptr<BaseDisplayCPUProcessor> processor;
198 if (display_parameters.
inverse) {
199 processor = std::make_shared<DisplayCPUProcessor<srgb_to_linearrgb_v3_v3, true>>();
202 processor = std::make_shared<DisplayCPUProcessor<linearrgb_to_srgb_v3_v3, false>>();
206 if (display_parameters.
inverse) {
207 processor = std::make_shared<DisplayCPUProcessor<linearrgb_to_srgb_v3_v3, true>>();
210 processor = std::make_shared<DisplayCPUProcessor<srgb_to_linearrgb_v3_v3, false>>();
214 return NOOPDisplayCPUProcessor::get();
218 processor->exponent = display_parameters.
exponent;
224 processor->matrix *= matrix;
227 if (display_parameters.
inverse) {
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void apply(bContext &C, GestureData &gesture_data, wmOperator &op)
T pow(const T &x, const T &power)
CartesianBasis invert(const CartesianBasis &basis)
T max(const T &a, const T &b)
std::shared_ptr< const T > get(const GenericKey &key, FunctionRef< std::unique_ptr< T >()> compute_fn)
std::shared_ptr< const CPUProcessor > create_fallback_display_cpu_processor(const Config &config, const DisplayParameters &display_parameters)
float3x3 calculate_white_point_matrix(const Config &config, const float temperature, const float tint)
MatBase< float, 3, 3 > float3x3
static MatBase identity()
StringRefNull from_colorspace