Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
iop_profile.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2020 darktable developers.
4
5 darktable is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 darktable is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef DT_IOP_PROFILE_H
20#define DT_IOP_PROFILE_H
21
23#include "common/colorspaces.h"
24#include "common/matrices.h"
25#include "develop/imageop.h"
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#ifdef HAVE_OPENCL
32#include <CL/cl.h> // for cl_mem
33#endif
34
35struct dt_iop_module_t;
36struct dt_develop_t;
39
41{
45 dt_colormatrix_t matrix_in; // don't align on more than 16 bits or OpenCL will fail
48 float *lut_in[3];
49 float *lut_out[3];
50 float unbounded_coeffs_in[3][3] DT_ALIGNED_PIXEL;
51 float unbounded_coeffs_out[3][3] DT_ALIGNED_PIXEL;
53 float grey;
54 dt_colormatrix_t matrix_in_transposed; // same as matrix_in, but stored such as to permit vectorization
55 dt_colormatrix_t matrix_out_transposed; // same as matrix_out, but stored such as to permit vectorization
57
59void dt_ioppr_init_profile_info(dt_iop_order_iccprofile_info_t *profile_info, const int lutsize);
62
68 const char *profile_filename);
69
75 const dt_colorspaces_color_profile_type_t profile_type,
76 const char *profile_filename,
77 const int intent);
78
84 GList *iop_list);
86 GList *iop_list);
87
94 struct dt_dev_pixelpipe_t *pipe,
96 const char *filename,
97 const int intent);
98
101 struct dt_dev_pixelpipe_t *pipe,
103 const char *filename,
104 const int intent, const dt_colormatrix_t matrix_in);
105
108 struct dt_dev_pixelpipe_t *pipe,
110 const char *filename,
111 const int intent);
112
117
122
125 struct dt_dev_pixelpipe_t *pipe);
126
130 const char **profile_filename);
134 const char **profile_filename);
138 const char **profile_filename);
139
141void dt_ioppr_transform_image_colorspace(struct dt_iop_module_t *self, const float *const image_in,
142 float *const image_out, const int width, const int height,
143 const int cst_from, const int cst_to, int *converted_cst,
144 const dt_iop_order_iccprofile_info_t *const profile_info);
145
146void dt_ioppr_transform_image_colorspace_rgb(const float *const image_in, float *const image_out, const int width,
147 const int height,
148 const dt_iop_order_iccprofile_info_t *const profile_info_from,
149 const dt_iop_order_iccprofile_info_t *const profile_info_to,
150 const char *message);
151
152#ifdef HAVE_OPENCL
153typedef struct dt_colorspaces_cl_global_t
154{
155 int kernel_colorspaces_transform_lab_to_rgb_matrix;
156 int kernel_colorspaces_transform_rgb_matrix_to_lab;
157 int kernel_colorspaces_transform_rgb_matrix_to_rgb;
158} dt_colorspaces_cl_global_t;
159
160// must be in synch with colorspaces.cl dt_colorspaces_iccprofile_info_cl_t
162{
163 cl_float matrix_in[9];
164 cl_float matrix_out[9];
165 cl_int lutsize;
166 cl_float unbounded_coeffs_in[3][3];
167 cl_float unbounded_coeffs_out[3][3];
168 cl_int nonlinearlut;
169 cl_float grey;
171
172dt_colorspaces_cl_global_t *dt_colorspaces_init_cl_global(void);
173void dt_colorspaces_free_cl_global(dt_colorspaces_cl_global_t *g);
174
178void dt_ioppr_get_profile_info_cl(const dt_iop_order_iccprofile_info_t *const profile_info, dt_colorspaces_iccprofile_info_cl_t *profile_info_cl);
182cl_float *dt_ioppr_get_trc_cl(const dt_iop_order_iccprofile_info_t *const profile_info);
183
185cl_int dt_ioppr_build_iccprofile_params_cl(const dt_iop_order_iccprofile_info_t *const profile_info,
186 const int devid, dt_colorspaces_iccprofile_info_cl_t **_profile_info_cl,
187 cl_float **_profile_lut_cl, cl_mem *_dev_profile_info,
188 cl_mem *_dev_profile_lut);
190void dt_ioppr_free_iccprofile_params_cl(dt_colorspaces_iccprofile_info_cl_t **_profile_info_cl,
191 cl_float **_profile_lut_cl, cl_mem *_dev_profile_info,
192 cl_mem *_dev_profile_lut);
193
195int dt_ioppr_transform_image_colorspace_cl(struct dt_iop_module_t *self, const int devid, cl_mem dev_img_in,
196 cl_mem dev_img_out, const int width, const int height,
197 const int cst_from, const int cst_to, int *converted_cst,
198 const dt_iop_order_iccprofile_info_t *const profile_info);
199
200int dt_ioppr_transform_image_colorspace_rgb_cl(const int devid, cl_mem dev_img_in, cl_mem dev_img_out,
201 const int width, const int height,
202 const dt_iop_order_iccprofile_info_t *const profile_info_from,
203 const dt_iop_order_iccprofile_info_t *const profile_info_to,
204 const char *message);
205#endif
206
209#ifdef _OPENMP
210#pragma omp declare simd aligned(lut:64)
211#endif
212static inline float extrapolate_lut(const float *const lut, const float v, const int lutsize)
213{
214 // TODO: check if optimization is worthwhile!
215 const float ft = CLAMPS(v * (lutsize - 1), 0, lutsize - 1);
216 const int t = (ft < lutsize - 2) ? ft : lutsize - 2;
217 const float f = ft - t;
218 const float l1 = lut[t];
219 const float l2 = lut[t + 1];
220 return l1 * (1.0f - f) + l2 * f;
221}
222
223
224#ifdef _OPENMP
225#pragma omp declare simd
226#endif
227static inline float eval_exp(const float coeff[3], const float x)
228{
229 return coeff[1] * powf(x * coeff[0], coeff[2]);
230}
231
232
233#ifdef _OPENMP
234#pragma omp declare simd \
235 aligned(rgb_in, rgb_out, unbounded_coeffs:16) \
236 aligned(lut:64) \
237 uniform(rgb_in, rgb_out, unbounded_coeffs, lut)
238#endif
239static inline void _apply_trc(const dt_aligned_pixel_t rgb_in, dt_aligned_pixel_t rgb_out,
240 float *const lut[3],
241 const float unbounded_coeffs[3][3],
242 const int lutsize)
243{
244 for(int c = 0; c < 3; c++)
245 {
246 rgb_out[c] = (lut[c][0] >= 0.0f) ? ((rgb_in[c] < 1.0f) ? extrapolate_lut(lut[c], rgb_in[c], lutsize)
247 : eval_exp(unbounded_coeffs[c], rgb_in[c]))
248 : rgb_in[c];
249 }
250}
251
252#ifdef _OPENMP
253#pragma omp declare simd \
254 aligned(rgb, matrix_in, unbounded_coeffs_in:16) \
255 aligned(lut_in:64) \
256 uniform(rgb, matrix_in, lut_in, unbounded_coeffs_in)
257#endif
258static inline float dt_ioppr_get_rgb_matrix_luminance(const dt_aligned_pixel_t rgb,
259 const dt_colormatrix_t matrix_in, float *const lut_in[3],
260 const float unbounded_coeffs_in[3][3],
261 const int lutsize, const int nonlinearlut)
262{
263 float luminance = 0.f;
264
265 if(nonlinearlut)
266 {
267 dt_aligned_pixel_t linear_rgb;
268 _apply_trc(rgb, linear_rgb, lut_in, unbounded_coeffs_in, lutsize);
269 luminance = matrix_in[1][0] * linear_rgb[0] + matrix_in[1][1] * linear_rgb[1] + matrix_in[1][2] * linear_rgb[2];
270 }
271 else
272 luminance = matrix_in[1][0] * rgb[0] + matrix_in[1][1] * rgb[1] + matrix_in[1][2] * rgb[2];
273
274 return luminance;
275}
276
277
278#ifdef _OPENMP
279#pragma omp declare simd \
280 aligned(unbounded_coeffs_in:16) \
281 aligned(lut_in:64) \
282 uniform(lut_in, unbounded_coeffs_in)
283#endif
284static inline void dt_ioppr_rgb_matrix_to_xyz(const dt_aligned_pixel_t rgb, dt_aligned_pixel_t xyz,
285 const dt_colormatrix_t matrix_in_transposed, float *const lut_in[3],
286 const float unbounded_coeffs_in[3][3],
287 const int lutsize, const int nonlinearlut)
288{
289 if(nonlinearlut)
290 {
291 dt_aligned_pixel_t linear_rgb;
292 _apply_trc(rgb, linear_rgb, lut_in, unbounded_coeffs_in, lutsize);
293 dt_apply_transposed_color_matrix(linear_rgb, matrix_in_transposed, xyz);
294 }
295 else
296 dt_apply_transposed_color_matrix(rgb, matrix_in_transposed, xyz);
297}
298
299#ifdef _OPENMP
300#pragma omp declare simd \
301 aligned(unbounded_coeffs_out:16) \
302 aligned(lut_out:64) \
303 uniform(lut_out, unbounded_coeffs_out)
304#endif
305static inline void dt_ioppr_lab_to_rgb_matrix(const dt_aligned_pixel_t lab, dt_aligned_pixel_t rgb,
306 const dt_colormatrix_t matrix_out_transposed, float *const lut_out[3],
307 const float unbounded_coeffs_out[3][3],
308 const int lutsize, const int nonlinearlut)
309{
310 dt_aligned_pixel_t xyz;
311 dt_Lab_to_XYZ(lab, xyz);
312
313 if(nonlinearlut)
314 {
315 dt_aligned_pixel_t linear_rgb;
316 dt_apply_transposed_color_matrix(xyz, matrix_out_transposed, linear_rgb);
317 _apply_trc(linear_rgb, rgb, lut_out, unbounded_coeffs_out, lutsize);
318 }
319 else
320 {
321 dt_apply_transposed_color_matrix(xyz, matrix_out_transposed, rgb);
322 }
323}
324
325#ifdef _OPENMP
326#pragma omp declare simd \
327 aligned(unbounded_coeffs_in:16) \
328 aligned(lut_in:64) \
329 uniform(lut_in, unbounded_coeffs_in)
330#endif
331static inline void dt_ioppr_rgb_matrix_to_lab(const dt_aligned_pixel_t rgb, dt_aligned_pixel_t lab,
332 const dt_colormatrix_t matrix_in_transposed, float *const lut_in[3],
333 const float unbounded_coeffs_in[3][3],
334 const int lutsize, const int nonlinearlut)
335{
336 dt_aligned_pixel_t xyz = { 0.f };
337 dt_ioppr_rgb_matrix_to_xyz(rgb, xyz, matrix_in_transposed, lut_in, unbounded_coeffs_in, lutsize, nonlinearlut);
338 dt_XYZ_to_Lab(xyz, lab);
339}
340
341static inline float dt_ioppr_get_profile_info_middle_grey(const dt_iop_order_iccprofile_info_t *const profile_info)
342{
343 return profile_info->grey;
344}
345
346#ifdef _OPENMP
347#pragma omp declare simd
348#endif
349static inline float dt_ioppr_compensate_middle_grey(const float x, const dt_iop_order_iccprofile_info_t *const profile_info)
350{
351 // we transform the curve nodes from the image colorspace to lab
352 dt_aligned_pixel_t lab = { 0.0f };
353 const dt_aligned_pixel_t rgb = { x, x, x };
354 dt_ioppr_rgb_matrix_to_lab(rgb, lab, profile_info->matrix_in_transposed, profile_info->lut_in,
355 profile_info->unbounded_coeffs_in, profile_info->lutsize, profile_info->nonlinearlut);
356 return lab[0] * .01f;
357}
358
359#ifdef _OPENMP
360#pragma omp declare simd
361#endif
362static inline float dt_ioppr_uncompensate_middle_grey(const float x, const dt_iop_order_iccprofile_info_t *const profile_info)
363{
364 // we transform the curve nodes from lab to the image colorspace
365 const dt_aligned_pixel_t lab = { x * 100.f, 0.0f, 0.0f };
366 dt_aligned_pixel_t rgb = { 0.0f };
367
368 dt_ioppr_lab_to_rgb_matrix(lab, rgb, profile_info->matrix_out_transposed, profile_info->lut_out,
369 profile_info->unbounded_coeffs_out, profile_info->lutsize, profile_info->nonlinearlut);
370 return rgb[0];
371}
372
373#endif
374// clang-format off
375// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
376// vim: shiftwidth=2 expandtab tabstop=2 cindent
377// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
378// clang-format on
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
dt_iop_color_intent_t
Definition colorspaces.h:43
#define DT_IOP_COLOR_ICC_LEN
Definition colorspaces.h:37
dt_colorspaces_color_profile_type_t
Definition colorspaces.h:61
static void dt_apply_transposed_color_matrix(const dt_aligned_pixel_t in, const dt_colormatrix_t matrix, dt_aligned_pixel_t out)
Definition colorspaces_inline_conversions.h:167
static void dt_XYZ_to_Lab(const dt_aligned_pixel_t XYZ, dt_aligned_pixel_t Lab)
Definition colorspaces_inline_conversions.h:212
static void dt_Lab_to_XYZ(const dt_aligned_pixel_t Lab, dt_aligned_pixel_t XYZ)
Definition colorspaces_inline_conversions.h:236
int type
Definition common/metadata.c:42
static float f(const float t, const float c, const float x)
Definition graduatednd.c:173
dt_iop_order_iccprofile_info_t * dt_ioppr_add_profile_info_to_list(struct dt_develop_t *dev, const dt_colorspaces_color_profile_type_t profile_type, const char *profile_filename, const int intent)
Definition iop_profile.c:741
void dt_ioppr_transform_image_colorspace(struct dt_iop_module_t *self, const float *const image_in, float *const image_out, const int width, const int height, const int cst_from, const int cst_to, int *converted_cst, const dt_iop_order_iccprofile_info_t *const profile_info)
Definition iop_profile.c:1017
void dt_ioppr_get_work_profile_type(struct dt_develop_t *dev, dt_colorspaces_color_profile_type_t *profile_type, const char **profile_filename)
Definition iop_profile.c:922
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_work_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent)
Definition iop_profile.c:808
void dt_ioppr_transform_image_colorspace_rgb(const float *const image_in, float *const image_out, const int width, const int height, const dt_iop_order_iccprofile_info_t *const profile_info_from, const dt_iop_order_iccprofile_info_t *const profile_info_to, const char *message)
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_output_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent)
Definition iop_profile.c:861
static float extrapolate_lut(const float *const lut, const float v, const int lutsize)
Definition iop_profile.h:212
static float dt_ioppr_compensate_middle_grey(const float x, const dt_iop_order_iccprofile_info_t *const profile_info)
Definition iop_profile.h:349
dt_iop_order_iccprofile_info_t * dt_ioppr_get_iop_input_profile_info(struct dt_iop_module_t *module, GList *iop_list)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_histogram_profile_info(struct dt_develop_t *dev)
static void _apply_trc(const dt_aligned_pixel_t rgb_in, dt_aligned_pixel_t rgb_out, float *const lut[3], const float unbounded_coeffs[3][3], const int lutsize)
Definition iop_profile.h:239
dt_iop_order_iccprofile_info_t * dt_ioppr_get_profile_info_from_list(struct dt_develop_t *dev, dt_colorspaces_color_profile_type_t profile_type, const char *profile_filename)
Definition iop_profile.c:721
void dt_ioppr_get_input_profile_type(struct dt_develop_t *dev, dt_colorspaces_color_profile_type_t *profile_type, const char **profile_filename)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_input_profile_info(struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:892
static void dt_ioppr_rgb_matrix_to_lab(const dt_aligned_pixel_t rgb, dt_aligned_pixel_t lab, const dt_colormatrix_t matrix_in_transposed, float *const lut_in[3], const float unbounded_coeffs_in[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:331
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_current_profile_info(struct dt_iop_module_t *module, struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:902
dt_iop_order_iccprofile_info_t * dt_ioppr_get_iop_work_profile_info(struct dt_iop_module_t *module, GList *iop_list)
Definition iop_profile.c:765
static float dt_ioppr_get_rgb_matrix_luminance(const dt_aligned_pixel_t rgb, const dt_colormatrix_t matrix_in, float *const lut_in[3], const float unbounded_coeffs_in[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:258
static float dt_ioppr_uncompensate_middle_grey(const float x, const dt_iop_order_iccprofile_info_t *const profile_info)
Definition iop_profile.h:362
static float eval_exp(const float coeff[3], const float x)
Definition iop_profile.h:227
static float dt_ioppr_get_profile_info_middle_grey(const dt_iop_order_iccprofile_info_t *const profile_info)
Definition iop_profile.h:341
static void dt_ioppr_lab_to_rgb_matrix(const dt_aligned_pixel_t lab, dt_aligned_pixel_t rgb, const dt_colormatrix_t matrix_out_transposed, float *const lut_out[3], const float unbounded_coeffs_out[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:305
void dt_ioppr_cleanup_profile_info(dt_iop_order_iccprofile_info_t *profile_info)
Definition iop_profile.c:621
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:887
static void dt_ioppr_rgb_matrix_to_xyz(const dt_aligned_pixel_t rgb, dt_aligned_pixel_t xyz, const dt_colormatrix_t matrix_in_transposed, float *const lut_in[3], const float unbounded_coeffs_in[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:284
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_input_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent, const dt_colormatrix_t matrix_in)
Definition iop_profile.c:827
void dt_ioppr_get_export_profile_type(struct dt_develop_t *dev, dt_colorspaces_color_profile_type_t *profile_type, const char **profile_filename)
Definition iop_profile.c:969
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_output_profile_info(struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:897
void dt_ioppr_init_profile_info(dt_iop_order_iccprofile_info_t *profile_info, const int lutsize)
Definition iop_profile.c:599
#define CLAMPS(A, L, H)
Definition math.h:68
float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]
Definition matrices.h:24
Definition color_conversion.h:36
int lutsize
Definition color_conversion.h:39
float grey
Definition color_conversion.h:43
int nonlinearlut
Definition color_conversion.h:42
float unbounded_coeffs_out[3][3]
Definition color_conversion.h:41
float matrix_out[9]
Definition color_conversion.h:38
float unbounded_coeffs_in[3][3]
Definition color_conversion.h:40
float matrix_in[9]
Definition color_conversion.h:37
Definition pixelpipe_hb.h:46
Definition pixelpipe_hb.h:127
Definition develop.h:143
Definition imageop.h:182
Definition iop_profile.h:41
int nonlinearlut
Definition iop_profile.h:52
int lutsize
Definition iop_profile.h:47
dt_iop_color_intent_t intent
Definition iop_profile.h:44
dt_colormatrix_t matrix_out_transposed
Definition iop_profile.h:55
float grey
Definition iop_profile.h:53
dt_colorspaces_color_profile_type_t type
Definition iop_profile.h:42
float * lut_out[3]
Definition iop_profile.h:49
dt_colormatrix_t matrix_out
Definition iop_profile.h:46
float * lut_in[3]
Definition iop_profile.h:48
char filename[DT_IOP_COLOR_ICC_LEN]
Definition iop_profile.h:43
float unbounded_coeffs_in[3][3] DT_ALIGNED_PIXEL
Definition iop_profile.h:50
dt_colormatrix_t matrix_in_transposed
Definition iop_profile.h:54
dt_colormatrix_t matrix_in
Definition iop_profile.h:45
float unbounded_coeffs_out[3][3] DT_ALIGNED_PIXEL
Definition iop_profile.h:51