107 return C_(
"modulename",
"display encoding");
191static inline
void _write_pixel(const
float *const restrict in, uint8_t *const restrict
out,
193 const
size_t pixel_index, const
float alpha)
196 const size_t y = pixel_index /
preview->width;
197 const size_t x = pixel_index - y *
preview->width;
199 const gboolean first_y = y %
preview->checker_1 < y %
preview->checker_2;
200 const float *
const checker_color
201 = first_x == first_y ?
preview->checker_color_2 :
preview->checker_color_1;
203 for(
size_t c = 0; c < 3; c++)
205 const float value = in[c] * (1.0f - alpha) + checker_color[c] * alpha;
206 pixel[c] =
value <= 0.0031308f ? 12.92f *
value
207 : (1.0f + 0.055f) * powf(
value, 1.0f / 2.4f) - 0.055f;
211 for(
size_t c = 0; c < 3; c++)
213 const float value = roundf(255.0f * pixel[c]);
214 out[2 - c] = (uint8_t)(fminf(fmaxf(
value, 0.0f), 255.0f));
218static inline
__attribute__((always_inline))
void _normalize_color(float *const restrict pixel, const float norm)
221 const float factor = norm / fmaxf(pixel[0], fmaxf(pixel[1], pixel[2]));
227static inline
void _XYZ_to_REC_709_normalized(const float *const restrict
XYZ, float *const restrict
sRGB,
231 _normalize_color(
sRGB, norm);
235 const size_t buffsize,
const float alpha,
240 for(
size_t j = 0; j < buffsize; j += 4)
248 const size_t buffsize,
const float alpha,
256 for(
size_t j = 0; j < buffsize; j += 4)
261 const float value = fminf(fmaxf(in[j + 1] * 256.0f - 128.0f, -56.0f), 56.0f);
264 _XYZ_to_REC_709_normalized(xyz, pixel, 0.75f);
270 for(
size_t j = 0; j < buffsize; j += 4)
274 const float value = fminf(fmaxf(in[j + 1] * 256.0f - 128.0f, -65.0f), 65.0f);
277 _XYZ_to_REC_709_normalized(xyz, pixel, 0.75f);
283 for(
size_t j = 0; j < buffsize; j += 4)
291 for(
size_t j = 0; j < buffsize; j += 4)
299 for(
size_t j = 0; j < buffsize; j += 4)
309 for(
size_t j = 0; j < buffsize; j += 4)
317 for(
size_t j = 0; j < buffsize; j += 4)
321 dt_LCH_2_Lab(lch, lab);
324 _XYZ_to_REC_709_normalized(xyz, pixel, 0.75f);
330 for(
size_t j = 0; j < buffsize; j += 4)
334 dt_HSL_2_RGB(hsl, pixel);
335 _normalize_color(pixel, 0.75f);
341 for(
size_t j = 0; j < buffsize; j += 4)
347 dt_JzCzhz_2_JzAzBz(JzCzhz,
JzAzBz);
349 dt_XYZ_to_Rec709_D65(
XYZ_D65, pixel);
350 _normalize_color(pixel, 0.75f);
364static void _mask_display(
const float *
const restrict in, uint8_t *
const restrict
out,
const size_t buffsize,
369 for(
size_t j = 0; j < buffsize; j += 4)
374 const float gray = 0.3f * in[j + 0] + 0.59f * in[j + 1] + 0.11f * in[j + 2];
375 pixel[0] = pixel[1] = pixel[2] = gray;
377 const float hide = 1.0f - fminf(fmaxf(in[j + 3] * alpha, 0.0f), 1.0f);
382static void _copy_output(
const float *
const restrict in, uint8_t *
const restrict
out,
const size_t buffsize)
385 for(
size_t j = 0; j < buffsize; j += 4)
388 for(
size_t c = 0; c < 3; c++)
390 out[j + 2 - c] = (uint8_t)(fminf(roundf(255.0f * fmaxf(in[j + c], 0.0f)), 255.0f));
400 const size_t buffsize = (size_t)roi_out->
width * roi_out->
height * 4;
404 _copy_output((
const float *
const restrict)
i, (uint8_t *
const restrict)
o, buffsize);
415 _copy_output((
const float *
const restrict)
i, (uint8_t *
const restrict)
o, buffsize);
444 _copy_output((
const float *
const restrict)
i, (uint8_t *
const restrict)
o, buffsize);
487 cl_int err = CL_SUCCESS;
513 for(
int c = 0; c < 4; c++)
515 checker_color_1[c] =
d->preview.checker_color_1[c];
516 checker_color_2[c] =
d->preview.checker_color_2[c];
518 const int checker_1 = (int)
d->preview.checker_1;
519 const int checker_2 = (int)
d->preview.checker_2;
520 const int black_and_white =
d->preview.black_and_white ? 1 : 0;
550 _Static_assert(
sizeof(checker_color_1) == 4 *
sizeof(
float),
"checker colour 1 must be a float4, not a pointer");
551 _Static_assert(
sizeof(checker_color_2) == 4 *
sizeof(
float),
"checker colour 2 must be a float4, not a pointer");
559 if(err == CL_SUCCESS)
return TRUE;
567 const int program = 2;
585 module->params = calloc(1, sizeof(dt_iop_gamma_params_t));
586 module->default_params = calloc(1, sizeof(dt_iop_gamma_params_t));
587 module->params_size = sizeof(dt_iop_gamma_params_t);
588 module->hide_enable_button = 1;
589 module->default_enabled = 1;
612 piece->data_size = 0;
637 if(!
piece->enabled)
return;
646 const float checker_1_rgb[3] = {
647 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker1/red"), 0.0f, 1.0f),
648 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker1/green"), 0.0f, 1.0f),
649 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker1/blue"), 0.0f, 1.0f)
651 const float checker_2_rgb[3] = {
652 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker2/red"), 0.0f, 1.0f),
653 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker2/green"), 0.0f, 1.0f),
654 CLAMP(
dt_conf_get_float(
"plugins/darkroom/colorbalancergb/checker2/blue"), 0.0f, 1.0f)
657 for(
int c = 0; c < 3; c++)
659 d->preview.checker_color_1[c] = checker_1_rgb[c];
660 d->preview.checker_color_2[c] = checker_2_rgb[c];
662 d->preview.checker_color_1[3] = 0.0f;
663 d->preview.checker_color_2[3] = 0.0f;
665 const size_t checker_size
667 d->preview.checker_1 = checker_size;
668 d->preview.checker_2 = 2 * checker_size;
672 d->preview.width = 0;
674 d->preview.black_and_white
675 =
dt_conf_get_bool(
"plugins/darkroom/colorbalancergb/mask_preview/greyscaled");
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
dt_XYZ_to_Rec709_D50(XYZ, rgb)
static dt_aligned_pixel_t XYZ
static dt_aligned_pixel_t sRGB
static dt_aligned_pixel_t XYZ_D65
const dt_colormatrix_t dt_aligned_pixel_t out
static dt_aligned_pixel_t JzAzBz
int dt_conf_get_bool(const char *name)
float dt_conf_get_float(const char *name)
Float for name, clamped to its declared bounds.
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
gboolean dt_conf_is_equal(const char *name, const char *value)
dt_dev_pixelpipe_display_mask_t
@ DT_DEV_PIXELPIPE_DISPLAY_a
@ DT_DEV_PIXELPIPE_DISPLAY_OUTPUT
@ DT_DEV_PIXELPIPE_DISPLAY_G
@ DT_DEV_PIXELPIPE_DISPLAY_L
@ DT_DEV_PIXELPIPE_DISPLAY_CHANNEL
@ DT_DEV_PIXELPIPE_DISPLAY_ANY
@ DT_DEV_PIXELPIPE_DISPLAY_LCH_h
@ DT_DEV_PIXELPIPE_DISPLAY_JzCzhz_hz
@ DT_DEV_PIXELPIPE_DISPLAY_HSL_H
@ DT_DEV_PIXELPIPE_DISPLAY_HSL_S
@ DT_DEV_PIXELPIPE_DISPLAY_JzCzhz_Cz
@ DT_DEV_PIXELPIPE_DISPLAY_LCH_C
@ DT_DEV_PIXELPIPE_DISPLAY_b
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
@ DT_DEV_PIXELPIPE_DISPLAY_JzCzhz_Jz
@ DT_DEV_PIXELPIPE_DISPLAY_HSL_l
@ DT_DEV_PIXELPIPE_DISPLAY_GRAY
@ DT_DEV_PIXELPIPE_DISPLAY_B
@ DT_DEV_PIXELPIPE_DISPLAY_R
GtkWidget * preview
what the selected row actually captures
void init(dt_iop_module_t *module)
static __DT_CLONE_TARGETS__ void _channel_display_monochrome(const float *const restrict in, uint8_t *const restrict out, const size_t buffsize, const float alpha, const dt_iop_gamma_mask_preview_t *const preview)
int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o)
static int _false_color_channel_to_kernel_code(const dt_dev_pixelpipe_display_mask_t mask_display)
static __DT_CLONE_TARGETS__ void _channel_display_false_color(const float *const restrict in, uint8_t *const restrict out, const size_t buffsize, const float alpha, dt_dev_pixelpipe_display_mask_t channel, const dt_iop_gamma_mask_preview_t *const preview)
static void _write_pixel(const float *const restrict in, uint8_t *const restrict out, const dt_iop_gamma_mask_preview_t *const preview, const size_t pixel_index, const float alpha)
Blend one linear RGB pixel with its mask checker and encode it for display.
static __DT_CLONE_TARGETS__ void _copy_output(const float *const restrict in, uint8_t *const restrict out, const size_t buffsize)
dt_iop_gamma_kernel_mode_t
@ DT_IOP_GAMMA_KERNEL_MASK
@ DT_IOP_GAMMA_KERNEL_CHANNEL_FALSE_COLOR
@ DT_IOP_GAMMA_KERNEL_COPY
@ DT_IOP_GAMMA_KERNEL_CHANNEL_MONO
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
dt_iop_gamma_false_color_t
@ DT_IOP_GAMMA_FALSE_COLOR_MONO
@ DT_IOP_GAMMA_FALSE_COLOR_G
@ DT_IOP_GAMMA_FALSE_COLOR_C
@ DT_IOP_GAMMA_FALSE_COLOR_A
@ DT_IOP_GAMMA_FALSE_COLOR_R
@ DT_IOP_GAMMA_FALSE_COLOR_B_CH
@ DT_IOP_GAMMA_FALSE_COLOR_LCH_H
@ DT_IOP_GAMMA_FALSE_COLOR_JZ_HZ
@ DT_IOP_GAMMA_FALSE_COLOR_HSL_H
@ DT_IOP_GAMMA_FALSE_COLOR_B
void cleanup_global(dt_iop_module_so_t *module)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
void commit_params(dt_iop_module_t *self, dt_iop_params_t *params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void init_global(dt_iop_module_so_t *module)
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
static __DT_CLONE_TARGETS__ void _mask_display(const float *const restrict in, uint8_t *const restrict out, const size_t buffsize, const float alpha, const dt_iop_gamma_mask_preview_t *const preview)
gboolean runtime_data_hash(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
@ IOP_FLAGS_NO_HISTORY_STACK
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
static const dt_iop_drawlayer_params_t * params
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
int dt_opencl_create_kernel(const int prog, const char *name)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
#define __OMP_DECLARE_SIMD__(...)
#define __OMP_PARALLEL_FOR__(...)
#define __OMP_PARALLEL_FOR_SIMD__(...)
@ DT_DEV_PIXELPIPE_PREVIEW
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
#define for_each_channel(_var,...)
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
static const dt_aligned_pixel_simd_t value
dt_dev_pixelpipe_type_t type
dt_iop_buffer_type_t datatype
Everything the two process() paths need, settled once per commit_params().
dt_iop_gamma_mask_preview_t preview
Shared appearance of mask previews rendered by the display encoding module.
dt_aligned_pixel_t checker_color_2
dt_aligned_pixel_t checker_color_1
This module converts float32 RGBA pixels to uint8 BGRA pixels, for GUI pipelines only (darkroom main ...
dt_iop_global_data_t * data
dt_iop_global_data_t * global_data
Region of interest passed through the pixelpipe.
#define __DT_CLONE_TARGETS__