Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
color_conversion.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2018-2019 Edgardo Hoszowski.
4 Copyright (C) 2019, 2021 Aurélien PIERRE.
5 Copyright (C) 2019 Pascal Obry.
6 Copyright (C) 2020 Harold le Clément de Saint-Marcq.
7 Copyright (C) 2021 David Koller.
8 Copyright (C) 2021 mtvoid.
9 Copyright (C) 2022 Philipp Lutz.
10
11 darktable is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 darktable is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with darktable. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "common.h"
26#include "colorspace.h"
27
28// must be in synch with dt_iop_colorspace_type_t in imageop.h
39
40// must be in synch with dt_colorspaces_iccprofile_info_cl_t
51
52static inline float lerp_lookup_unbounded(const float x, read_only image2d_t lut,
53 constant const float *const unbounded_coeffs,
54 const int n_lut, const int lutsize)
55{
56 // in case the tone curve is marked as linear, return the fast
57 // path to linear unbounded (does not clip x at 1)
58 if(unbounded_coeffs[0] >= 0.0f)
59 {
60 if(x < 1.0f)
61 {
62 const float ft = clamp(x * (float)(lutsize - 1), 0.0f, (float)(lutsize - 1));
63 const int t = ft < lutsize - 2 ? ft : lutsize - 2;
64 const float f = ft - t;
65 const int tx = t & 0xff;
66 const int ty = (t >> 8) + n_lut * 256;
67
68 // Fast path: one hardware-linear fetch when both samples are on the same LUT row.
69 if(tx < 255)
70 return read_imagef(lut, samplerf, (float2)(tx + f + 0.5f, ty + 0.5f)).x;
71
72 // Seam fallback keeps exact row-major interpolation at x=255 -> x=0 (next row).
73 const int2 p1 = (int2)(tx, ty);
74 const int2 p2 = (int2)(0, ty + 1);
75 const float l1 = read_imagef(lut, sampleri, p1).x;
76 const float l2 = read_imagef(lut, sampleri, p2).x;
77 return fma(f, l2 - l1, l1);
78 }
79 else return unbounded_coeffs[1] * native_powr(x*unbounded_coeffs[0], unbounded_coeffs[2]);
80 }
81 else return x;
82}
83
84static inline float lookup(read_only image2d_t lut, const float x)
85{
86 const int xi = clamp((int)(x * 0x10000ul), 0, 0xffff);
87 const int2 p = (int2)((xi & 0xff), (xi >> 8));
88 return read_imagef(lut, sampleri, p).x;
89}
90
91static inline float lookup_unbounded(read_only image2d_t lut, const float x, constant const float *const a)
92{
93 // in case the tone curve is marked as linear, return the fast
94 // path to linear unbounded (does not clip x at 1)
95 if(a[0] >= 0.0f)
96 {
97 if(x < 1.0f)
98 {
99 const int xi = clamp((int)(x * 0x10000ul), 0, 0xffff);
100 const int2 p = (int2)((xi & 0xff), (xi >> 8));
101 return read_imagef(lut, sampleri, p).x;
102 }
103 else return a[1] * native_powr(x*a[0], a[2]);
104 }
105 else return x;
106}
107
108static inline float4 apply_trc_in(const float4 rgb_in,
109 constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info,
110 read_only image2d_t lut)
111{
112 const float R = lerp_lookup_unbounded(rgb_in.x, lut, profile_info->unbounded_coeffs_in[0], 0, profile_info->lutsize);
113 const float G = lerp_lookup_unbounded(rgb_in.y, lut, profile_info->unbounded_coeffs_in[1], 1, profile_info->lutsize);
114 const float B = lerp_lookup_unbounded(rgb_in.z, lut, profile_info->unbounded_coeffs_in[2], 2, profile_info->lutsize);
115 const float a = rgb_in.w;
116 return (float4)(R, G, B, a);
117}
118
119static inline float4 apply_trc_out(const float4 rgb_in,
120 constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info,
121 read_only image2d_t lut)
122{
123 const float R = lerp_lookup_unbounded(rgb_in.x, lut, profile_info->unbounded_coeffs_out[0], 3, profile_info->lutsize);
124 const float G = lerp_lookup_unbounded(rgb_in.y, lut, profile_info->unbounded_coeffs_out[1], 4, profile_info->lutsize);
125 const float B = lerp_lookup_unbounded(rgb_in.z, lut, profile_info->unbounded_coeffs_out[2], 5, profile_info->lutsize);
126 const float a = rgb_in.w;
127 return (float4)(R, G, B, a);
128}
129
130static inline float get_rgb_matrix_luminance(const float4 rgb,
131 constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info,
132 constant const float *const matrix, read_only image2d_t lut)
133{
134 float luminance = 0.f;
135
136 if(profile_info->nonlinearlut)
137 {
138 float4 linear_rgb;
139
140 linear_rgb = apply_trc_in(rgb, profile_info, lut);
141 luminance = matrix[3] * linear_rgb.x + matrix[4] * linear_rgb.y + matrix[5] * linear_rgb.z;
142 }
143 else
144 luminance = matrix[3] * rgb.x + matrix[4] * rgb.y + matrix[5] * rgb.z;
145
146 return luminance;
147}
148
149static inline float4 rgb_matrix_to_xyz(const float4 rgb,
150 constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info,
151 constant const float *const matrix, read_only image2d_t lut)
152{
153 float4 out;
154 if(profile_info->nonlinearlut)
155 {
156 float4 linear_rgb = apply_trc_in(rgb, profile_info, lut);
157 out = matrix_product(linear_rgb, matrix);
158 }
159 else
160 {
162 }
163 return out;
164}
165
166static inline float dt_camera_rgb_luminance(const float4 rgb)
167{
168 const float4 coeffs = { 0.2225045f, 0.7168786f, 0.0606169f, 0.0f };
169 return dot(rgb, coeffs);
170}
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:315
static float4 apply_trc_in(const float4 rgb_in, constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info, read_only image2d_t lut)
Definition color_conversion.h:108
static float4 rgb_matrix_to_xyz(const float4 rgb, constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info, constant const float *const matrix, read_only image2d_t lut)
Definition color_conversion.h:149
static float lookup(read_only image2d_t lut, const float x)
Definition color_conversion.h:84
static float lookup_unbounded(read_only image2d_t lut, const float x, constant const float *const a)
Definition color_conversion.h:91
static float dt_camera_rgb_luminance(const float4 rgb)
Definition color_conversion.h:166
static float get_rgb_matrix_luminance(const float4 rgb, constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info, constant const float *const matrix, read_only image2d_t lut)
Definition color_conversion.h:130
dt_iop_colorspace_type_t
Definition color_conversion.h:30
@ IOP_CS_RAW
Definition color_conversion.h:32
@ IOP_CS_LCH
Definition color_conversion.h:35
@ IOP_CS_JZCZHZ
Definition color_conversion.h:37
@ IOP_CS_RGB
Definition color_conversion.h:34
@ IOP_CS_HSL
Definition color_conversion.h:36
@ IOP_CS_LAB
Definition color_conversion.h:33
@ IOP_CS_NONE
Definition color_conversion.h:31
static float lerp_lookup_unbounded(const float x, read_only image2d_t lut, constant const float *const unbounded_coeffs, const int n_lut, const int lutsize)
Definition color_conversion.h:52
static float4 apply_trc_out(const float4 rgb_in, constant const dt_colorspaces_iccprofile_info_cl_t *const profile_info, read_only image2d_t lut)
Definition color_conversion.h:119
float float2[2]
Definition colormapping.c:86
static float4 matrix_product(const float4 xyz, constant const float *const matrix)
Definition colorspace.h:43
#define B(y, x)
Definition colorspaces.c:187
const dt_aligned_pixel_t f
Definition colorspaces_inline_conversions.h:256
const float a
Definition colorspaces_inline_conversions.h:1292
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
static dt_aligned_pixel_t rgb
Definition colorspaces_inline_conversions.h:530
static const dt_colormatrix_t matrix
Definition colorspaces_inline_conversions.h:182
constant sampler_t sampleri
Definition data/kernels/common.h:25
constant sampler_t samplerf
Definition data/kernels/common.h:27
static double dot(int g[], double x, double y, double z)
Definition grain.c:179
static const float x
Definition iop_profile.h:239
const float l2
Definition iop_profile.h:230
static const float *const lut
Definition iop_profile.h:246
const int t
Definition iop_profile.h:227
const float l1
Definition iop_profile.h:229
static const float const int lutsize
Definition iop_profile.h:224
#define R
static float clamp(float f, float m, float M)
Definition noiseprofile.c:162
Definition color_conversion.h:42
int lutsize
Definition color_conversion.h:45
float grey
Definition color_conversion.h:49
int nonlinearlut
Definition color_conversion.h:48
float unbounded_coeffs_out[3][3]
Definition color_conversion.h:47
float matrix_out[9]
Definition color_conversion.h:44
float unbounded_coeffs_in[3][3]
Definition color_conversion.h:46
float matrix_in[9]
Definition color_conversion.h:43