Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorchecker.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2020-2021 Aurélien PIERRE.
4 Copyright (C) 2021 Hubert Kowalski.
5 Copyright (C) 2021 Marco Carrarini.
6 Copyright (C) 2021 Ralf Brown.
7 Copyright (C) 2022 Martin Bařinka.
8 Copyright (C) 2023 Luca Zulberti.
9 Copyright (C) 2026 Guillaume Stutin.
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 "darktable.h"
26
31// types of targets we support
43
44// helper to deal with patch color
46{
47 char *name; // mnemonic name for the patch
48 dt_aligned_pixel_t Lab; // reference color in CIE Lab
49
50 // (x, y) position of the patch center, relatively to the guides (white dots)
51 // in ratio of the grid dimension along that axis
52 struct
53 {
54 float x;
55 float y;
56 };
58
59typedef struct dt_color_checker_t
60{
61 char *name;
62 char *author;
63 char *date;
66
67 float ratio; // format ratio of the chart, guide to guide (white dots)
68 float radius; // radius of a patch in ratio of the checker diagonal
69 size_t patches; // number of patches in target
70 size_t size[2]; // dimension along x, y axes
71 size_t middle_grey; // index of the closest patch to 20% neutral grey
72 size_t white; // index of the closest patch to pure white
73 size_t black; // index of the closest patch to pure black
74 dt_color_checker_patch *values; // pointer to an array of colors
75 gboolean finished; // whether the color checker is loaded or not
77
79 { "A1", { 37.986, 13.555, 14.059 }, { 0.087, 0.125}},
80 { "A2", { 65.711, 18.13, 17.81 }, { 0.250, 0.125}},
81 { "A3", { 49.927, -04.88, -21.905 }, { 0.417, 0.125}},
82 { "A4", { 43.139, -13.095, 21.905 }, { 0.584, 0.125}},
83 { "A5", { 55.112, 08.844, -25.399 }, { 0.751, 0.125}},
84 { "A6", { 70.719, -33.397, -0.199 }, { 0.918, 0.125}},
85 { "B1", { 62.661, 36.067, 57.096 }, { 0.087, 0.375}},
86 { "B2", { 40.02, 10.41, -45.964 }, { 0.250, 0.375}},
87 { "B3", { 51.124, 48.239, 16.248 }, { 0.417, 0.375}},
88 { "B4", { 30.325, 22.976, -21.587 }, { 0.584, 0.375}},
89 { "B5", { 72.532, -23.709, 57.255 }, { 0.751, 0.375}},
90 { "B6", { 71.941, 19.363, 67.857 }, { 0.918, 0.375}},
91 { "C1", { 28.778, 14.179, -50.297 }, { 0.087, 0.625}},
92 { "C2", { 55.261, -38.342, 31.37 }, { 0.250, 0.625}},
93 { "C3", { 42.101, 53.378, 28.19 }, { 0.417, 0.625}},
94 { "C4", { 81.733, 04.039, 79.819 }, { 0.584, 0.625}},
95 { "C5", { 51.935, 49.986, -14.574 }, { 0.751, 0.625}},
96 { "C6", { 51.038, -28.631, -28.638 }, { 0.918, 0.625}},
97 { "D1", { 96.539, -0.425, 1.186 }, { 0.087, 0.875}},
98 { "D2", { 81.257, -0.638, -0.335 }, { 0.250, 0.875}},
99 { "D3", { 66.766, -0.734, -0.504 }, { 0.417, 0.875}},
100 { "D4", { 50.867, -0.153, -0.27 }, { 0.584, 0.875}},
101 { "D5", { 35.656, -0.421, -1.231 }, { 0.751, 0.875}},
102 { "D6", { 20.461, -0.079, -0.973 }, { 0.918, 0.875}} };
103
104dt_color_checker_t xrite_24_2000 = { .name = "Xrite ColorChecker 24 before 2014",
105 .author = "X-Rite",
106 .date = "3/27/2000",
107 .manufacturer = "X-Rite/Gretag Macbeth",
109 .ratio = 2.f / 3.f,
110 .radius = 0.055f,
111 .patches = 24,
112 .size = { 4, 6 },
113 .middle_grey = 21,
114 .white = 18,
115 .black = 23,
116 .values = xrite_24_2000_patches };
117
119 { "A1", { 37.54, 14.37, 14.92 }, { 0.087, 0.125}},
120 { "A2", { 64.66, 19.27, 17.50 }, { 0.250, 0.125}},
121 { "A3", { 49.32, -03.82, -22.54 }, { 0.417, 0.125}},
122 { "A4", { 43.46, -12.74, 22.72 }, { 0.584, 0.125}},
123 { "A5", { 54.94, 09.61, -24.79 }, { 0.751, 0.125}},
124 { "A6", { 70.48, -32.26, -00.37 }, { 0.918, 0.125}},
125 { "A1", { 37.54, 14.37, 14.92 }, { 0.087, 0.125}},
126 { "A2", { 64.66, 19.27, 17.50 }, { 0.250, 0.125}},
127 { "A3", { 49.32, -03.82, -22.54 }, { 0.417, 0.125}},
128 { "A4", { 43.46, -12.74, 22.72 }, { 0.584, 0.125}},
129 { "A5", { 54.94, 09.61, -24.79 }, { 0.751, 0.125}},
130 { "A6", { 70.48, -32.26, -00.37 }, { 0.918, 0.125}},
131 { "B1", { 62.73, 35.83, 56.50 }, { 0.087, 0.375}},
132 { "B2", { 39.43, 10.75, -45.17 }, { 0.250, 0.375}},
133 { "B3", { 50.57, 48.64, 16.67 }, { 0.417, 0.375}},
134 { "B4", { 30.10, 22.54, -20.87 }, { 0.584, 0.375}},
135 { "B5", { 71.77, -24.13, 58.19 }, { 0.751, 0.375}},
136 { "B6", { 71.51, 18.24, 67.37 }, { 0.918, 0.375}},
137 { "C1", { 28.37, 15.42, -49.80 }, { 0.087, 0.625}},
138 { "C2", { 54.38, -39.72, 32.27 }, { 0.250, 0.625}},
139 { "C3", { 42.43, 51.05, 28.62 }, { 0.417, 0.625}},
140 { "C4", { 81.80, 02.67, 80.41 }, { 0.584, 0.625}},
141 { "C5", { 50.63, 51.28, -14.12 }, { 0.751, 0.625}},
142 { "C6", { 49.57, -29.71, -28.32 }, { 0.918, 0.625}},
143 { "D1", { 95.19, -01.03, 02.93 }, { 0.087, 0.875}},
144 { "D2", { 81.29, -00.57, 00.44 }, { 0.250, 0.875}},
145 { "D3", { 66.89, -00.75, -00.06 }, { 0.417, 0.875}},
146 { "D4", { 50.76, -00.13, 00.14 }, { 0.584, 0.875}},
147 { "D5", { 35.63, -00.46, -00.48 }, { 0.751, 0.875}},
148 { "D6", { 20.64, 00.07, -00.46 }, { 0.918, 0.875}} };
149
150dt_color_checker_t xrite_24_2014 = { .name = "Xrite ColorChecker 24 after 2014",
151 .author = "X-Rite",
152 .date = "3/28/2015",
153 .manufacturer = "X-Rite/Gretag Macbeth",
155 .ratio = 2.f / 3.f,
156 .radius = 0.055f,
157 .patches = 24,
158 .size = { 4, 6 },
159 .middle_grey = 21,
160 .white = 18,
161 .black = 23,
162 .values = xrite_24_2014_patches };
163
164
165// dimensions between reference dots : 197 mm width x 135 mm height
166// patch width : 26x26 mm
167// outer gutter : 8 mm
168// internal gutters (gap between patches) : 5 mm
169
171 { "A1", { 96.04, 2.16, 2.60 }, { 0.107, 0.844 } },
172 { "A2", { 80.44, 1.17, 2.05 }, { 0.264, 0.844 } },
173 { "A3", { 65.52, 0.69, 1.86 }, { 0.421, 0.844 } },
174 { "A4", { 49.62, 0.58, 1.56 }, { 0.579, 0.844 } },
175 { "A5", { 33.55, 0.35, 1.40 }, { 0.736, 0.844 } },
176 { "A6", { 16.91, 1.43, -0.81 }, { 0.893, 0.844 } },
177 { "B1", { 47.12, -32.50, -28.75 }, { 0.107, 0.615 } },
178 { "B2", { 50.49, 53.45, -13.55 }, { 0.264, 0.615 } },
179 { "B3", { 83.61, 3.36, 87.02 }, { 0.421, 0.615 } },
180 { "B4", { 41.05, 60.75, 31.17 }, { 0.579, 0.615 } },
181 { "B5", { 54.14, -40.80, 34.75 }, { 0.736, 0.615 } },
182 { "B6", { 24.75, 13.78, -49.48 }, { 0.893, 0.615 } },
183 { "C1", { 60.94, 38.21, 61.31 }, { 0.107, 0.385 } },
184 { "C2", { 37.80, 7.30, -43.04 }, { 0.264, 0.385 } },
185 { "C3", { 49.81, 48.50, 15.76 }, { 0.421, 0.385 } },
186 { "C4", { 28.88, 19.36, -24.48 }, { 0.579, 0.385 } },
187 { "C5", { 72.45, -23.60, 60.47 }, { 0.736, 0.385 } },
188 { "C6", { 71.65, 23.74, 72.28 }, { 0.893, 0.385 } },
189 { "D1", { 70.19, -31.90, 1.98 }, { 0.107, 0.155 } },
190 { "D2", { 54.38, 8.84, -25.71 }, { 0.264, 0.155 } },
191 { "D3", { 42.03, -15.80, 22.93 }, { 0.421, 0.155 } },
192 { "D4", { 48.82, -5.11, -23.08 }, { 0.579, 0.155 } },
193 { "D5", { 65.10, 18.14, 18.68 }, { 0.736, 0.155 } },
194 { "D6", { 36.13, 14.15, 15.78 }, { 0.893, 0.155 } } };
195
196dt_color_checker_t spyder_24 = { .name = "Datacolor SpyderCheckr 24 before 2018",
197 .author = "Aur\303\251lien PIERRE",
198 .date = "dec, 9 2016",
199 .manufacturer = "DataColor",
201 .ratio = 2.f / 3.f,
202 .radius = 0.035,
203 .patches = 24,
204 .size = { 4, 6 },
205 .middle_grey = 03,
206 .white = 00,
207 .black = 05,
208 .values = spyder_24_patches };
209
210
211// dimensions between reference dots : 197 mm width x 135 mm height
212// patch width : 26x26 mm
213// outer gutter : 8 mm
214// internal gutters (gap between patches) : 5 mm
215
216dt_color_checker_patch spyder_24_v2_patch[] = {{ "A1", { 96.04, 2.16, 2.60 }, { 0.107, 0.844 } },
217 { "A2", { 80.44, 1.17, 2.05 }, { 0.264, 0.844 } },
218 { "A3", { 65.52, 0.69, 1.86 }, { 0.421, 0.844 } },
219 { "A4", { 49.62, 0.58, 1.56 }, { 0.579, 0.844 } },
220 { "A5", { 33.55, 0.35, 1.40 }, { 0.736, 0.844 } },
221 { "A6", { 16.91, 1.43, -0.81 }, { 0.893, 0.844 } },
222 { "B1", { 47.12, -32.50, -28.75 }, { 0.107, 0.615 } },
223 { "B2", { 50.49, 53.45, -13.55 }, { 0.264, 0.615 } },
224 { "B3", { 83.61, 3.36, 87.02 }, { 0.421, 0.615 } },
225 { "B4", { 41.05, 60.75, 31.17 }, { 0.579, 0.615 } },
226 { "B5", { 54.14, -40.80, 34.75 }, { 0.736, 0.615 } },
227 { "B6", { 24.75, 13.78, -49.48 }, { 0.893, 0.615 } },
228 { "C1", { 60.94, 38.21, 61.31 }, { 0.107, 0.385 } },
229 { "C2", { 37.80, 7.30, -43.04 }, { 0.264, 0.385 } },
230 { "C3", { 49.81, 48.50, 15.76 }, { 0.421, 0.385 } },
231 { "C4", { 28.88, 19.36, -24.48 }, { 0.579, 0.385 } },
232 { "C5", { 72.45, -23.57, 60.47 }, { 0.736, 0.385 } },
233 { "C6", { 71.65, 23.74, 72.28 }, { 0.893, 0.385 } },
234 { "D1", { 70.19, -31.85, 1.98 }, { 0.107, 0.155 } },
235 { "D2", { 54.38, 8.84, -25.71 }, { 0.264, 0.155 } },
236 { "D3", { 42.03, -15.78, 22.93 }, { 0.421, 0.155 } },
237 { "D4", { 48.82, -5.11, -23.08 }, { 0.579, 0.155 } },
238 { "D5", { 65.10, 18.14, 18.68 }, { 0.736, 0.155 } },
239 { "D6", { 36.13, 14.15, 15.78 }, { 0.893, 0.155 } } };
240
241dt_color_checker_t spyder_24_v2 = { .name = "Datacolor SpyderCheckr 24 after 2018",
242 .author = "Aur\303\251lien PIERRE",
243 .date = "dec, 9 2016",
244 .manufacturer = "DataColor",
246 .ratio = 2.f / 3.f,
247 .radius = 0.035,
248 .patches = 24,
249 .size = { 4, 6 },
250 .middle_grey = 03,
251 .white = 00,
252 .black = 05,
253 .values = spyder_24_v2_patch };
254
255
256// dimensions between reference dots : 297 mm width x 197 mm height
257// patch width : 26x26 mm
258// outer gutter : 8 mm
259// internal gutters (gap between patches) : 5 mm
260
261dt_color_checker_patch spyder_48_patches[] = { { "A1", { 61.35, 34.81, 18.38 }, { 0.071, 0.107 } },
262 { "A2", { 75.50 , 5.84, 50.42 }, { 0.071, 0.264 } },
263 { "A3", { 66.82, -25.1, 23.47 }, { 0.071, 0.421 } },
264 { "A4", { 60.53, -22.6, -20.40 }, { 0.071, 0.579 } },
265 { "A5", { 59.66, -2.03, -28.46 }, { 0.071, 0.736 } },
266 { "A6", { 59.15, 30.83, -5.72 }, { 0.071, 0.893 } },
267 { "B1", { 82.68, 5.03, 3.02 }, { 0.175, 0.107 } },
268 { "B2", { 82.25, -2.42, 3.78 }, { 0.175, 0.264 } },
269 { "B3", { 82.29, 2.20, -2.04 }, { 0.175, 0.421 } },
270 { "B4", { 24.89, 4.43, 0.78 }, { 0.175, 0.579 } },
271 { "B5", { 25.16, -3.88, 2.13 }, { 0.175, 0.736 } },
272 { "B6", { 26.13, 2.61, -5.03 }, { 0.175, 0.893 } },
273 { "C1", { 85.42, 9.41, 14.49 }, { 0.279, 0.107 } },
274 { "C2", { 74.28, 9.05, 27.21 }, { 0.279, 0.264 } },
275 { "C3", { 64.57, 12.39, 37.24 }, { 0.279, 0.421 } },
276 { "C4", { 44.49, 17.23, 26.24 }, { 0.279, 0.579 } },
277 { "C5", { 25.29, 7.95, 8.87 }, { 0.279, 0.736 } },
278 { "C6", { 22.67, 2.11, -1.10 }, { 0.279, 0.893 } },
279 { "D1", { 92.72, 1.89, 2.76 }, { 0.384, 0.107 } },
280 { "D2", { 88.85, 1.59, 2.27 }, { 0.384, 0.264 } },
281 { "D3", { 73.42, 0.99, 1.89 }, { 0.384, 0.421 } },
282 { "D4", { 57.15, 0.57, 1.19 }, { 0.384, 0.579 } },
283 { "D5", { 41.57, 0.24, 1.45 }, { 0.384, 0.736 } },
284 { "D6", { 25.65, 1.24, 0.05 }, { 0.384, 0.893 } },
285 { "E1", { 96.04, 2.16, 2.60 }, { 0.616, 0.107 } },
286 { "E2", { 80.44, 1.17, 2.05 }, { 0.616, 0.264 } },
287 { "E3", { 65.52, 0.69, 1.86 }, { 0.616, 0.421 } },
288 { "E4", { 49.62, 0.58, 1.56 }, { 0.616, 0.579 } },
289 { "E5", { 33.55, 0.35, 1.40 }, { 0.616, 0.736 } },
290 { "E6", { 16.91, 1.43, -0.81 }, { 0.616, 0.893 } },
291 { "F1", { 47.12, -32.50, -28.75 }, { 0.721, 0.107 } },
292 { "F2", { 50.49, 53.45, -13.55 }, { 0.721, 0.264 } },
293 { "F3", { 83.61, 3.36, 87.02 }, { 0.721, 0.421 } },
294 { "F4", { 41.05, 60.75, 31.17 }, { 0.721, 0.579 } },
295 { "F5", { 54.14, -40.80, 34.75 }, { 0.721, 0.736 } },
296 { "F6", { 24.75, 13.78, -49.48 }, { 0.721, 0.893 } },
297 { "G1", { 60.94, 38.21, 61.31 }, { 0.825, 0.107 } },
298 { "G2", { 37.80, 7.30, -43.04 }, { 0.825, 0.264 } },
299 { "G3", { 49.81, 48.50, 15.76 }, { 0.825, 0.421 } },
300 { "G4", { 28.88, 19.36, -24.48 }, { 0.825, 0.579 } },
301 { "G5", { 72.45, -23.60, 60.47 }, { 0.825, 0.736 } },
302 { "G6", { 71.65, 23.74, 72.28 }, { 0.825, 0.893 } },
303 { "H1", { 70.19, -31.90, 1.98 }, { 0.929, 0.107 } },
304 { "H2", { 54.38, 8.84, -25.71 }, { 0.929, 0.264 } },
305 { "H3", { 42.03, -15.80, 22.93 }, { 0.929, 0.421 } },
306 { "H4", { 48.82, -5.11, -23.08 }, { 0.929, 0.579 } },
307 { "H5", { 65.10, 18.14, 18.68 }, { 0.929, 0.736 } },
308 { "H6", { 36.13, 14.15, 15.78 }, { 0.929, 0.893 } } };
309
310dt_color_checker_t spyder_48 = { .name = "Datacolor SpyderCheckr 48 before 2018",
311 .author = "Aur\303\251lien PIERRE",
312 .date = "dec, 9 2016",
313 .manufacturer = "DataColor",
315 .ratio = 2.f / 3.f,
316 .radius = 0.035,
317 .patches = 48,
318 .size = { 8, 6 },
319 .middle_grey = 24,
320 .white = 21,
321 .black = 29,
322 .values = spyder_48_patches };
323
324
325// dimensions between reference dots : 297 mm width x 197 mm height
326// patch width : 26x26 mm
327// outer gutter : 8 mm
328// internal gutters (gap between patches) : 5 mm
329
330dt_color_checker_patch spyder_48_v2_patch[] = { { "A1", { 61.35, 34.81, 18.38 }, { 0.071, 0.107 } },
331 { "A2", { 75.50 , 5.84, 50.42 }, { 0.071, 0.264 } },
332 { "A3", { 66.82, -25.1, 23.47 }, { 0.071, 0.421 } },
333 { "A4", { 60.53, -22.62, -20.40 }, { 0.071, 0.579 } },
334 { "A5", { 59.66, -2.03, -28.46 }, { 0.071, 0.736 } },
335 { "A6", { 59.15, 30.83, -5.72 }, { 0.071, 0.893 } },
336 { "B1", { 82.68, 5.03, 3.02 }, { 0.175, 0.107 } },
337 { "B2", { 82.25, -2.42, 3.78 }, { 0.175, 0.264 } },
338 { "B3", { 82.29, 2.20, -2.04 }, { 0.175, 0.421 } },
339 { "B4", { 24.89, 4.43, 0.78 }, { 0.175, 0.579 } },
340 { "B5", { 25.16, -3.88, 2.13 }, { 0.175, 0.736 } },
341 { "B6", { 26.13, 2.61, -5.03 }, { 0.175, 0.893 } },
342 { "C1", { 85.42, 9.41, 14.49 }, { 0.279, 0.107 } },
343 { "C2", { 74.28, 9.05, 27.21 }, { 0.279, 0.264 } },
344 { "C3", { 64.57, 12.39, 37.24 }, { 0.279, 0.421 } },
345 { "C4", { 44.49, 17.23, 26.24 }, { 0.279, 0.579 } },
346 { "C5", { 25.29, 7.95, 8.87 }, { 0.279, 0.736 } },
347 { "C6", { 22.67, 2.11, -1.10 }, { 0.279, 0.893 } },
348 { "D1", { 92.72, 1.89, 2.76 }, { 0.384, 0.107 } },
349 { "D2", { 88.85, 1.59, 2.27 }, { 0.384, 0.264 } },
350 { "D3", { 73.42, 0.99, 1.89 }, { 0.384, 0.421 } },
351 { "D4", { 57.15, 0.57, 1.19 }, { 0.384, 0.579 } },
352 { "D5", { 41.57, 0.24, 1.45 }, { 0.384, 0.736 } },
353 { "D6", { 25.65, 1.24, 0.05 }, { 0.384, 0.893 } },
354 { "E1", { 96.04, 2.16, 2.60 }, { 0.616, 0.107 } },
355 { "E2", { 80.44, 1.17, 2.05 }, { 0.616, 0.264 } },
356 { "E3", { 65.52, 0.69, 1.86 }, { 0.616, 0.421 } },
357 { "E4", { 49.62, 0.58, 1.56 }, { 0.616, 0.579 } },
358 { "E5", { 33.55, 0.35, 1.40 }, { 0.616, 0.736 } },
359 { "E6", { 16.91, 1.43, -0.81 }, { 0.616, 0.893 } },
360 { "F1", { 47.12, -32.50, -28.75 }, { 0.721, 0.107 } },
361 { "F2", { 50.49, 53.45, -13.55 }, { 0.721, 0.264 } },
362 { "F3", { 83.61, 3.36, 87.02 }, { 0.721, 0.421 } },
363 { "F4", { 41.05, 60.75, 31.17 }, { 0.721, 0.579 } },
364 { "F5", { 54.14, -40.80, 34.75 }, { 0.721, 0.736 } },
365 { "F6", { 24.75, 13.78, -49.48 }, { 0.721, 0.893 } },
366 { "G1", { 60.94, 38.21, 61.31 }, { 0.825, 0.107 } },
367 { "G2", { 37.80, 7.30, -43.04 }, { 0.825, 0.264 } },
368 { "G3", { 49.81, 48.50, 15.76 }, { 0.825, 0.421 } },
369 { "G4", { 28.88, 19.36, -24.48 }, { 0.825, 0.579 } },
370 { "G5", { 72.45, -23.57, 60.47 }, { 0.825, 0.736 } },
371 { "G6", { 71.65, 23.74, 72.28 }, { 0.825, 0.893 } },
372 { "H1", { 70.19, -31.85, 1.98 }, { 0.929, 0.107 } },
373 { "H2", { 54.38, 8.84, -25.71 }, { 0.929, 0.264 } },
374 { "H3", { 42.03, -15.78, 22.93 }, { 0.929, 0.421 } },
375 { "H4", { 48.82, -5.11, -23.08 }, { 0.929, 0.579 } },
376 { "H5", { 65.10, 18.14, 18.68 }, { 0.929, 0.736 } },
377 { "H6", { 36.13, 14.15, 15.78 }, { 0.929, 0.893 } } };
378
379dt_color_checker_t spyder_48_v2 = { .name = "Datacolor SpyderCheckr 48 after 2018",
380 .author = "Aur\303\251lien PIERRE",
381 .date = "dec, 9 2016",
382 .manufacturer = "DataColor",
384 .ratio = 2.f / 3.f,
385 .radius = 0.035,
386 .patches = 48,
387 .size = { 8, 6 },
388 .middle_grey = 24,
389 .white = 21,
390 .black = 29,
391 .values = spyder_48_v2_patch };
392
400
401// Add other supported type of CGATS here
410
412 "IT8.7/1", // transparent
413 "IT8.7/2", // opaque
414 "CTI3" // opaque
415};
416
423
425 "Transparent",
426 "Opaque"
427};
428
435
436// This defines charts specifications
438{
439 const gchar *type;
440 float radius; // radius of a patch in ratio of the checker diagonal
441 float ratio; // format ratio of the chart, guide to guide (white dots)
442 size_t size[2]; // number of patch along x, y axes
443 float guide_size[2];// size of the guide area, specified by "MARK" data in cht files
445 size_t white;
446 size_t black;
447
448 int num_patches; // total number of patches
450 int rows;
455
456 GSList *patches; // list of patches struct, data are dt_color_checker_patch
457
459
460dt_colorchecker_label_t *dt_colorchecker_label_init(const char *label, const dt_color_checker_targets type, const char *path, const int patch_nb)
461{
462 dt_colorchecker_label_t *checker_label = malloc(sizeof(dt_colorchecker_label_t));
463 if(!checker_label) return NULL;
464
465 checker_label->name = label ? g_strdup(label) : NULL;
466 checker_label->type = type;
467 checker_label->path = path ? g_strdup(path) : NULL;
468 checker_label->patch_nb = patch_nb;
469
470 return checker_label;
471}
472
474{
476 if(!patches) return NULL;
477
478 // Initialize the patches
479 for(size_t i = 0; i < num_patches; i++)
480 {
481 patches[i].name = NULL;
482 patches[i].x = 0.0f;
483 patches[i].y = 0.0f;
484 patches[i].Lab[0] = 0.0f;
485 patches[i].Lab[1] = 0.0f;
486 patches[i].Lab[2] = 0.0f;
487 }
488 return patches;
489}
490
492{
493 if(!patch) return;
494 if(!patch->name) return;
495
496 dt_free(patch->name);
497}
498
499// This one is to fully free GSList of dt_color_checker_patch
501{
503 if(!patch) return;
504
505 // Free the name if it was allocated
506 dt_free(patch->name);
507
508 dt_free(patch);
509}
510
512{
513 dt_color_checker_t *checker = (dt_color_checker_t*)malloc(sizeof(dt_color_checker_t));
514 if(!checker) return NULL;
515
516 checker->name = NULL;
517 checker->author = NULL;
518 checker->date = NULL;
519 checker->manufacturer = NULL;
520 checker->values = NULL;
521 checker->finished = FALSE;
522
523 return checker;
524}
525
527{
528 if (!checker) return;
529
530 dt_free(checker->name);
531 dt_free(checker->author);
532 dt_free(checker->date);
533 dt_free(checker->manufacturer);
534
535 if(checker->patches > 0 && checker->values)
536 {
537 for(size_t i = 0; i < checker->patches; i++)
538 {
540 }
541
542 dt_free_align(checker->values);
543 }
544 free(checker);
545 checker = NULL;
546}
547
548void dt_colorchecker_label_free(gpointer data)
549{
550 dt_colorchecker_label_t *checker_label = (dt_colorchecker_label_t *)data;
551 if(!checker_label) return;
552
553 dt_free(checker_label->name);
554 dt_free(checker_label->path);
555 dt_free(checker_label);
556}
557
558void dt_colorchecker_label_list_cleanup(GList **colorcheckers)
559{
560 if(!colorcheckers) return;
561
562 g_list_free_full(g_steal_pointer(colorcheckers), dt_colorchecker_label_free);
563 *colorcheckers = NULL;
564}
565
573dt_color_checker_t *dt_colorchecker_user_ref_create(const char *color_filename, const char *cht_filename);
574
581int dt_colorchecker_find_cht_files(GList **chts);
582
589int dt_colorchecker_find_CGATS_reference_files(GList **ref_colorcheckers_files);
590
597int dt_colorchecker_find_builtin(GList **colorcheckers_label);
598
606
607
608static dt_color_checker_t *dt_get_color_checker(const dt_color_checker_targets target_type, GList **colorchecker_label, const char *color_filename)
609{
610 // initialize the destination checker
611 dt_color_checker_t *checker_dest = NULL;
612 checker_dest = dt_colorchecker_init();
613 if(!checker_dest) return NULL;
614
615 // check if the target type is a user reference and get the label data if available
617 const char *cht_filename = NULL;
618 if(target_type >= COLOR_CHECKER_USER_REF && colorchecker_label)
619 {
620 dt_print(DT_DEBUG_VERBOSE, _("dt_get_color_checker: colorchecker type %i is a user reference.\n"), target_type);
621
622 // Get the label data from the list
623 const dt_colorchecker_label_t *label_data = (const dt_colorchecker_label_t*)g_list_nth_data(*colorchecker_label, target_type);
624 checker_type = COLOR_CHECKER_USER_REF;
625 cht_filename = label_data->path;
626 }
627 else // it's a builtin colorchecker
628 checker_type = target_type;
629
630 // Copy the color checker data from the predefined checkers or from reference file
631 switch(checker_type)
632 {
634 dt_colorchecker_copy(checker_dest, &xrite_24_2000);
635 break;
637 dt_colorchecker_copy(checker_dest, &xrite_24_2014);
638 break;
640 dt_colorchecker_copy(checker_dest, &spyder_24);
641 break;
643 dt_colorchecker_copy(checker_dest, &spyder_24_v2);
644 break;
646 dt_colorchecker_copy(checker_dest, &spyder_48);
647 break;
649 dt_colorchecker_copy(checker_dest, &spyder_48_v2);
650 break;
652 if(color_filename)
653 {
654 dt_color_checker_t *p = dt_colorchecker_user_ref_create(color_filename, cht_filename);
655 if(p)
656 {
657 dt_colorchecker_copy(checker_dest, p);
659 }
660 }
661 else fprintf(stderr, "dt_get_color_checker: colorchecker %i is a user reference but no color filename was provided!\n", target_type);
662 break;
663
665 fprintf(stderr, "dt_get_color_checker: colorchecker type %i not found!\n", target_type);
666 dt_colorchecker_copy(checker_dest, &xrite_24_2014);
667 }
668
669 return checker_dest;
670}
671
676// get a patch index in the list of values from the coordinates of the patch in the checker array
677static inline size_t dt_color_checker_get_index(const dt_color_checker_t *const target_checker, const size_t coordinates[2])
678{
679 // patches are stored column-major
680 const size_t height = target_checker->size[1];
681 return CLAMP(height * coordinates[0] + coordinates[1], 0, target_checker->patches - 1);
682}
683
684// get a a patch coordinates of in the checker array from the patch index in the list of values
685static inline void dt_color_checker_get_coordinates(const dt_color_checker_t *const target_checker, size_t *coordinates, const size_t index)
686{
687 // patches are stored column-major
688 const size_t idx = CLAMP(index, 0, target_checker->patches - 1);
689 const size_t height = target_checker->size[1];
690 const size_t num_col = idx / height;
691 const size_t num_lin = idx - num_col * height;
692 coordinates[0] = CLAMP(num_col, 0, target_checker->size[0] - 1);
693 coordinates[1] = CLAMP(num_lin, 0, target_checker->size[1] - 1);
694}
695
696// find a patch matching a name
697static inline const dt_color_checker_patch *dt_color_checker_get_patch_by_name(const dt_color_checker_t *const target_checker, const char *name, size_t *index)
698{
699 size_t idx = -1;
700 const dt_color_checker_patch *patch = NULL;
701
702 for(size_t k = 0; k < target_checker->patches; k++)
703 if(strcmp(name, target_checker->values[k].name) == 0)
704 {
705 idx = k;
706 patch = &target_checker->values[k];
707 break;
708 }
709
710 if(IS_NULL_PTR(patch)) fprintf(stderr, "No patch matching name `%s` was found in %s\n", name, target_checker->name);
711
712 if(index) *index = idx;
713 return patch;
714}
715
722int dt_colorchecker_find(GList **colorcheckers_label)
723{
724 int total = dt_colorchecker_find_builtin(colorcheckers_label);
725 dt_print(DT_DEBUG_VERBOSE, _("dt_colorchecker_find: found %d builtin colorcheckers\n"), total);
726 int b_nb = total;
727
728 total += dt_colorchecker_find_cht_files(colorcheckers_label);
729 if (total) dt_print(DT_DEBUG_VERBOSE, _("dt_colorchecker_find: found %d CGAT references files\n"), total - b_nb);
730 return total;
731}
732
739int dt_colorchecker_find_color(GList **color_label)
740{
741 if(!color_label) return 0;
742
743 // Clear cht file list
745
746 // Refill the list
747 const int total = dt_colorchecker_find_CGATS_reference_files(color_label);
748 if(total) dt_print(DT_DEBUG_VERBOSE, _("dt_colorchecker_find_color: found %d .cht files\n"), total);
749
750 if(*color_label == NULL)
751 fprintf(stderr, "[channelmixerrgb] no CGATS file found\n");
752
753 return *color_label ? total : 0;
754}
755
756// clang-format off
757// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
758// vim: shiftwidth=2 expandtab tabstop=2 cindent
759// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
760// clang-format on
#define FALSE
Definition ashift_lsd.c:158
int height
Definition bilateral.h:1
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
int dt_colorchecker_find_CGATS_reference_files(GList **ref_colorcheckers_files)
Find all CGAT files in the user config/color/it8 directory.
dt_color_checker_patch spyder_48_v2_patch[]
dt_color_checker_targets
@ COLOR_CHECKER_SPYDER_48
@ COLOR_CHECKER_XRITE_24_2000
@ COLOR_CHECKER_XRITE_24_2014
@ COLOR_CHECKER_LAST
@ COLOR_CHECKER_SPYDER_24_V2
@ COLOR_CHECKER_SPYDER_24
@ COLOR_CHECKER_USER_REF
@ COLOR_CHECKER_SPYDER_48_V2
dt_color_checker_patch spyder_24_patches[]
dt_color_checker_patch xrite_24_2014_patches[]
dt_colorchecker_material_types
@ COLOR_CHECKER_MATERIAL_TRANSPARENT
@ COLOR_CHECKER_MATERIAL_UNKNOWN
@ COLOR_CHECKER_MATERIAL_OPAQUE
dt_color_checker_t * dt_colorchecker_init()
int dt_colorchecker_find_cht_files(GList **chts)
Find all .cht files in the user config/color/it8 directory.
static size_t dt_color_checker_get_index(const dt_color_checker_t *const target_checker, const size_t coordinates[2])
dt_colorchecker_CGATS_types
@ CGATS_TYPE_IT8_7_1
@ CGATS_TYPE_UNKOWN
@ CGATS_TYPE_IT8_7_2
@ CGATS_TYPE_CTI3
dt_color_checker_t spyder_24
static const dt_color_checker_patch * dt_color_checker_get_patch_by_name(const dt_color_checker_t *const target_checker, const char *name, size_t *index)
void dt_colorchecker_patch_cleanup_list(void *_patch)
dt_color_checker_t spyder_48
void dt_colorchecker_patch_cleanup(dt_color_checker_patch *patch)
void dt_colorchecker_copy(dt_color_checker_t *dest, const dt_color_checker_t *src)
Copy the content of a color checker from source to destination.
const char * colorchecker_material_types[COLOR_CHECKER_MATERIAL_UNKNOWN]
dt_color_checker_t * dt_colorchecker_user_ref_create(const char *color_filename, const char *cht_filename)
Creates a color checker from a reference file (CGATS format).
void dt_colorchecker_label_free(gpointer data)
dt_color_checker_patch spyder_48_patches[]
dt_color_checker_t spyder_48_v2
dt_colorchecker_label_t * dt_colorchecker_label_init(const char *label, const dt_color_checker_targets type, const char *path, const int patch_nb)
void dt_colorchecker_label_list_cleanup(GList **colorcheckers)
dt_color_checker_t spyder_24_v2
static void dt_color_checker_get_coordinates(const dt_color_checker_t *const target_checker, size_t *coordinates, const size_t index)
dt_color_checker_t xrite_24_2014
dt_color_checker_patch spyder_24_v2_patch[]
dt_color_checker_patch * dt_colorchecker_patch_array_init(const size_t num_patches)
int dt_colorchecker_find_builtin(GList **colorcheckers_label)
Find all builtin colorcheckers.
static dt_color_checker_t * dt_get_color_checker(const dt_color_checker_targets target_type, GList **colorchecker_label, const char *color_filename)
dt_color_checker_t xrite_24_2000
dt_color_checker_patch xrite_24_2000_patches[]
int dt_colorchecker_find(GList **colorcheckers_label)
Find all builtin and .cht colorcheckers.
void dt_colorchecker_cleanup(dt_color_checker_t *checker)
int dt_colorchecker_find_color(GList **color_label)
Find all builtin and CGATS colorcheckers.
const char * CGATS_types[CGATS_TYPE_UNKOWN]
int type
char * name
void * dt_alloc_align(size_t size)
Definition darktable.c:446
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
#define dt_free_align(ptr)
Definition darktable.h:481
@ DT_DEBUG_VERBOSE
Definition darktable.h:743
#define dt_free(ptr)
Definition darktable.h:456
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
float *const restrict const size_t k
float dt_aligned_pixel_t[4]
dt_aligned_pixel_t Lab
dt_color_checker_targets type
dt_color_checker_patch * values
dt_color_checker_targets type