1 /*
2     This file is part of darktable,
3     Copyright (C) 2010-2021 darktable developers.
4 
5     darktable 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     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 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 #pragma once
20 
21 #include "common/darktable.h"
22 
23 #include <lcms2.h>
24 
25 // this was removed from lcms2 in 2.4
26 #ifndef TYPE_XYZA_FLT
27   #define TYPE_XYZA_FLT         (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
28 #endif
29 
30 // constants fit to the ones from lcms.h:
31 typedef enum dt_iop_color_intent_t
32 {
33   DT_INTENT_PERCEPTUAL = INTENT_PERCEPTUAL,                       // 0
34   DT_INTENT_RELATIVE_COLORIMETRIC = INTENT_RELATIVE_COLORIMETRIC, // 1
35   DT_INTENT_SATURATION = INTENT_SATURATION,                       // 2
36   DT_INTENT_ABSOLUTE_COLORIMETRIC = INTENT_ABSOLUTE_COLORIMETRIC, // 3
37   DT_INTENT_LAST
38 } dt_iop_color_intent_t;
39 
40 typedef enum dt_colorspaces_profile_type_t
41 {
42   DT_COLORSPACES_PROFILE_TYPE_INPUT = 1,
43   DT_COLORSPACES_PROFILE_TYPE_WORK = 2,
44   DT_COLORSPACES_PROFILE_TYPE_EXPORT = 3,
45   DT_COLORSPACES_PROFILE_TYPE_DISPLAY = 4,
46   DT_COLORSPACES_PROFILE_TYPE_SOFTPROOF = 5,
47   DT_COLORSPACES_PROFILE_TYPE_HISTOGRAM = 6,
48   DT_COLORSPACES_PROFILE_TYPE_DISPLAY2 = 7
49 } dt_colorspaces_profile_type_t;
50 
51 typedef enum dt_colorspaces_color_profile_type_t
52 {
53   DT_COLORSPACE_NONE = -1,
54   DT_COLORSPACE_FILE = 0,
55   DT_COLORSPACE_SRGB = 1,
56   DT_COLORSPACE_ADOBERGB = 2,
57   DT_COLORSPACE_LIN_REC709 = 3,
58   DT_COLORSPACE_LIN_REC2020 = 4,
59   DT_COLORSPACE_XYZ = 5,
60   DT_COLORSPACE_LAB = 6,
61   DT_COLORSPACE_INFRARED = 7,
62   DT_COLORSPACE_DISPLAY = 8,
63   DT_COLORSPACE_EMBEDDED_ICC = 9,
64   DT_COLORSPACE_EMBEDDED_MATRIX = 10,
65   DT_COLORSPACE_STANDARD_MATRIX = 11,
66   DT_COLORSPACE_ENHANCED_MATRIX = 12,
67   DT_COLORSPACE_VENDOR_MATRIX = 13,
68   DT_COLORSPACE_ALTERNATE_MATRIX = 14,
69   DT_COLORSPACE_BRG = 15,
70   DT_COLORSPACE_EXPORT = 16, // export and softproof are categories and will return NULL with dt_colorspaces_get_profile()
71   DT_COLORSPACE_SOFTPROOF = 17,
72   DT_COLORSPACE_WORK = 18,
73   DT_COLORSPACE_DISPLAY2 = 19,
74   DT_COLORSPACE_REC709 = 20,
75   DT_COLORSPACE_PROPHOTO_RGB = 21,
76   DT_COLORSPACE_PQ_REC2020 = 22,
77   DT_COLORSPACE_HLG_REC2020 = 23,
78   DT_COLORSPACE_PQ_P3 = 24,
79   DT_COLORSPACE_HLG_P3 = 25,
80   DT_COLORSPACE_LAST = 26
81 } dt_colorspaces_color_profile_type_t;
82 
83 typedef enum dt_colorspaces_color_mode_t
84 {
85   DT_PROFILE_NORMAL = 0,
86   DT_PROFILE_SOFTPROOF,
87   DT_PROFILE_GAMUTCHECK
88 } dt_colorspaces_color_mode_t;
89 
90 typedef enum dt_colorspaces_profile_direction_t
91 {
92   DT_PROFILE_DIRECTION_IN = 1 << 0,
93   DT_PROFILE_DIRECTION_OUT = 1 << 1,
94   DT_PROFILE_DIRECTION_DISPLAY = 1 << 2,
95   DT_PROFILE_DIRECTION_CATEGORY = 1 << 3, // categories will return NULL with dt_colorspaces_get_profile()
96   DT_PROFILE_DIRECTION_WORK = 1 << 4,
97   DT_PROFILE_DIRECTION_DISPLAY2 = 1 << 5,
98   DT_PROFILE_DIRECTION_ANY = DT_PROFILE_DIRECTION_IN | DT_PROFILE_DIRECTION_OUT | DT_PROFILE_DIRECTION_DISPLAY
99                              | DT_PROFILE_DIRECTION_CATEGORY
100                              | DT_PROFILE_DIRECTION_WORK
101                              | DT_PROFILE_DIRECTION_DISPLAY2
102 } dt_colorspaces_profile_direction_t;
103 
104 typedef struct dt_colorspaces_t
105 {
106   GList *profiles;
107 
108   // xatom color profile:
109   pthread_rwlock_t xprofile_lock;
110   gchar *colord_profile_file;
111   uint8_t *xprofile_data;
112   int xprofile_size;
113 
114   gchar *colord_profile_file2;
115   uint8_t *xprofile_data2;
116   int xprofile_size2;
117 
118   // the current set of selected profiles
119   dt_colorspaces_color_profile_type_t display_type;
120   dt_colorspaces_color_profile_type_t display2_type;
121   dt_colorspaces_color_profile_type_t softproof_type;
122   dt_colorspaces_color_profile_type_t histogram_type;
123   char display_filename[512];
124   char display2_filename[512];
125   char softproof_filename[512];
126   char histogram_filename[512];
127   dt_iop_color_intent_t display_intent;
128   dt_iop_color_intent_t display2_intent;
129   dt_iop_color_intent_t softproof_intent;
130 
131   dt_colorspaces_color_mode_t mode;
132 
133   cmsHTRANSFORM transform_srgb_to_display, transform_adobe_rgb_to_display;
134   cmsHTRANSFORM transform_srgb_to_display2, transform_adobe_rgb_to_display2;
135 
136 } dt_colorspaces_t;
137 
138 typedef struct dt_colorspaces_color_profile_t
139 {
140   dt_colorspaces_color_profile_type_t type; // filename is only used for type DT_COLORSPACE_FILE
141   // must be in synch with DT_IOPPR_COLOR_ICC_LEN in iop_order.h
142   char filename[512];                       // icc file name
143   char name[512];                           // product name, displayed in GUI
144   cmsHPROFILE profile;                      // the actual profile
145   int in_pos;                               // position in input combo box, -1 if not applicable
146   int out_pos;                              // position in output combo box, -1 if not applicable
147   int display_pos;                          // position in display combo box, -1 if not applicable
148   int display2_pos;                         // position in display2 combo box, -1 if not applicable
149   int category_pos;                         // position in category combo box, -1 if not applicable
150   int work_pos;                             // position in working combo box, -1 if not applicable
151 } dt_colorspaces_color_profile_t;
152 
153 int mat3inv_float(float *const dst, const float *const src);
154 int mat3inv_double(double *const dst, const double *const src);
155 int mat3inv(float *const dst, const float *const src);
156 
157 /** populate the global color profile lists */
158 dt_colorspaces_t *dt_colorspaces_init();
159 /** cleanup on shutdown */
160 void dt_colorspaces_cleanup(dt_colorspaces_t *self);
161 
162 /** create a profile from a xyz->camera matrix. */
163 cmsHPROFILE dt_colorspaces_create_xyzimatrix_profile(float cam_xyz[3][3]);
164 
165 /** create a ICC virtual profile from the shipped presets in darktable. */
166 cmsHPROFILE dt_colorspaces_create_darktable_profile(const char *makermodel);
167 
168 /** create a ICC virtual profile from the shipped vendor matrices in darktable. */
169 cmsHPROFILE dt_colorspaces_create_vendor_profile(const char *makermodel);
170 
171 /** create a ICC virtual profile from the shipped alternate matrices in darktable. */
172 cmsHPROFILE dt_colorspaces_create_alternate_profile(const char *makermodel);
173 
174 /** just get the associated transformation matrix, for manual application. */
175 int dt_colorspaces_get_darktable_matrix(const char *makermodel, float *matrix);
176 
177 /** return the work profile as set in colorin */
178 const dt_colorspaces_color_profile_t *dt_colorspaces_get_work_profile(const int imgid);
179 
180 /** return the output profile as set in colorout, taking export override into account if passed in. */
181 const dt_colorspaces_color_profile_t *dt_colorspaces_get_output_profile(const int imgid,
182                                                                         dt_colorspaces_color_profile_type_t over_type,
183                                                                         const char *over_filename);
184 
185 /** return an rgb lcms2 profile from data. if data points to a grayscale profile a new rgb profile is created
186  * that has the same TRC, black and white point and rec709 primaries. */
187 cmsHPROFILE dt_colorspaces_get_rgb_profile_from_mem(uint8_t *data, uint32_t size);
188 
189 /** free the resources of a profile created with the functions above. */
190 void dt_colorspaces_cleanup_profile(cmsHPROFILE p);
191 
192 /** extracts tonecurves and color matrix prof to XYZ from a given input profile, returns 0 on success (curves
193  * and matrix are inverted for input) */
194 int dt_colorspaces_get_matrix_from_input_profile(cmsHPROFILE prof, float *matrix, float *lutr, float *lutg,
195                                                  float *lutb, const int lutsize);
196 
197 /** extracts tonecurves and color matrix prof to XYZ from a given output profile, returns 0 on success. */
198 int dt_colorspaces_get_matrix_from_output_profile(cmsHPROFILE prof, float *matrix, float *lutr, float *lutg,
199                                                   float *lutb, const int lutsize);
200 
201 /** wrapper to get the name from a color profile. this tries to handle character encodings. */
202 void dt_colorspaces_get_profile_name(cmsHPROFILE p, const char *language, const char *country, char *name,
203                                      size_t len);
204 
205 /** get a nice printable name. */
206 const char *dt_colorspaces_get_name(dt_colorspaces_color_profile_type_t type, const char *filename);
207 
208 /** common functions to change between colorspaces, used in iop modules */
209 void rgb2hsl(const float rgb[3], float *h, float *s, float *l);
210 void hsl2rgb(float rgb[3], float h, float s, float l);
211 
212 /** trigger updating the display profile from the system settings (x atom, colord, ...) */
213 void dt_colorspaces_set_display_profile(const dt_colorspaces_color_profile_type_t profile_type);
214 /** get the profile described by type & filename.
215  *  this doesn't support image specifics like embedded profiles or camera matrices */
216 const dt_colorspaces_color_profile_t *
217 dt_colorspaces_get_profile(dt_colorspaces_color_profile_type_t type, const char *filename,
218                            dt_colorspaces_profile_direction_t direction);
219 
220 /** check whether filename is the same profil as fullname, this is taking into account that
221  *  fullname is always the fullpathname to the profile and filename may be a full pathname
222  *  or just a base name */
223 gboolean  dt_colorspaces_is_profile_equal(const char *fullname, const char *filename);
224 
225 /** update the display transforms of srgb and adobergb to the display profile.
226  * make sure that darktable.color_profiles->xprofile_lock is held when calling this! */
227 void dt_colorspaces_update_display_transforms();
228 /** same for display2 */
229 void dt_colorspaces_update_display2_transforms();
230 
231 /** Calculate CAM->XYZ, XYZ->CAM matrices **/
232 int dt_colorspaces_conversion_matrices_xyz(const char *name, float in_XYZ_to_CAM[9], double XYZ_to_CAM[4][3], double CAM_to_XYZ[3][4]);
233 
234 /** Calculate CAM->RGB, RGB->CAM matrices and default WB multipliers */
235 int dt_colorspaces_conversion_matrices_rgb(const char *name, double RGB_to_CAM[4][3], double CAM_to_RGB[3][4], const float *embedded_matrix, double mul[4]);
236 
237 /** Applies CYGM WB coeffs to an image that's already been converted to RGB by dt_colorspaces_cygm_to_rgb */
238 void dt_colorspaces_cygm_apply_coeffs_to_rgb(float *out, const float *in, int num, double RGB_to_CAM[4][3], double CAM_to_RGB[3][4], float coeffs[4]);
239 
240 /** convert CYGM buffer to RGB */
241 void dt_colorspaces_cygm_to_rgb(float *out, int num, double CAM_to_RGB[3][4]);
242 
243 /** convert RGB buffer to CYGM */
244 void dt_colorspaces_rgb_to_cygm(float *out, int num, double RGB_to_CAM[4][3]);
245 
246 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
247 // vim: shiftwidth=2 expandtab tabstop=2 cindent
248 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
249