Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
imageio_profile.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010 Alex Chateau.
4 Copyright (C) 2010-2011 Henrik Andersson.
5 Copyright (C) 2010-2013, 2016-2017 johannes hanika.
6 Copyright (C) 2010 José Carlos García Sogo.
7 Copyright (C) 2010, 2012-2014 Pascal de Bruijn.
8 Copyright (C) 2011 Antony Dovgal.
9 Copyright (C) 2011 Bruce Guenter.
10 Copyright (C) 2011 Robert Bieber.
11 Copyright (C) 2011-2018 Tobias Ellinghaus.
12 Copyright (C) 2011, 2013-2014 Ulrich Pegelow.
13 Copyright (C) 2012 Christian Tellefsen.
14 Copyright (C) 2012 Jérémy Rosen.
15 Copyright (C) 2012 Richard Wonka.
16 Copyright (C) 2014-2016 Pedro Côrte-Real.
17 Copyright (C) 2014-2016 Roman Lebedev.
18 Copyright (C) 2015 parafin.
19 Copyright (C) 2016 Peter Budai.
20 Copyright (C) 2018-2019 Edgardo Hoszowski.
21 Copyright (C) 2019 Andreas Schneider.
22 Copyright (C) 2019-2020 Heiko Bauke.
23 Copyright (C) 2019 jakubfi.
24 Copyright (C) 2019 luzpaz.
25 Copyright (C) 2019 Matthias Vogelgesang.
26 Copyright (C) 2019-2022 Pascal Obry.
27 Copyright (C) 2019 Philippe Weyland.
28 Copyright (C) 2020 a.
29 Copyright (C) 2020, 2022-2026 Aurélien PIERRE.
30 Copyright (C) 2020 Dan Torop.
31 Copyright (C) 2020 Hubert Kowalski.
32 Copyright (C) 2020-2021 Miloš Komarčević.
33 Copyright (C) 2020-2021 Ralf Brown.
34 Copyright (C) 2021 Sakari Kapanen.
35 Copyright (C) 2022 Martin Bařinka.
36 Copyright (C) 2023 Alynx Zhou.
37 Copyright (C) 2023 Luca Zulberti.
38
39 darktable is free software: you can redistribute it and/or modify
40 it under the terms of the GNU General Public License as published by
41 the Free Software Foundation, either version 3 of the License, or
42 (at your option) any later version.
43
44 darktable is distributed in the hope that it will be useful,
45 but WITHOUT ANY WARRANTY; without even the implied warranty of
46 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 GNU General Public License for more details.
48
49 You should have received a copy of the GNU General Public License
50 along with darktable. If not, see <http://www.gnu.org/licenses/>.
51*/
52
53/* Choosing an ICC profile FOR AN IMAGE, and reading the one the file carries.
54 *
55 * This is codec work, not colour-management work, which is why it lives here rather than with
56 * the LittleCMS2 code in common/colorspaces.c. Deciding that a JPEG's embedded profile beats
57 * its EXIF colorspace tag, or that a RAW should use its camera matrix, means knowing what each
58 * format stores and where -- and it was the only reason colorspaces.c included six imageio
59 * codec headers.
60 */
61
63#include "common/paths.h" // DT_PATH_MAX
64
66#include "common/image.h"
67#include "caches/image_cache.h"
68#include "common/logging.h"
69#include "system/macros.h"
70#include "system/mem_alloc.h"
71
72#include <lcms2.h>
73#include <string.h>
74
75#ifdef HAVE_OPENJPEG
76#include "imageio/imageio_j2k.h" // conditional-ok: only the HAVE_OPENJPEG branch below reads J2K
77#endif
79#include "imageio/imageio_png.h"
81#ifdef HAVE_LIBAVIF
82#include "imageio/imageio_avif.h" // conditional-ok: only the HAVE_LIBAVIF branch below reads AVIF
83#endif
84#ifdef HAVE_LIBHEIF
85#include "imageio/imageio_heif.h" // conditional-ok: only the HAVE_LIBHEIF branch below reads HEIF
86#endif
87
89{
90 // Note : when the image has already been opened from cache on the current session,
91 // the embedded color profile is already inited and stored in img->profile.
92
93 // Untagged images should be assumed to be sRGB.
96
97 /* The `goto finish` below (invalid imgid -> no cache entry) skips every assignment to
98 * *output, including the sRGB fallback at the end, so the caller was left returning an
99 * indeterminate pointer that reached cmsCreateTransform. Establish the contract here:
100 * *output is always written. */
101 if(!IS_NULL_PTR(output)) *output = NULL;
102
103 // Fetch filename for extension retrieval
104 char filename[DT_PATH_MAX] = { 0 };
105 gboolean from_cache = TRUE;
107
108 const gchar *cc = filename + strlen(filename);
109 for(; *cc != '.' && cc > filename; cc--);
110 gchar *ext = g_ascii_strdown(cc + 1, -1);
111
112 // Fetch actual image
113 dt_image_t *img = dt_image_cache_get(imgid, 'w');
114 if(IS_NULL_PTR(img)) goto finish;
115
116 // Image codecs doing their own colorspace detection should set this to TRUE
117 gboolean already_set = FALSE;
118
119 dt_print(DT_DEBUG_COLORPROFILE, "Color profile type for %s: \n", filename);
120
121 /* Both of these CREATE a profile. Calling them once in the condition and again in the
122 * body -- which is what this cascade did -- leaked the first one every time the branch
123 * was taken. Create once, here, and hand the same object out below. The second is built
124 * only if the first failed, which is what the else-if short-circuit used to express. */
125 cmsHPROFILE embedded_icc = NULL;
126 if(img->profile && img->profile_size > 0)
128
129 cmsHPROFILE exif_matrix = NULL;
132
134 {
135 // Fast path : we already extracted ICC before. ICC profile is already inside.
137 if(!IS_NULL_PTR(output))
138 {
139 *output = embedded_icc;
140 embedded_icc = NULL; // handed over
141 *new_profile = TRUE;
142 }
143 dt_print(DT_DEBUG_COLORPROFILE, "Embedded ICC profile (inline)\n");
144 }
145 else if(!IS_NULL_PTR(exif_matrix))
146 {
147 // DNG and others : matrix inside EXIF
149 if(!IS_NULL_PTR(output))
150 {
151 *output = exif_matrix;
152 exif_matrix = NULL; // handed over
153 *new_profile = TRUE;
154 }
155 dt_print(DT_DEBUG_COLORPROFILE, "Embedded EXIF matrix\n");
156 }
157 else if(dt_image_is_monochrome(img))
158 {
159 // Monochrome RAW - colorspace doesn't matter
161 if(!IS_NULL_PTR(output))
163 dt_print(DT_DEBUG_COLORPROFILE, "Monochrome RAW\n");
164 }
166 {
167 // Color RAW
169 if(!IS_NULL_PTR(output))
170 {
172 *new_profile = TRUE;
173 }
174 dt_print(DT_DEBUG_COLORPROFILE, "Typical RAW\n");
175 }
176 else if(img->flags & DT_IMAGE_4BAYER)
177 {
178 // 4Bayer images have been pre-converted to rec2020
180 if(!IS_NULL_PTR(output))
182 dt_print(DT_DEBUG_COLORPROFILE, "4Bayer RAW\n");
183 }
184 else if(img->colorspace == DT_IMAGE_COLORSPACE_SRGB)
185 {
186 // Images tagged explicitely with sRGB flag
188 dt_print(DT_DEBUG_COLORPROFILE, "Raster image tagged with sRGB\n");
189 }
191 {
192 // Images tagged explicitely with Adobe RGB flag
194 if(!IS_NULL_PTR(output))
196 dt_print(DT_DEBUG_COLORPROFILE, "Raster image tagged with Adobe RGB\n");
197 }
198 else if(!strcmp(ext, "pfm"))
199 {
200 // PFM have no embedded color profile nor ICC tag, we can't know the color space
201 // but we can assume the are linear since it's a floating point format
203 if(!IS_NULL_PTR(output))
205 dt_print(DT_DEBUG_COLORPROFILE, "PFM untagged image\n");
206 }
207 else
208 {
209 // Images that need codecs.
210
211 // First, extract embedded profiles from headers.
212 // Done only once : if everything goes well, the next time we access this image from cache,
213 // we will read img->profile directly (first branch here).
214
215 if(!strcmp(ext, "jpg") || !strcmp(ext, "jpeg"))
216 {
220 }
221#ifdef HAVE_OPENJPEG
222 else if(!strcmp(ext, "jp2") || !strcmp(ext, "j2k") || !strcmp(ext, "j2c") || !strcmp(ext, "jpc"))
223 {
225 }
226#endif
227 else if((!strcmp(ext, "tif") || !strcmp(ext, "tiff")))
228 {
230 }
231 else if(!strcmp(ext, "png"))
232 {
234 }
235#ifdef HAVE_LIBAVIF
236 else if(!strcmp(ext, "avif"))
237 {
240
241 // try the nclx box before falling back to any ICC profile
243
244 // If we found a basic RGB colorspace from private AVIF metadata,
245 // bypass generic LCMS2 reading below
247 }
248#endif
249#ifdef HAVE_LIBHEIF
250 else if(!strcmp(ext, "heif") || !strcmp(ext, "heic") || !strcmp(ext, "hif"))
251 {
254
255 // try the nclx box before falling back to any ICC profile
257
258 // If we found a basic RGB colorspace from private AVIF metadata,
259 // bypass generic LCMS2 reading below
261 }
262#endif
263
264 // Finally, read the prepared embedded profile
265 /* Same double-create as above: build it once. */
266 cmsHPROFILE extracted_icc = NULL;
267 if(!already_set && img->profile && img->profile_size > 0)
269
271 {
273 if(!IS_NULL_PTR(output))
274 {
275 *output = extracted_icc;
276 extracted_icc = NULL; // handed over
277 *new_profile = TRUE;
278 }
279 dt_print(DT_DEBUG_COLORPROFILE, "Embedded ICC (extracted)\n");
280 }
281 else if(already_set && img->profile && img->profile_size > 0)
282 {
283 // This happens when AVIF/HEIF found a basic color profile into CICP fields
284 if(!IS_NULL_PTR(output))
286 dt_print(DT_DEBUG_COLORPROFILE, "Embedded ICC (extracted)\n");
287 }
288
290 }
291
292 // Handle the fallback to sRGB space
296
297 /* Anything built above but not handed to the caller is ours to close. This is the
298 * `output == NULL` case -- a caller that wants only the resolved type -- and the branches
299 * where a later one in the cascade won. Deliberately before the label: the `goto finish`
300 * path runs before either is created. */
303
304finish:
306 dt_free(ext);
307 return color_profile;
308}
310 int32_t imgid,
312 cmsHPROFILE *output,
313 gboolean *new_profile)
314{
315 if(output) *output = NULL;
317
319 return dt_image_find_best_color_profile(imgid, output, new_profile);
320
324 return DT_COLORSPACE_NONE;
325
326 const dt_image_t *img = dt_image_cache_get(imgid, 'r');
327 if(IS_NULL_PTR(img)) return DT_COLORSPACE_NONE;
328
330 {
332 return dt_image_find_best_color_profile(imgid, output, new_profile);
333 }
334
335 gboolean have_embedded_icc = (img->profile && img->profile_size > 0);
337
339 {
340 // Try to extract embedded ICC into cache if needed.
341 gboolean dummy_new_profile = FALSE;
343 }
344
345 img = dt_image_cache_get(imgid, 'r');
346 if(IS_NULL_PTR(img)) return DT_COLORSPACE_NONE;
347
348 cmsHPROFILE profile = NULL;
350
352 {
353 if(img->profile && img->profile_size > 0)
354 {
356 if(profile)
357 {
359 goto finish;
360 }
361 }
363 }
364
366 {
367 if(!isnan(img->d65_color_matrix[0]))
368 {
370 if(profile)
371 {
373 goto finish;
374 }
375 }
377 }
378
380 {
381 if(!isnan(img->adobe_XYZ_to_CAM[0][0]))
382 {
384 if(profile)
385 {
387 goto finish;
388 }
389 }
390 }
391
393
394finish:
396
397 if(profile)
398 {
399 if(output)
400 {
401 *output = profile;
403 }
404 else
405 {
407 }
408 }
409
410 return type;
411}
413{
414 cmsHPROFILE output = NULL;
416 return output;
417}
418/* Build (or reuse) the parsed profile for an image's embedded ICC, and give it to the image.
419 *
420 * It used to be appended to dt_colorspaces_t.profiles instead. That list is built once by
421 * dt_colorspaces_init() and then read from ~23 places without any lock, which is only safe
422 * while it is immutable -- and this function made it mutable, from export jobs that run in
423 * parallel. It also grew the list for the lifetime of the session (one entry per exported
424 * image), and leaked the container outright whenever the profile was not newly created,
425 * because only the new_profile branch ever registered it.
426 *
427 * An embedded profile is a property of one image, so the image owns it: stored under the image
428 * cache entry's own lock, freed when the image is evicted, and reused on the next export of the
429 * same image instead of built again.
430 */
433{
434 gboolean new_profile = FALSE;
436
437 // -1 in all indices ensures it is hidden from the GUI: this profile belongs to one image and
438 // has no place in any combo box.
439 /* new_profile carries ownership: several branches of dt_image_find_best_color_profile()
440 * return a profile borrowed from the application-wide list rather than a fresh one, and a
441 * container that closed such a profile would double-free it. */
444 {
446 return NULL;
447 }
448
449 if(profile && new_profile)
450 {
451 char *lang = getenv("LANG");
452 if(IS_NULL_PTR(lang)) lang = "en_US";
453 dt_colorspaces_get_profile_name(profile, lang, lang + 3, container->name, sizeof(container->name));
454 }
455
456 dt_image_t *img = dt_image_cache_get(imgid, 'w');
457 if(IS_NULL_PTR(img))
458 {
459 // No image to hand it to. Better to leak nothing and let the caller fall back than to put
460 // it back on the global list.
462 return NULL;
463 }
464
465 const dt_colorspaces_color_profile_t *result;
466 if(img->embedded_profile)
467 {
468 // Another thread got here first while we were parsing. Theirs is as good as ours, and it is
469 // the one every other borrower already holds.
471 result = img->embedded_profile;
472 }
473 else
474 {
476 result = container;
477 }
478 // Nothing persistent changed: this is a cached derivation of bytes already in the image.
480
481 return result;
482}
484 const int32_t imgid,
486 const char *camera_makermodel,
488{
489 if(resolved) *resolved = DT_COLORSPACE_NONE;
490
492 cmsHPROFILE profile = NULL;
493 gboolean owns = FALSE;
494
495 /* The three built-from-the-camera types. Each falls over to the embedded-ICC branch when
496 * this camera is not in the corresponding table -- which is what "matrix not found" means
497 * to a user, and why the fallthrough below is a chain rather than a switch. */
499 {
500 profile = camera_makermodel ? dt_colorspaces_create_darktable_profile(camera_makermodel) : NULL;
502 else owns = TRUE;
503 }
505 {
506 profile = camera_makermodel ? dt_colorspaces_create_vendor_profile(camera_makermodel) : NULL;
508 else owns = TRUE;
509 }
511 {
512 profile = camera_makermodel ? dt_colorspaces_create_alternate_profile(camera_makermodel) : NULL;
514 else owns = TRUE;
515 }
516
520 {
521 gboolean new_profile = FALSE;
524 }
525
526 if(IS_NULL_PTR(profile)) return NULL;
527
530 {
531 /* Do not leak the handle just because the container allocation failed: only WE know at
532 * this point whether it was created here or borrowed from the application list. */
534 return NULL;
535 }
536
537 if(resolved) *resolved = type;
538 return container;
539}
540
555
558 const char *over_filename)
559{
560
562
563 // Special case if output is undefined or uses private image color spaces : use the embedded profile if any.
564 // We need to read it from the original image and create it on-the-fly.
565 // Note: we don't allow export with deprecated vendor/enhanced/alternate matrices
570 {
572 }
573 else
574 {
575 // return a pointer to the profile specified in export.
576 // we have that in here to get rid of the if() check in all places calling this function.
578 }
579
580 // if all else fails -> fall back to sRGB
581 if(IS_NULL_PTR(p))
582 {
585 }
586
587 return p;
588}
590{
591 switch(cicp->color_primaries)
592 {
593 /* Give up immediately if unspecified */
595 if(cicp->transfer_characteristics == DT_CICP_TRANSFER_CHARACTERISTICS_UNSPECIFIED
596 && cicp->matrix_coefficients == DT_CICP_MATRIX_COEFFICIENTS_UNSPECIFIED)
597 return DT_COLORSPACE_NONE;
598 break; /* unspecified */
599
600 /* REC709 */
602
603 switch(cicp->transfer_characteristics)
604 {
605 /* SRGB */
607
608 switch(cicp->matrix_coefficients)
609 {
610 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
613 case DT_CICP_MATRIX_COEFFICIENTS_REC601: /* support equivalents just in case of mistagging */
614 case DT_CICP_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL: /* support incorrectly tagged files */
616 return DT_COLORSPACE_SRGB;
617 default:
618 break;
619 }
620
621 break; /* SRGB */
622
623 /* REC709 */
625 case DT_CICP_TRANSFER_CHARACTERISTICS_REC601: /* support equivalents just in case of mistagging */
626 case DT_CICP_TRANSFER_CHARACTERISTICS_REC2020_10B: /* support equivalents just in case of mistagging */
627 case DT_CICP_TRANSFER_CHARACTERISTICS_REC2020_12B: /* support equivalents just in case of mistagging */
628
629 switch(cicp->matrix_coefficients)
630 {
631 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
636 default:
637 break;
638 }
639
640 break; /* REC709 */
641
642 /* LINEAR REC709 */
644
645 switch(cicp->matrix_coefficients)
646 {
647 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
652 default:
653 break;
654 }
655
656 break; /* LINEAR REC709 */
657
658 default:
659 break;
660 }
661
662 break; /* REC709 */
663
664 /* REC2020 */
666
667 switch(cicp->transfer_characteristics)
668 {
669 /* LINEAR REC2020 */
671
672 switch(cicp->matrix_coefficients)
673 {
674 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
679 default:
680 break;
681 }
682
683 break; /* LINEAR REC2020 */
684
685 /* PQ REC2020 */
687
688 switch(cicp->matrix_coefficients)
689 {
690 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
695 default:
696 break;
697 }
698
699 break; /* PQ REC2020 */
700
701 /* HLG REC2020 */
703
704 switch(cicp->matrix_coefficients)
705 {
706 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
711 default:
712 break;
713 }
714
715 break; /* HLG REC2020 */
716
717 default:
718 break;
719 }
720
721 break; /* REC2020 */
722
723 /* P3 */
725
726 switch(cicp->transfer_characteristics)
727 {
728 /* PQ P3 */
730
731 switch(cicp->matrix_coefficients)
732 {
733 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
739 return DT_COLORSPACE_PQ_P3;
740 default:
741 break;
742 }
743
744 break; /* PQ P3 */
745
746 /* HLG P3 */
748
749 switch(cicp->matrix_coefficients)
750 {
751 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
758 default:
759 break;
760 }
761
762 break; /* HLG P3 */
763
764 /* Display P3 */
766
767 switch(cicp->matrix_coefficients)
768 {
769 case DT_CICP_MATRIX_COEFFICIENTS_IDENTITY: /* support RGB (4:4:4 or lossless) */
776 default:
777 break;
778 }
779
780 break; /* Display P3 */
781
782 default:
783 break;
784 }
785
786 break; /* P3 */
787
788 /* XYZ */
790
791 switch(cicp->transfer_characteristics)
792 {
793 /* LINEAR XYZ */
795
796 switch(cicp->matrix_coefficients)
797 {
800 return DT_COLORSPACE_XYZ;
801 default:
802 break;
803 }
804
805 break; /* LINEAR XYZ */
806
807 default:
808 break;
809 }
810
811 break; /* XYZ */
812
813 default:
814 break;
815 }
816
818 dt_print(DT_DEBUG_IMAGEIO, "[colorin] unsupported CICP color profile for `%s': %d/%d/%d\n", filename,
819 cicp->color_primaries, cicp->transfer_characteristics, cicp->matrix_coefficients);
820
821 return DT_COLORSPACE_NONE;
822}
823
824// clang-format off
825// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
826// vim: shiftwidth=2 expandtab tabstop=2 cindent
827// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
828// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
uint32_t container(dt_lib_module_t *self)
cmsHPROFILE dt_colorspaces_create_xyzimatrix_profile(float mat[3][3])
Create a linear-gamma RGB profile from an XYZ->camera matrix.
void dt_colorspaces_free_image_profile(struct dt_colorspaces_color_profile_t *profile)
Release a profile container owned by an image, closing the LCMS2 handle inside it if and only if the ...
struct dt_colorspaces_color_profile_t * dt_colorspaces_new_image_profile(dt_colorspaces_color_profile_type_t type, cmsHPROFILE profile, gboolean owns_profile)
Build a container for a profile that belongs to ONE image rather than to the application.
const dt_colorspaces_color_profile_t * dt_colorspaces_get_profile(dt_colorspaces_color_profile_type_t type, const char *filename, dt_colorspaces_profile_role_t role)
Resolve a profile identity to its registered entry.
cmsHPROFILE dt_colorspaces_create_vendor_profile(const char *makermodel)
Create an ICC virtual profile from the shipped vendor matrices.
cmsHPROFILE dt_colorspaces_create_darktable_profile(const char *makermodel)
Create an ICC virtual profile from the shipped profiled colour matrices.
void dt_colorspaces_cleanup_profile(cmsHPROFILE p)
Close a profile created by any of the dt_colorspaces_create_* / dt_colorspaces_get_rgb_profile_from_m...
cmsHPROFILE dt_colorspaces_get_rgb_profile_from_mem(uint8_t *data, uint32_t size)
Open an lcms2 RGB profile from an in-memory ICC blob.
void dt_colorspaces_get_profile_name(cmsHPROFILE p, const char *language, const char *country, char *name, size_t len)
Read a profile's description tag into name, handling character encodings.
cmsHPROFILE dt_colorspaces_create_alternate_profile(const char *makermodel)
Create an ICC virtual profile from the shipped alternate matrices.
The colour-profile module's API: which profiles exist, and how to apply one.
gboolean dt_image_is_matrix_correction_supported(const dt_image_t *img)
gboolean dt_image_is_monochrome(const dt_image_t *img)
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
@ DT_IMAGE_COLORSPACE_ADOBE_RGB
Definition image.h:194
@ DT_IMAGE_COLORSPACE_SRGB
Definition image.h:193
@ DT_IMAGE_4BAYER
Definition image.h:140
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
@ DT_IMAGE_CACHE_RELAXED
Definition image_cache.h:50
int dt_imageio_avif_read_profile(const char *filename, uint8_t **out, dt_colorspaces_cicp_t *cicp)
int dt_imageio_heif_read_profile(const char *filename, uint8_t **out, dt_colorspaces_cicp_t *cicp)
int dt_imageio_j2k_read_profile(const char *filename, uint8_t **out)
int dt_imageio_jpeg_read_profile(dt_imageio_jpeg_t *jpg, uint8_t **out)
int dt_imageio_jpeg_read_header(const char *filename, dt_imageio_jpeg_t *jpg)
int dt_imageio_png_read_profile(const char *filename, uint8_t **out)
static const dt_colorspaces_color_profile_t * _build_embedded_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *type)
dt_colorspaces_color_profile_type_t dt_colorspaces_get_input_profile_from_image(int32_t imgid, dt_colorspaces_color_profile_type_t requested, cmsHPROFILE *output, gboolean *new_profile)
Resolve an embedded/matrix input profile for a given image, honoring the requested type when possible...
const dt_colorspaces_color_profile_t * dt_colorspaces_get_output_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *over_type, const char *over_filename)
const cmsHPROFILE dt_colorspaces_get_embedded_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *type, gboolean *new_profile)
struct dt_colorspaces_color_profile_t * dt_image_get_input_profile(const int32_t imgid, const dt_colorspaces_color_profile_type_t requested, const char *camera_makermodel, dt_colorspaces_color_profile_type_t *resolved)
Resolve an image's own input profile into an opaque container, whatever kind it is.
struct dt_colorspaces_color_profile_t * dt_image_get_embedded_output_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *type)
Resolve the ICC profile embedded in an image's own file, into an opaque container.
dt_colorspaces_color_profile_type_t dt_image_find_best_color_profile(int32_t imgid, cmsHPROFILE *output, gboolean *new_profile)
Best effort to find a suitable (input) color profile for a given image, using embedded ICC or EXIF wh...
dt_colorspaces_color_profile_type_t dt_colorspaces_cicp_to_type(const dt_colorspaces_cicp_t *cicp, const char *filename)
int dt_imageio_tiff_read_profile(const char *filename, uint8_t **out)
_lib_location_type_t type
Definition location.c:1
@ DT_DEBUG_COLORPROFILE
Definition logging.h:79
@ DT_DEBUG_IMAGEIO
Definition logging.h:68
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...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
Definition paths.h:57
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_ADOBERGB
@ DT_COLORSPACE_EMBEDDED_MATRIX
@ DT_COLORSPACE_EMBEDDED_ICC
Image-derived profiles: enum 9..14, NOT registered in the list.
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_COLORSPACE_REC709
@ DT_COLORSPACE_HLG_P3
@ DT_COLORSPACE_PQ_P3
@ DT_COLORSPACE_PQ_REC2020
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
@ DT_COLORSPACE_HLG_REC2020
@ DT_COLORSPACE_ENHANCED_MATRIX
@ DT_COLORSPACE_LIN_REC2020
@ DT_COLORSPACE_DISPLAY_P3
@ DT_COLORSPACE_STANDARD_MATRIX
@ DT_COLORSPACE_XYZ
@ DT_COLORSPACE_VENDOR_MATRIX
@ DT_COLORSPACE_LIN_REC709
@ DT_COLORSPACE_ALTERNATE_MATRIX
@ DT_PROFILE_ROLE_OUTPUT
Listed in the output/export-profile combo (colorout, export).
@ DT_PROFILE_ROLE_INPUT
Listed in the input-profile combo (colorin).
@ DT_PROFILE_ROLE_MONITOR
Eligible for the monitor-profile menu.
@ DT_CICP_TRANSFER_CHARACTERISTICS_UNSPECIFIED
@ DT_CICP_TRANSFER_CHARACTERISTICS_LINEAR
@ DT_CICP_TRANSFER_CHARACTERISTICS_HLG
@ DT_CICP_TRANSFER_CHARACTERISTICS_REC2020_12B
@ DT_CICP_TRANSFER_CHARACTERISTICS_REC709
@ DT_CICP_TRANSFER_CHARACTERISTICS_PQ
@ DT_CICP_TRANSFER_CHARACTERISTICS_REC2020_10B
@ DT_CICP_TRANSFER_CHARACTERISTICS_REC601
@ DT_CICP_TRANSFER_CHARACTERISTICS_SRGB
@ DT_CICP_COLOR_PRIMARIES_REC2020
@ DT_CICP_COLOR_PRIMARIES_UNSPECIFIED
@ DT_CICP_COLOR_PRIMARIES_P3
@ DT_CICP_COLOR_PRIMARIES_REC709
@ DT_CICP_COLOR_PRIMARIES_XYZ
@ DT_CICP_MATRIX_COEFFICIENTS_REC601
@ DT_CICP_MATRIX_COEFFICIENTS_REC2020_NCL
@ DT_CICP_MATRIX_COEFFICIENTS_UNSPECIFIED
@ DT_CICP_MATRIX_COEFFICIENTS_IDENTITY
@ DT_CICP_MATRIX_COEFFICIENTS_SYCC
@ DT_CICP_MATRIX_COEFFICIENTS_REC709
@ DT_CICP_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL
The three ITU-T H.273 code points that describe a colour space without an ICC profile.
One registered profile: its identity, its LCMS handle, and where it sits in each combo box.
cmsHPROFILE profile
the actual profile; NULL for the three category entries
char filename[DT_IOP_COLOR_ICC_LEN]
icc file name (absolute; compare with dt_colorspaces_is_profile_equal())
int32_t flags
Definition image.h:401
uint32_t profile_size
Definition image.h:423
float d65_color_matrix[9]
Definition image.h:421
dt_image_colorspace_t colorspace
Definition image.h:429
float adobe_XYZ_to_CAM[4][3]
Definition image.h:449
struct dt_colorspaces_color_profile_t * embedded_profile
Definition image.h:428
uint8_t * profile
Definition image.h:422