1 /* 2 */ 3 4 /* 5 6 Copyright (C) 2014 Ferrero Andrea 7 8 This program is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 22 */ 23 24 /* 25 26 These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ 27 28 */ 29 30 #ifndef PF_ICCSTORE_H 31 #define PF_ICCSTORE_H 32 33 #include <string.h> 34 #include <string> 35 #include <lcms2.h> 36 #include <glibmm.h> 37 #include <vips/vips.h> 38 39 #include "color.hh" 40 #include "../rt/rtengine/LUT.h" 41 42 namespace PF 43 { 44 45 enum TRC_type 46 { 47 PF_TRC_STANDARD=0, 48 PF_TRC_PERCEPTUAL=1, 49 PF_TRC_LINEAR=2, 50 PF_TRC_sRGB=3, 51 PF_TRC_GAMMA_22=4, 52 PF_TRC_GAMMA_18=5, 53 PF_TRC_UNKNOWN=1000 54 }; 55 56 57 enum profile_mode_t { 58 PROF_MODE_NONE, 59 PROF_MODE_DEFAULT, 60 PROF_MODE_EMBEDDED, 61 PROF_MODE_EMBEDDED_sRGB, 62 PROF_MODE_CUSTOM, 63 PROF_MODE_ICC 64 }; 65 66 67 enum profile_type_t { 68 PROF_TYPE_EMBEDDED, 69 PROF_TYPE_FROM_SETTINGS, 70 PROF_TYPE_FROM_DISK, 71 PROF_TYPE_sRGB, 72 PROF_TYPE_sRGB_D50, 73 PROF_TYPE_REC2020, 74 PROF_TYPE_ADOBE, 75 PROF_TYPE_PROPHOTO, 76 PROF_TYPE_PROPHOTO_D65, 77 PROF_TYPE_ACEScg, 78 PROF_TYPE_ACES, 79 PROF_TYPE_LAB, 80 PROF_TYPE_XYZ, 81 PROF_TYPE_CUSTOM, 82 PROF_TYPE_NONE, 83 }; 84 85 86 87 extern cmsToneCurve* Lstar_trc; 88 extern cmsToneCurve* iLstar_trc; 89 90 91 struct ICCProfileData 92 { 93 cmsToneCurve* perceptual_trc; 94 cmsToneCurve* perceptual_trc_inv; 95 TRC_type trc_type; 96 97 //float perceptual_trc_vec[65536]; 98 //float perceptual_trc_inv_vec[65536]; 99 100 float Y_R, Y_G, Y_B; 101 }; 102 103 104 #define PF_GAMUT_MAP_NJZ 500 105 106 class ICCTransform; 107 108 class ICCProfile 109 { 110 bool has_colorants; 111 void* profile_data; 112 cmsUInt32Number profile_size; 113 cmsHPROFILE profile; 114 cmsToneCurve* perceptual_trc; 115 cmsToneCurve* perceptual_trc_inv; 116 profile_type_t profile_type; 117 TRC_type trc_type; 118 bool parametric_trc; 119 120 Glib::ustring filename; 121 122 //float perceptual_trc_vec[65536]; 123 //float perceptual_trc_inv_vec[65536]; 124 125 LUTf p2l_lut, l2p_lut; 126 127 double colorants[9]; 128 float rgb2xyz[3][3]; 129 float rgb2xyz100_D65[3][3]; 130 float xyz1002rgb_D65[3][3]; 131 float Y_R, Y_G, Y_B; 132 133 void init_trc( cmsToneCurve* trc, cmsToneCurve* trc_inv ); 134 135 int refcount; 136 137 ICCTransform* to_lab; 138 ICCTransform* from_lab; 139 140 float** gamut_boundary; 141 float** gamut_boundary_out; 142 float* gamut_Lid_Cmax; 143 144 145 public: 146 ICCProfile(); 147 virtual ~ICCProfile(); 148 ref()149 void ref() { refcount += 1; } unref()150 void unref() { refcount -= 1; } get_ref_count()151 int get_ref_count() { return refcount; } 152 set_file_name(Glib::ustring name)153 void set_file_name( Glib::ustring name ) { filename = name; } get_file_name()154 Glib::ustring get_file_name() { return filename; } 155 156 void init_colorants(); 157 void init_trc(); 158 void init_Lab_conversions( ICCProfile* plab ); 159 160 bool is_rgb(); 161 bool is_grayscale(); 162 bool is_lab(); 163 bool is_cmyk(); 164 165 bool is_matrix(); get_colorants()166 double* get_colorants() { return colorants; } 167 set_profile_type(profile_type_t p)168 void set_profile_type(profile_type_t p) { profile_type = p; } get_profile_type()169 profile_type_t get_profile_type() { return profile_type; } set_trc_type(TRC_type type)170 void set_trc_type(TRC_type type) { trc_type = type; } get_trc_type()171 TRC_type get_trc_type() { return trc_type; } is_linear()172 bool is_linear() { return( get_trc_type() == PF_TRC_LINEAR ); } is_parametric()173 bool is_parametric() { return( parametric_trc ); } is_perceptual()174 bool is_perceptual() { return( get_trc_type() == PF_TRC_PERCEPTUAL ); } is_standard()175 bool is_standard() { return( get_trc_type() == PF_TRC_STANDARD ); } 176 get_p2l_trc()177 cmsToneCurve* get_p2l_trc() { return perceptual_trc; } get_l2p_trc()178 cmsToneCurve* get_l2p_trc() { return perceptual_trc_inv; } 179 180 void set_profile( cmsHPROFILE p ); 181 cmsHPROFILE get_profile(); //{ return profile; } 182 get_profile_size()183 cmsUInt32Number get_profile_size() { return profile_size; } get_profile_data()184 void* get_profile_data() { return profile_data; } 185 186 cmsFloat32Number linear2perceptual( cmsFloat32Number val ); 187 cmsFloat32Number perceptual2linear( cmsFloat32Number val ); 188 189 //float* get_linear2perceptual_vec() { return perceptual_trc_inv_vec; } 190 //float* get_perceptual2linear_vec() { return perceptual_trc_vec; } 191 get_luminance(const float & R,const float & G,const float & B)192 float get_luminance( const float& R, const float& G, const float& B ) 193 { 194 return( (has_colorants) ? Y_R*R + Y_G*G + Y_B*B : 0.0f ); 195 } 196 //void get_luminance( float* RGBv, float* Lv, size_t size ); 197 198 float get_lightness( const float& R, const float& G, const float& B ); 199 void get_lightness( float* RGBv, float* Lv, size_t size ); 200 201 void to_Jzazbz( const float& R, const float& G, const float& B, float& Jz, float& az, float& bz ); 202 void from_Jzazbz( const float& Jz, const float& az, const float& bz, float& R, float& G, float& B ); 203 204 void init_gamut_mapping(); 205 void set_destination_gamut(ICCProfile* pout); get_gamut_boundary()206 float** get_gamut_boundary() { return gamut_boundary; } get_gamut_Lid_Cmax()207 float* get_gamut_Lid_Cmax() { return gamut_Lid_Cmax; } 208 void gamut_mapping( float& R, float& G, float& B, float** gamut_boundary_out, float* gamut_Lid_Cmax_out, float saturation ); 209 bool chroma_compression( float& J, float& C, float& H, float** gamut_boundary_out, float* gamut_Lid_Cmax_out, float saturation ); 210 211 bool equals_to( PF::ICCProfile* prof); 212 get_data()213 ICCProfileData* get_data() 214 { 215 ICCProfileData* data = new ICCProfileData; 216 data->trc_type = trc_type; 217 //memcpy( data->perceptual_trc_vec, perceptual_trc_vec, sizeof(perceptual_trc_vec) ); 218 //memcpy( data->perceptual_trc_inv_vec, perceptual_trc_inv_vec, sizeof(perceptual_trc_inv_vec) ); 219 data->perceptual_trc = cmsDupToneCurve( perceptual_trc ); 220 data->perceptual_trc_inv = cmsDupToneCurve( perceptual_trc_inv ); 221 data->Y_R = Y_R; 222 data->Y_G = Y_G; 223 data->Y_B = Y_B; 224 225 return data; 226 } 227 }; 228 229 230 //ICCProfileData* get_icc_profile_data( VipsImage* img ); 231 //void free_icc_profile_data( ICCProfileData* data ); 232 void set_icc_profile( VipsImage* img, ICCProfile* prof ); 233 ICCProfile* get_icc_profile( VipsImage* img ); 234 void iccprofile_unref( void* prof ); 235 236 //cmsFloat32Number linear2perceptual( ICCProfileData* data, cmsFloat32Number val ); 237 //cmsFloat32Number perceptual2linear( ICCProfileData* data, cmsFloat32Number val ); 238 239 240 class DiskProfile: public ICCProfile 241 { 242 public: 243 DiskProfile(); 244 }; 245 246 247 class ACESProfile: public ICCProfile 248 { 249 public: 250 ACESProfile(TRC_type type); 251 }; 252 253 254 class Rec2020Profile: public ICCProfile 255 { 256 public: 257 Rec2020Profile(TRC_type type); 258 }; 259 260 261 class sRGBProfile: public ICCProfile 262 { 263 public: 264 sRGBProfile(TRC_type type); 265 }; 266 267 268 class sRGBProfileD50: public ICCProfile 269 { 270 public: 271 sRGBProfileD50(TRC_type type); 272 }; 273 274 275 class ProPhotoProfile: public ICCProfile 276 { 277 public: 278 ProPhotoProfile(TRC_type type); 279 }; 280 281 282 class ProPhotoProfileD65: public ICCProfile 283 { 284 public: 285 ProPhotoProfileD65(TRC_type type); 286 }; 287 288 289 class LabProfile: public ICCProfile 290 { 291 public: 292 LabProfile(TRC_type type); 293 }; 294 295 296 class XYZProfile: public ICCProfile 297 { 298 public: 299 XYZProfile(TRC_type type); 300 }; 301 302 303 class ICCTransform 304 { 305 ICCProfile* in_profile; 306 ICCProfile* out_profile; 307 cmsUInt32Number intent; 308 bool bpc; 309 float adaptation_state; 310 cmsHTRANSFORM transform; 311 312 LUTf trc_lut, itrc_lut; 313 314 bool is_rgb2rgb; 315 float rgb2rgb[3][3]; 316 317 cmsColorSpaceSignature input_cs_type; 318 cmsColorSpaceSignature output_cs_type; 319 320 public: ICCTransform()321 ICCTransform(): in_profile(NULL), out_profile(NULL), transform(NULL) {} ~ICCTransform()322 ~ICCTransform() { 323 if( transform ) { 324 cmsDeleteTransform( transform ); 325 } 326 } valid()327 bool valid() { return( transform!=NULL || is_rgb2rgb ); } 328 void init(ICCProfile* in_profile, ICCProfile* out_profile, VipsBandFormat band_fmt, 329 cmsUInt32Number intent=INTENT_RELATIVE_COLORIMETRIC, 330 bool bpc=true, float adaptation_state=0); 331 void apply(float* in, float* out, int n=1); 332 }; 333 334 335 class ICCStore 336 { 337 ICCProfile* srgb_profiles[6]; 338 ICCProfile* srgb_d50_profiles[6]; 339 ICCProfile* rec2020_profiles[6]; 340 ICCProfile* aces_profiles[6]; 341 ICCProfile* acescg_profiles[6]; 342 ICCProfile* adobe_profiles[6]; 343 ICCProfile* prophoto_profiles[6]; 344 ICCProfile* prophoto_d65_profiles[6]; 345 ICCProfile* system_monitor_profile; 346 std::vector<ICCProfile*> profiles; 347 348 ICCProfile* Lab_profile; 349 ICCProfile* XYZ_profile; 350 351 static ICCStore* instance; 352 353 Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS 354 public: 355 ICCStore(); 356 357 static ICCStore& Instance(); 358 get_srgb_profile(TRC_type type)359 ICCProfile* get_srgb_profile(TRC_type type) { return srgb_profiles[type]; } 360 ICCProfile* get_profile(profile_type_t ptype, TRC_type trc_type); 361 ICCProfile* get_profile( Glib::ustring pname ); 362 ICCProfile* get_profile( void* pdata, cmsUInt32Number psize ); 363 ICCProfile* get_profile( cmsHPROFILE profile ); 364 get_Lab_profile()365 ICCProfile* get_Lab_profile() { return Lab_profile; } get_XYZ_profile()366 ICCProfile* get_XYZ_profile() { return XYZ_profile; } 367 get_Lstar_trc()368 cmsToneCurve* get_Lstar_trc() {return Lstar_trc; } get_iLstar_trc()369 cmsToneCurve* get_iLstar_trc() {return iLstar_trc; } 370 371 void set_system_monitor_profile( cmsHPROFILE profile ); get_system_monitor_profile()372 ICCProfile* get_system_monitor_profile() { return system_monitor_profile; } 373 }; 374 } 375 376 377 #endif 378 379 380