Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
core.h
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU 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 Ansel 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef DT_IOP_HIGHLIGHTS_CORE_H
20#define DT_IOP_HIGHLIGHTS_CORE_H
21
22// Self-dome fallback and all-clip joint core stages (CPU + OpenCL).
23// Public API of this highlights harmonic-transposition module (a compiled TU). Include
24// this header to call into the module; internals are static in the .c. See common.h.
25
27#include <stdint.h>
28
29void _selfdome(_hl_region_ctx_t *const ctx);
30
31void _joint_core(_hl_region_ctx_t *const ctx);
32
33// Chromaticity-gradient continuation (article addendum): extend the BRIGHT valid surround's
34// chromaticity shares s_c = u_c / sum_j u_j into the blown zone BIHARMONICALLY (value + gradient
35// continuation, the same operator the luminance dome uses), then reproject every multi-clip pixel's
36// clipped subset onto the extended field and re-assert the joint saturation floor. Rationale
37// (measured on a blown sunrise laced with branches): every value-continuing estimator (colour-line
38// fits, harmonic ratio fills) inherits the chromaticity of the LAST unclipped band before the
39// blow-out, which is unrepresentative (whitened fence band, occluder penumbras) -- the interior then
40// carries blotchy fence chromaticity. A C1 continuation of the bright surround's chromaticity
41// GRADIENT restores the scene's chromatic trend (e.g. warming toward a sunrise sun) and is smooth
42// across occluders by construction. 1-clip pixels (measured chromaticity-correct through the
43// 2-guide fits) are left untouched WHERE THE FIT SPOKE; where the fit landed at/below the pixel's
44// own saturation floor (floor-authored: est <= 1.03 x clip0 -- measured 92.5% of the 1-clip zone
45// on a real flare-veiled sunrise) they are reprojected like partial multi-clip pixels, gated by
46// the clip-asymmetry floor gate (WB'd clips only; unit-WB bench behavior is bit-exact) and
47// excluded from the content gate's trusted ring.
49
50#if defined(HAVE_OPENCL) && DT_HL_SPARSE_SOLVE
51// The hue-coupled self-dome stage on the GPU: soft clip floor (rounded lower bound at the
52// clip level), ONE shared biharmonic brightness dome over the union hole, harmonically
53// filled chromaticity ratios (each channel divided by the brightness sum), a depth-gated
54// blend (dome takes over where the colour-line fit quality is low AND the pixel is shallow),
55// then a hard clip-floor re-assert. est/vld/bsc/clip0/dep are device buffers (working pixels,
56// validity mask, fit quality, clip thresholds, distance-to-valid depth).
57// Mirrors the DT_HL_SELF_DOME block of _region_guided_filter (CPU): any change here must be
58// mirrored there and re-validated with the HL_DOMECL_TEST self-test
59// (_selfdome_stage_cl_selftest).
60//
61// MATHS BRIDGE -- article "The algorithm" steps 5-6. Step 5: soft saturation floor (rounded lower
62// bound at c0). Step 6: hue-coupled self-dome -- ONE shared biharmonic brightness dome (Delta^2 L_sum
63// = 0, hl_soft_floor->hl_lsb_hole->_biharmonic_dome_cl) times harmonically-filled chromaticity ratios
64// r_c = est_c/L_sum, blended in by the depth-gated keep weight
65// keep = 1 - dome_fraction, dome_fraction = (1 - S_{0.4}^{0.85}(R^2)) * exp(-(delta/1.5 sigma)^2)
66// (hl_dome_blend), then a hard clip-floor re-assert. The hue coupling (dome_c = L_dome * r_c) is what
67// stops three per-channel domes drifting the hue -- the failure that kept the per-channel ancestor off.
68cl_int _selfdome_stage_cl(const int devid, void *gd_void, cl_mem estimate, cl_mem valid, cl_mem model_quality,
69 cl_mem clip0, cl_mem depth, cl_mem region_worth, const int region_w, const int region_h, const float cf_sigma,
70 const float reg_radius, const int ds_shared, const float floor_gate,
71 const dt_dev_pixelpipe_t *pipe);
72
73// All-clipped joint core on the device (pixels where NO channel survived, so no guide
74// exists): shared biharmonic brightness dome (floored at the saturated sum) x
75// screened-Poisson diffused chromaticity (diffusion plus a pull toward the mean valid
76// colour, strength set by the "inpaint a flat colour" user slider) -- ONE host symbolic
77// analysis + GPU numeric factorization serves the three channels, whose right-hand sides are
78// assembled on the device (hl_pde_rhs) so no full-res float plane crosses the bus --
79// composed through the gaussian-feathered core mask. The only downloads are the full-res
80// hole MASK (bytes; the sparse symbolic analysis needs it anyway) and the per-workgroup
81// mean-chromaticity partial sums.
82// Mirrors the all-clip joint-core block of _region_guided_filter (CPU, DT_HL_COEFF_FIELD):
83// any change here must be mirrored there and re-validated with the HL_CORECL_TEST self-test
84// (_joint_core_stage_cl_selftest).
85//
86// MATHS BRIDGE -- Step 7 all-clip core (article §"Filling holes with no survivor"): magnitude =
87// shared biharmonic dome L_dome (Delta^2 L_sum = 0, floored at sum_c clip0_c), chrominance =
88// screened-Poisson rim fill r_c ((lambda_solid*I - Delta) r = lambda_solid*r_target) with
89// r_target = mean valid chromaticity, solved per channel by ONE shared Cholesky factor (direct) or
90// the on-device CG (large cores). Recombine core_c = L_dome * (r_c / sum_j r_j), composed through a
91// gaussian-feathered core mask (no hard hand-off at the core rim).
92cl_int _joint_core_stage_cl(const int devid, void *gd_void, cl_mem estimate, cl_mem valid, cl_mem clip0,
93 const int region_w, const int region_h, const float solid_color,
94 const float reg_radius, const int extent, const float floor_gate,
95 const dt_dev_pixelpipe_t *pipe);
96
97// Gradient-extending chroma on the device (see _chromaticity_gradient above for the method).
98// Mirrors the CPU stage: any change here must be mirrored there and re-validated with the
99// HL_CGRADCL_TEST self-test (_chromaticity_gradient_stage_cl_selftest).
100cl_int _chromaticity_gradient_stage_cl(const int devid, void *gd_void, cl_mem estimate, cl_mem valid,
101 cl_mem clip0, cl_mem clip_depth, const int region_w, const int region_h,
102 const float reg_radius, const float floor_gate,
103 const float module_scale, const dt_dev_pixelpipe_t *pipe);
104
105#endif
106#endif // DT_IOP_HIGHLIGHTS_CORE_H
void _joint_core(_hl_region_ctx_t *const ctx)
Definition core.c:267
void _selfdome(_hl_region_ctx_t *const ctx)
Definition core.c:36
void _chromaticity_gradient(_hl_region_ctx_t *const ctx)
Definition core.c:509