app: s/sprintf/g_snprintf/ in xcf_save_image()
[gimp.git] / libgimpcolor / gimpcolorprofile.c
blob9d64e8f1ddcdb16ce6881d7aa63f7146858e0f7f
1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
4 * gimpcolorprofile.c
5 * Copyright (C) 2014 Michael Natterer <mitch@gimp.org>
6 * Elle Stone <ellestone@ninedegreesbelow.com>
7 * Øyvind Kolås <pippin@gimp.org>
9 * This library is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 3 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library. If not, see
21 * <https://www.gnu.org/licenses/>.
24 #include "config.h"
26 #include <string.h>
28 #include <lcms2.h>
30 #include <gio/gio.h>
31 #include <gegl.h>
33 #include "libgimpbase/gimpbase.h"
35 #include "gimpcolortypes.h"
37 #include "gimpcolorprofile.h"
39 #include "libgimp/libgimp-intl.h"
42 #ifndef TYPE_RGBA_DBL
43 #define TYPE_RGBA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(0))
44 #endif
46 #ifndef TYPE_GRAYA_HALF_FLT
47 #define TYPE_GRAYA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2))
48 #endif
50 #ifndef TYPE_GRAYA_FLT
51 #define TYPE_GRAYA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(4))
52 #endif
54 #ifndef TYPE_GRAYA_DBL
55 #define TYPE_GRAYA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(0))
56 #endif
58 #ifndef TYPE_CMYKA_DBL
59 #define TYPE_CMYKA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(0))
60 #endif
62 #ifndef TYPE_CMYKA_HALF_FLT
63 #define TYPE_CMYKA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(2))
64 #endif
66 #ifndef TYPE_CMYKA_FLT
67 #define TYPE_CMYKA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(4))
68 #endif
70 #ifndef TYPE_CMYKA_16
71 #define TYPE_CMYKA_16 (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(2))
72 #endif
75 /**
76 * SECTION: gimpcolorprofile
77 * @title: GimpColorProfile
78 * @short_description: Definitions and Functions relating to LCMS.
80 * Definitions and Functions relating to LCMS.
81 **/
83 /**
84 * GimpColorProfile:
86 * Simply a typedef to #gpointer, but actually is a cmsHPROFILE. It's
87 * used in public GIMP APIs in order to avoid having to include LCMS
88 * headers.
89 **/
92 struct _GimpColorProfilePrivate
94 cmsHPROFILE lcms_profile;
95 guint8 *data;
96 gsize length;
98 gchar *description;
99 gchar *manufacturer;
100 gchar *model;
101 gchar *copyright;
102 gchar *label;
103 gchar *summary;
107 static void gimp_color_profile_finalize (GObject *object);
110 G_DEFINE_TYPE (GimpColorProfile, gimp_color_profile,
111 G_TYPE_OBJECT);
113 #define parent_class gimp_color_profile_parent_class
116 #define GIMP_COLOR_PROFILE_ERROR gimp_color_profile_error_quark ()
118 static GQuark
119 gimp_color_profile_error_quark (void)
121 static GQuark quark = 0;
123 if (G_UNLIKELY (quark == 0))
124 quark = g_quark_from_static_string ("gimp-color-profile-error-quark");
126 return quark;
129 static void
130 gimp_color_profile_class_init (GimpColorProfileClass *klass)
132 GObjectClass *object_class = G_OBJECT_CLASS (klass);
134 object_class->finalize = gimp_color_profile_finalize;
136 g_type_class_add_private (klass, sizeof (GimpColorProfilePrivate));
139 static void
140 gimp_color_profile_init (GimpColorProfile *profile)
142 profile->priv = G_TYPE_INSTANCE_GET_PRIVATE (profile,
143 GIMP_TYPE_COLOR_PROFILE,
144 GimpColorProfilePrivate);
147 static void
148 gimp_color_profile_finalize (GObject *object)
150 GimpColorProfile *profile = GIMP_COLOR_PROFILE (object);
152 g_clear_pointer (&profile->priv->lcms_profile, cmsCloseProfile);
154 g_clear_pointer (&profile->priv->data, g_free);
155 profile->priv->length = 0;
157 g_clear_pointer (&profile->priv->description, g_free);
158 g_clear_pointer (&profile->priv->manufacturer, g_free);
159 g_clear_pointer (&profile->priv->model, g_free);
160 g_clear_pointer (&profile->priv->copyright, g_free);
161 g_clear_pointer (&profile->priv->label, g_free);
162 g_clear_pointer (&profile->priv->summary, g_free);
164 G_OBJECT_CLASS (parent_class)->finalize (object);
169 * gimp_color_profile_new_from_file:
170 * @file: a #GFile
171 * @error: return location for #GError
173 * This function opens an ICC color profile from @file.
175 * Return value: the #GimpColorProfile, or %NULL. On error, %NULL is
176 * returned and @error is set.
178 * Since: 2.10
180 GimpColorProfile *
181 gimp_color_profile_new_from_file (GFile *file,
182 GError **error)
184 GimpColorProfile *profile = NULL;
185 cmsHPROFILE lcms_profile = NULL;
186 guint8 *data = NULL;
187 gsize length = 0;
188 gchar *path;
190 g_return_val_if_fail (G_IS_FILE (file), NULL);
191 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
193 path = g_file_get_path (file);
195 if (path)
197 GMappedFile *mapped;
199 mapped = g_mapped_file_new (path, FALSE, error);
200 g_free (path);
202 if (! mapped)
203 return NULL;
205 length = g_mapped_file_get_length (mapped);
206 data = g_memdup (g_mapped_file_get_contents (mapped), length);
208 lcms_profile = cmsOpenProfileFromMem (data, length);
210 g_mapped_file_unref (mapped);
212 else
214 GFileInfo *info;
216 info = g_file_query_info (file,
217 G_FILE_ATTRIBUTE_STANDARD_SIZE,
218 G_FILE_QUERY_INFO_NONE,
219 NULL, error);
220 if (info)
222 GInputStream *input;
224 length = g_file_info_get_size (info);
225 data = g_malloc (length);
227 g_object_unref (info);
229 input = G_INPUT_STREAM (g_file_read (file, NULL, error));
231 if (input)
233 gsize bytes_read;
235 if (g_input_stream_read_all (input, data, length,
236 &bytes_read, NULL, error) &&
237 bytes_read == length)
239 lcms_profile = cmsOpenProfileFromMem (data, length);
242 g_object_unref (input);
247 if (lcms_profile)
249 profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL);
251 profile->priv->lcms_profile = lcms_profile;
252 profile->priv->data = data;
253 profile->priv->length = length;
255 else
257 if (data)
258 g_free (data);
260 if (error && *error == NULL)
262 g_set_error (error, GIMP_COLOR_PROFILE_ERROR, 0,
263 _("'%s' does not appear to be an ICC color profile"),
264 gimp_file_get_utf8_name (file));
268 return profile;
272 * gimp_color_profile_new_from_icc_profile:
273 * @data: pointer to memory containing an ICC profile
274 * @length: length of the profile in memory, in bytes
275 * @error: return location for #GError
277 * This function opens an ICC color profile from memory. On error,
278 * %NULL is returned and @error is set.
280 * Return value: the #GimpColorProfile, or %NULL.
282 * Since: 2.10
284 GimpColorProfile *
285 gimp_color_profile_new_from_icc_profile (const guint8 *data,
286 gsize length,
287 GError **error)
289 cmsHPROFILE lcms_profile = 0;
290 GimpColorProfile *profile = NULL;
292 g_return_val_if_fail (data != NULL || length == 0, NULL);
293 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
295 if (length > 0)
296 lcms_profile = cmsOpenProfileFromMem (data, length);
298 if (lcms_profile)
300 profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL);
302 profile->priv->lcms_profile = lcms_profile;
303 profile->priv->data = g_memdup (data, length);
304 profile->priv->length = length;
306 else
308 g_set_error_literal (error, GIMP_COLOR_PROFILE_ERROR, 0,
309 _("Data does not appear to be an ICC color profile"));
312 return profile;
316 * gimp_color_profile_new_from_lcms_profile:
317 * @lcms_profile: an LCMS cmsHPROFILE pointer
318 * @error: return location for #GError
320 * This function creates a GimpColorProfile from a cmsHPROFILE. On
321 * error, %NULL is returned and @error is set. The passed
322 * @lcms_profile pointer is not retained by the created
323 * #GimpColorProfile.
325 * Return value: the #GimpColorProfile, or %NULL.
327 * Since: 2.10
329 GimpColorProfile *
330 gimp_color_profile_new_from_lcms_profile (gpointer lcms_profile,
331 GError **error)
333 cmsUInt32Number size;
335 g_return_val_if_fail (lcms_profile != NULL, NULL);
336 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
338 if (cmsSaveProfileToMem (lcms_profile, NULL, &size))
340 guint8 *data = g_malloc (size);
342 if (cmsSaveProfileToMem (lcms_profile, data, &size))
344 gsize length = size;
346 lcms_profile = cmsOpenProfileFromMem (data, length);
348 if (lcms_profile)
350 GimpColorProfile *profile;
352 profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL);
354 profile->priv->lcms_profile = lcms_profile;
355 profile->priv->data = data;
356 profile->priv->length = length;
358 return profile;
362 g_free (data);
365 g_set_error_literal (error, GIMP_COLOR_PROFILE_ERROR, 0,
366 _("Could not save color profile to memory"));
368 return NULL;
372 * gimp_color_profile_save_to_file:
373 * @profile: a #GimpColorProfile
374 * @file: a #GFile
375 * @error: return location for #GError
377 * This function saves @profile to @file as ICC profile.
379 * Return value: %TRUE on success, %FALSE if an error occurred.
381 * Since: 2.10
383 gboolean
384 gimp_color_profile_save_to_file (GimpColorProfile *profile,
385 GFile *file,
386 GError **error)
388 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
389 g_return_val_if_fail (G_IS_FILE (file), FALSE);
390 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
392 return g_file_replace_contents (file,
393 (const gchar *) profile->priv->data,
394 profile->priv->length,
395 NULL, FALSE,
396 G_FILE_CREATE_NONE,
397 NULL,
398 NULL,
399 error);
403 * gimp_color_profile_get_icc_profile:
404 * @profile: a #GimpColorProfile
405 * @length: return location for the number of bytes
407 * This function returns @profile as ICC profile data. The returned
408 * memory belongs to @profile and must not be modified or freed.
410 * Return value: a pointer to the IIC profile data.
412 * Since: 2.10
414 const guint8 *
415 gimp_color_profile_get_icc_profile (GimpColorProfile *profile,
416 gsize *length)
418 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
419 g_return_val_if_fail (length != NULL, NULL);
421 *length = profile->priv->length;
423 return profile->priv->data;
427 * gimp_color_profile_get_lcms_profile:
428 * @profile: a #GimpColorProfile
430 * This function returns @profile's cmsHPROFILE. The returned
431 * value belongs to @profile and must not be modified or freed.
433 * Return value: a pointer to the cmsHPROFILE.
435 * Since: 2.10
437 gpointer
438 gimp_color_profile_get_lcms_profile (GimpColorProfile *profile)
440 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
442 return profile->priv->lcms_profile;
445 static gchar *
446 gimp_color_profile_get_info (GimpColorProfile *profile,
447 cmsInfoType info)
449 cmsUInt32Number size;
450 gchar *text = NULL;
452 size = cmsGetProfileInfoASCII (profile->priv->lcms_profile, info,
453 "en", "US", NULL, 0);
454 if (size > 0)
456 gchar *data = g_new (gchar, size + 1);
458 size = cmsGetProfileInfoASCII (profile->priv->lcms_profile, info,
459 "en", "US", data, size);
460 if (size > 0)
461 text = gimp_any_to_utf8 (data, -1, NULL);
463 g_free (data);
466 return text;
470 * gimp_color_profile_get_description:
471 * @profile: a #GimpColorProfile
473 * Return value: a string containing @profile's description. The
474 * returned value belongs to @profile and must not be
475 * modified or freed.
477 * Since: 2.10
479 const gchar *
480 gimp_color_profile_get_description (GimpColorProfile *profile)
482 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
484 if (! profile->priv->description)
485 profile->priv->description =
486 gimp_color_profile_get_info (profile, cmsInfoDescription);
488 return profile->priv->description;
492 * gimp_color_profile_get_manufacturer:
493 * @profile: a #GimpColorProfile
495 * Return value: a string containing @profile's manufacturer. The
496 * returned value belongs to @profile and must not be
497 * modified or freed.
499 * Since: 2.10
501 const gchar *
502 gimp_color_profile_get_manufacturer (GimpColorProfile *profile)
504 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
506 if (! profile->priv->manufacturer)
507 profile->priv->manufacturer =
508 gimp_color_profile_get_info (profile, cmsInfoManufacturer);
510 return profile->priv->manufacturer;
514 * gimp_color_profile_get_model:
515 * @profile: a #GimpColorProfile
517 * Return value: a string containing @profile's model. The returned
518 * value belongs to @profile and must not be modified or
519 * freed.
521 * Since: 2.10
523 const gchar *
524 gimp_color_profile_get_model (GimpColorProfile *profile)
526 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
528 if (! profile->priv->model)
529 profile->priv->model =
530 gimp_color_profile_get_info (profile, cmsInfoModel);
532 return profile->priv->model;
536 * gimp_color_profile_get_copyright:
537 * @profile: a #GimpColorProfile
539 * Return value: a string containing @profile's copyright. The
540 * returned value belongs to @profile and must not be
541 * modified or freed.
543 * Since: 2.10
545 const gchar *
546 gimp_color_profile_get_copyright (GimpColorProfile *profile)
548 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
550 if (! profile->priv->copyright)
551 profile->priv->copyright =
552 gimp_color_profile_get_info (profile, cmsInfoCopyright);
554 return profile->priv->copyright;
558 * gimp_color_profile_get_label:
559 * @profile: a #GimpColorProfile
561 * This function returns a string containing @profile's "title", a
562 * string that can be used to label the profile in a user interface.
564 * Unlike gimp_color_profile_get_description(), this function always
565 * returns a string (as a fallback, it returns "(unnamed profile)").
567 * Return value: the @profile's label. The returned value belongs to
568 * @profile and must not be modified or freed.
570 * Since: 2.10
572 const gchar *
573 gimp_color_profile_get_label (GimpColorProfile *profile)
576 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
578 if (! profile->priv->label)
580 const gchar *label = gimp_color_profile_get_description (profile);
582 if (! label || ! strlen (label))
583 label = _("(unnamed profile)");
585 profile->priv->label = g_strdup (label);
588 return profile->priv->label;
592 * gimp_color_profile_get_summary:
593 * @profile: a #GimpColorProfile
595 * This function return a string containing a multi-line summary of
596 * @profile's description, model, manufacturer and copyright, to be
597 * used as detailed information about the profile in a user
598 * interface.
600 * Return value: the @profile's summary. The returned value belongs to
601 * @profile and must not be modified or freed.
603 * Since: 2.10
605 const gchar *
606 gimp_color_profile_get_summary (GimpColorProfile *profile)
608 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
610 if (! profile->priv->summary)
612 GString *string = g_string_new (NULL);
613 const gchar *text;
615 text = gimp_color_profile_get_description (profile);
616 if (text)
617 g_string_append (string, text);
619 text = gimp_color_profile_get_model (profile);
620 if (text)
622 if (string->len > 0)
623 g_string_append (string, "\n");
625 g_string_append_printf (string, _("Model: %s"), text);
628 text = gimp_color_profile_get_manufacturer (profile);
629 if (text)
631 if (string->len > 0)
632 g_string_append (string, "\n");
634 g_string_append_printf (string, _("Manufacturer: %s"), text);
637 text = gimp_color_profile_get_copyright (profile);
638 if (text)
640 if (string->len > 0)
641 g_string_append (string, "\n");
643 g_string_append_printf (string, _("Copyright: %s"), text);
646 profile->priv->summary = g_string_free (string, FALSE);
649 return profile->priv->summary;
653 * gimp_color_profile_is_equal:
654 * @profile1: a #GimpColorProfile
655 * @profile2: a #GimpColorProfile
657 * Compares two profiles.
659 * Return value: %TRUE if the profiles are equal, %FALSE otherwise.
661 * Since: 2.10
663 gboolean
664 gimp_color_profile_is_equal (GimpColorProfile *profile1,
665 GimpColorProfile *profile2)
667 const gsize header_len = sizeof (cmsICCHeader);
669 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile1), FALSE);
670 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile2), FALSE);
672 return profile1 == profile2 ||
673 (profile1->priv->length == profile2->priv->length &&
674 memcmp (profile1->priv->data + header_len,
675 profile2->priv->data + header_len,
676 profile1->priv->length - header_len) == 0);
680 * gimp_color_profile_is_rgb:
681 * @profile: a #GimpColorProfile
683 * Return value: %TRUE if the profile's color space is RGB, %FALSE
684 * otherwise.
686 * Since: 2.10
688 gboolean
689 gimp_color_profile_is_rgb (GimpColorProfile *profile)
691 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
693 return (cmsGetColorSpace (profile->priv->lcms_profile) == cmsSigRgbData);
697 * gimp_color_profile_is_gray:
698 * @profile: a #GimpColorProfile
700 * Return value: %TRUE if the profile's color space is grayscale, %FALSE
701 * otherwise.
703 * Since: 2.10
705 gboolean
706 gimp_color_profile_is_gray (GimpColorProfile *profile)
708 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
710 return (cmsGetColorSpace (profile->priv->lcms_profile) == cmsSigGrayData);
714 * gimp_color_profile_is_cmyk:
715 * @profile: a #GimpColorProfile
717 * Return value: %TRUE if the profile's color space is CMYK, %FALSE
718 * otherwise.
720 * Since: 2.10
722 gboolean
723 gimp_color_profile_is_cmyk (GimpColorProfile *profile)
725 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
727 return (cmsGetColorSpace (profile->priv->lcms_profile) == cmsSigCmykData);
732 * gimp_color_profile_is_linear:
733 * @profile: a #GimpColorProfile
735 * This function determines is the ICC profile represented by a GimpColorProfile
736 * is a linear RGB profile or not, some profiles that are LUTs though linear
737 * will also return FALSE;
739 * Return value: %TRUE if the profile is a matrix shaping profile with linear
740 * TRCs, %FALSE otherwise.
742 * Since: 2.10
744 gboolean
745 gimp_color_profile_is_linear (GimpColorProfile *profile)
747 cmsHPROFILE prof;
748 cmsToneCurve *curve;
750 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
752 prof = profile->priv->lcms_profile;
754 if (! cmsIsMatrixShaper (prof))
755 return FALSE;
757 if (cmsIsCLUT (prof, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT))
758 return FALSE;
760 if (cmsIsCLUT (prof, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT))
761 return FALSE;
763 if (gimp_color_profile_is_rgb (profile))
765 curve = cmsReadTag(prof, cmsSigRedTRCTag);
766 if (curve == NULL || ! cmsIsToneCurveLinear (curve))
767 return FALSE;
769 curve = cmsReadTag (prof, cmsSigGreenTRCTag);
770 if (curve == NULL || ! cmsIsToneCurveLinear (curve))
771 return FALSE;
773 curve = cmsReadTag (prof, cmsSigBlueTRCTag);
774 if (curve == NULL || ! cmsIsToneCurveLinear (curve))
775 return FALSE;
777 else if (gimp_color_profile_is_gray (profile))
779 curve = cmsReadTag(prof, cmsSigGrayTRCTag);
780 if (curve == NULL || ! cmsIsToneCurveLinear (curve))
781 return FALSE;
783 else
785 return FALSE;
788 return TRUE;
791 static void
792 gimp_color_profile_set_tag (cmsHPROFILE profile,
793 cmsTagSignature sig,
794 const gchar *tag)
796 cmsMLU *mlu;
798 mlu = cmsMLUalloc (NULL, 1);
799 cmsMLUsetASCII (mlu, "en", "US", tag);
800 cmsWriteTag (profile, sig, mlu);
801 cmsMLUfree (mlu);
804 static gboolean
805 gimp_color_profile_get_rgb_matrix_colorants (GimpColorProfile *profile,
806 GimpMatrix3 *matrix)
808 cmsHPROFILE lcms_profile;
809 cmsCIEXYZ *red;
810 cmsCIEXYZ *green;
811 cmsCIEXYZ *blue;
813 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
815 lcms_profile = profile->priv->lcms_profile;
817 red = cmsReadTag (lcms_profile, cmsSigRedColorantTag);
818 green = cmsReadTag (lcms_profile, cmsSigGreenColorantTag);
819 blue = cmsReadTag (lcms_profile, cmsSigBlueColorantTag);
821 if (red && green && blue)
823 if (matrix)
825 matrix->coeff[0][0] = red->X;
826 matrix->coeff[0][1] = red->Y;
827 matrix->coeff[0][2] = red->Z;
829 matrix->coeff[1][0] = green->X;
830 matrix->coeff[1][1] = green->Y;
831 matrix->coeff[1][2] = green->Z;
833 matrix->coeff[2][0] = blue->X;
834 matrix->coeff[2][1] = blue->Y;
835 matrix->coeff[2][2] = blue->Z;
838 return TRUE;
841 return FALSE;
844 static GimpColorProfile *
845 gimp_color_profile_new_from_color_profile (GimpColorProfile *profile,
846 gboolean linear)
848 GimpColorProfile *new_profile;
849 cmsHPROFILE target_profile;
850 GimpMatrix3 matrix = { { { 0, } } };
851 cmsCIEXYZ *whitepoint;
852 cmsToneCurve *curve;
853 const gchar *model;
854 gchar *new_model;
856 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
858 if (gimp_color_profile_is_rgb (profile))
860 if (! gimp_color_profile_get_rgb_matrix_colorants (profile, &matrix))
861 return NULL;
863 else if (! gimp_color_profile_is_gray (profile))
865 return NULL;
868 whitepoint = cmsReadTag (profile->priv->lcms_profile,
869 cmsSigMediaWhitePointTag);
871 target_profile = cmsCreateProfilePlaceholder (0);
873 cmsSetProfileVersion (target_profile, 4.3);
874 cmsSetDeviceClass (target_profile, cmsSigDisplayClass);
875 cmsSetPCS (target_profile, cmsSigXYZData);
877 cmsWriteTag (target_profile, cmsSigMediaWhitePointTag, whitepoint);
879 if (linear)
881 /* linear light */
882 curve = cmsBuildGamma (NULL, 1.00);
884 gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag,
885 "linear TRC variant generated by GIMP");
887 else
889 cmsFloat64Number srgb_parameters[5] =
890 { 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 };
892 /* sRGB curve */
893 curve = cmsBuildParametricToneCurve (NULL, 4, srgb_parameters);
895 gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag,
896 "sRGB TRC variant generated by GIMP");
899 if (gimp_color_profile_is_rgb (profile))
901 cmsCIEXYZ red;
902 cmsCIEXYZ green;
903 cmsCIEXYZ blue;
905 cmsSetColorSpace (target_profile, cmsSigRgbData);
907 red.X = matrix.coeff[0][0];
908 red.Y = matrix.coeff[0][1];
909 red.Z = matrix.coeff[0][2];
911 green.X = matrix.coeff[1][0];
912 green.Y = matrix.coeff[1][1];
913 green.Z = matrix.coeff[1][2];
915 blue.X = matrix.coeff[2][0];
916 blue.Y = matrix.coeff[2][1];
917 blue.Z = matrix.coeff[2][2];
919 cmsWriteTag (target_profile, cmsSigRedColorantTag, &red);
920 cmsWriteTag (target_profile, cmsSigGreenColorantTag, &green);
921 cmsWriteTag (target_profile, cmsSigBlueColorantTag, &blue);
923 cmsWriteTag (target_profile, cmsSigRedTRCTag, curve);
924 cmsWriteTag (target_profile, cmsSigGreenTRCTag, curve);
925 cmsWriteTag (target_profile, cmsSigBlueTRCTag, curve);
927 else
929 cmsSetColorSpace (target_profile, cmsSigGrayData);
931 cmsWriteTag (target_profile, cmsSigGrayTRCTag, curve);
934 cmsFreeToneCurve (curve);
936 model = gimp_color_profile_get_model (profile);
938 if (model && g_str_has_prefix (model, "Generated from '"))
940 /* don't add multiple "Generated from 'foo'" */
941 new_model = g_strdup (model);
943 else
945 new_model = g_strdup_printf ("Generated from '%s'",
946 gimp_color_profile_get_description (profile));
949 gimp_color_profile_set_tag (target_profile, cmsSigDeviceMfgDescTag,
950 "GIMP");
951 gimp_color_profile_set_tag (target_profile, cmsSigDeviceModelDescTag,
952 new_model);
953 gimp_color_profile_set_tag (target_profile, cmsSigCopyrightTag,
954 "Public Domain");
956 g_free (new_model);
958 new_profile = gimp_color_profile_new_from_lcms_profile (target_profile, NULL);
960 cmsCloseProfile (target_profile);
962 return new_profile;
966 * gimp_color_profile_new_srgb_trc_from_color_profile:
967 * @profile: a #GimpColorProfile
969 * This function creates a new RGB #GimpColorProfile with a sRGB gamma
970 * TRC and @profile's RGB chromacities and whitepoint.
972 * Return value: the new #GimpColorProfile, or %NULL if @profile is not
973 * an RGB profile or not matrix-based.
975 * Since: 2.10
977 GimpColorProfile *
978 gimp_color_profile_new_srgb_trc_from_color_profile (GimpColorProfile *profile)
980 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
982 return gimp_color_profile_new_from_color_profile (profile, FALSE);
986 * gimp_color_profile_new_linear_from_color_profile:
987 * @profile: a #GimpColorProfile
989 * This function creates a new RGB #GimpColorProfile with a linear TRC
990 * and @profile's RGB chromacities and whitepoint.
992 * Return value: the new #GimpColorProfile, or %NULL if @profile is not
993 * an RGB profile or not matrix-based.
995 * Since: 2.10
997 GimpColorProfile *
998 gimp_color_profile_new_linear_from_color_profile (GimpColorProfile *profile)
1000 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
1002 return gimp_color_profile_new_from_color_profile (profile, TRUE);
1005 static cmsHPROFILE *
1006 gimp_color_profile_new_rgb_srgb_internal (void)
1008 cmsHPROFILE profile;
1010 /* white point is D65 from the sRGB specs */
1011 cmsCIExyY whitepoint = { 0.3127, 0.3290, 1.0 };
1013 /* primaries are ITU‐R BT.709‐5 (xYY), which are also the primaries
1014 * from the sRGB specs, modified to properly account for hexadecimal
1015 * quantization during the profile making process.
1017 cmsCIExyYTRIPLE primaries =
1019 /* R { 0.6400, 0.3300, 1.0 }, */
1020 /* G { 0.3000, 0.6000, 1.0 }, */
1021 /* B { 0.1500, 0.0600, 1.0 } */
1022 /* R */ { 0.639998686, 0.330010138, 1.0 },
1023 /* G */ { 0.300003784, 0.600003357, 1.0 },
1024 /* B */ { 0.150002046, 0.059997204, 1.0 }
1027 cmsFloat64Number srgb_parameters[5] =
1028 { 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 };
1030 cmsToneCurve *curve[3];
1032 /* sRGB curve */
1033 curve[0] = curve[1] = curve[2] = cmsBuildParametricToneCurve (NULL, 4,
1034 srgb_parameters);
1036 profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
1038 cmsFreeToneCurve (curve[0]);
1040 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1041 "GIMP built-in sRGB");
1042 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1043 "GIMP");
1044 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1045 "sRGB");
1046 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1047 "Public Domain");
1049 /* The following line produces a V2 profile with a point curve TRC.
1050 * Profiles with point curve TRCs can't be used in LCMS2 unbounded
1051 * mode ICC profile conversions. A V2 profile might be appropriate
1052 * for embedding in sRGB images saved to disk, if the image is to be
1053 * opened by an image editing application that doesn't understand V4
1054 * profiles.
1056 * cmsSetProfileVersion (srgb_profile, 2.1);
1059 return profile;
1063 * gimp_color_profile_new_rgb_srgb:
1065 * This function is a replacement for cmsCreate_sRGBProfile() and
1066 * returns an sRGB profile that is functionally the same as the
1067 * ArgyllCMS sRGB.icm profile. "Functionally the same" means it has
1068 * the same red, green, and blue colorants and the V4 "chad"
1069 * equivalent of the ArgyllCMS V2 white point. The profile TRC is also
1070 * functionally equivalent to the ArgyllCMS sRGB.icm TRC and is the
1071 * same as the LCMS sRGB built-in profile TRC.
1073 * The actual primaries in the sRGB specification are
1074 * red xy: {0.6400, 0.3300, 1.0}
1075 * green xy: {0.3000, 0.6000, 1.0}
1076 * blue xy: {0.1500, 0.0600, 1.0}
1078 * The sRGB primaries given below are "pre-quantized" to compensate
1079 * for hexadecimal quantization during the profile-making process.
1080 * Unless the profile-making code compensates for this quantization,
1081 * the resulting profile's red, green, and blue colorants will deviate
1082 * slightly from the correct XYZ values.
1084 * LCMS2 doesn't compensate for hexadecimal quantization. The
1085 * "pre-quantized" primaries below were back-calculated from the
1086 * ArgyllCMS sRGB.icm profile. The resulting sRGB profile's colorants
1087 * exactly matches the ArgyllCMS sRGB.icm profile colorants.
1089 * Return value: the sRGB #GimpColorProfile.
1091 * Since: 2.10
1093 GimpColorProfile *
1094 gimp_color_profile_new_rgb_srgb (void)
1096 static GimpColorProfile *profile = NULL;
1098 const guint8 *data;
1099 gsize length;
1101 if (G_UNLIKELY (profile == NULL))
1103 cmsHPROFILE lcms_profile = gimp_color_profile_new_rgb_srgb_internal ();
1105 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1107 cmsCloseProfile (lcms_profile);
1110 data = gimp_color_profile_get_icc_profile (profile, &length);
1112 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1115 static cmsHPROFILE
1116 gimp_color_profile_new_rgb_srgb_linear_internal (void)
1118 cmsHPROFILE profile;
1120 /* white point is D65 from the sRGB specs */
1121 cmsCIExyY whitepoint = { 0.3127, 0.3290, 1.0 };
1123 /* primaries are ITU‐R BT.709‐5 (xYY), which are also the primaries
1124 * from the sRGB specs, modified to properly account for hexadecimal
1125 * quantization during the profile making process.
1127 cmsCIExyYTRIPLE primaries =
1129 /* R { 0.6400, 0.3300, 1.0 }, */
1130 /* G { 0.3000, 0.6000, 1.0 }, */
1131 /* B { 0.1500, 0.0600, 1.0 } */
1132 /* R */ { 0.639998686, 0.330010138, 1.0 },
1133 /* G */ { 0.300003784, 0.600003357, 1.0 },
1134 /* B */ { 0.150002046, 0.059997204, 1.0 }
1137 cmsToneCurve *curve[3];
1139 /* linear light */
1140 curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 1.0);
1142 profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
1144 cmsFreeToneCurve (curve[0]);
1146 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1147 "GIMP built-in Linear sRGB");
1148 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1149 "GIMP");
1150 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1151 "Linear sRGB");
1152 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1153 "Public Domain");
1155 return profile;
1159 * gimp_color_profile_new_rgb_srgb_linear:
1161 * This function creates a profile for babl_model("RGB"). Please
1162 * somebody write something smarter here.
1164 * Return value: the linear RGB #GimpColorProfile.
1166 * Since: 2.10
1168 GimpColorProfile *
1169 gimp_color_profile_new_rgb_srgb_linear (void)
1171 static GimpColorProfile *profile = NULL;
1173 const guint8 *data;
1174 gsize length;
1176 if (G_UNLIKELY (profile == NULL))
1178 cmsHPROFILE lcms_profile = gimp_color_profile_new_rgb_srgb_linear_internal ();
1180 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1182 cmsCloseProfile (lcms_profile);
1185 data = gimp_color_profile_get_icc_profile (profile, &length);
1187 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1190 static cmsHPROFILE *
1191 gimp_color_profile_new_rgb_adobe_internal (void)
1193 cmsHPROFILE profile;
1195 /* white point is D65 from the sRGB specs */
1196 cmsCIExyY whitepoint = { 0.3127, 0.3290, 1.0 };
1198 /* AdobeRGB1998 and sRGB have the same white point.
1200 * The primaries below are technically correct, but because of
1201 * hexadecimal rounding these primaries don't make a profile that
1202 * matches the original.
1204 * cmsCIExyYTRIPLE primaries = {
1205 * { 0.6400, 0.3300, 1.0 },
1206 * { 0.2100, 0.7100, 1.0 },
1207 * { 0.1500, 0.0600, 1.0 }
1208 * };
1210 cmsCIExyYTRIPLE primaries =
1212 { 0.639996511, 0.329996864, 1.0 },
1213 { 0.210005295, 0.710004866, 1.0 },
1214 { 0.149997606, 0.060003644, 1.0 }
1217 cmsToneCurve *curve[3];
1219 /* gamma 2.2 */
1220 curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 2.19921875);
1222 profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
1224 cmsFreeToneCurve (curve[0]);
1226 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1227 "Compatible with Adobe RGB (1998)");
1228 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1229 "GIMP");
1230 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1231 "Compatible with Adobe RGB (1998)");
1232 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1233 "Public Domain");
1235 return profile;
1239 * gimp_color_profile_new_rgb_adobe:
1241 * This function creates a profile compatible with AbobeRGB (1998).
1243 * Return value: the AdobeRGB-compatible #GimpColorProfile.
1245 * Since: 2.10
1247 GimpColorProfile *
1248 gimp_color_profile_new_rgb_adobe (void)
1250 static GimpColorProfile *profile = NULL;
1252 const guint8 *data;
1253 gsize length;
1255 if (G_UNLIKELY (profile == NULL))
1257 cmsHPROFILE lcms_profile = gimp_color_profile_new_rgb_adobe_internal ();
1259 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1261 cmsCloseProfile (lcms_profile);
1264 data = gimp_color_profile_get_icc_profile (profile, &length);
1266 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1269 static cmsHPROFILE *
1270 gimp_color_profile_new_d65_gray_srgb_trc_internal (void)
1272 cmsHPROFILE profile;
1274 /* white point is D65 from the sRGB specs */
1275 cmsCIExyY whitepoint = { 0.3127, 0.3290, 1.0 };
1277 cmsFloat64Number srgb_parameters[5] =
1278 { 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 };
1280 cmsToneCurve *curve = cmsBuildParametricToneCurve (NULL, 4,
1281 srgb_parameters);
1283 profile = cmsCreateGrayProfile (&whitepoint, curve);
1285 cmsFreeToneCurve (curve);
1287 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1288 "GIMP built-in D65 Grayscale with sRGB TRC");
1289 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1290 "GIMP");
1291 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1292 "D65 Grayscale with sRGB TRC");
1293 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1294 "Public Domain");
1296 return profile;
1300 * gimp_color_profile_new_d65_gray_srgb_trc
1302 * This function creates a grayscale #GimpColorProfile with an
1303 * sRGB TRC. See gimp_color_profile_new_rgb_srgb().
1305 * Return value: the sRGB-gamma grayscale #GimpColorProfile.
1307 * Since: 2.10
1309 GimpColorProfile *
1310 gimp_color_profile_new_d65_gray_srgb_trc (void)
1312 static GimpColorProfile *profile = NULL;
1314 const guint8 *data;
1315 gsize length;
1317 if (G_UNLIKELY (profile == NULL))
1319 cmsHPROFILE lcms_profile = gimp_color_profile_new_d65_gray_srgb_trc_internal ();
1321 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1323 cmsCloseProfile (lcms_profile);
1326 data = gimp_color_profile_get_icc_profile (profile, &length);
1328 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1331 static cmsHPROFILE
1332 gimp_color_profile_new_d65_gray_linear_internal (void)
1334 cmsHPROFILE profile;
1336 /* white point is D65 from the sRGB specs */
1337 cmsCIExyY whitepoint = { 0.3127, 0.3290, 1.0 };
1339 cmsToneCurve *curve = cmsBuildGamma (NULL, 1.0);
1341 profile = cmsCreateGrayProfile (&whitepoint, curve);
1343 cmsFreeToneCurve (curve);
1345 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1346 "GIMP built-in D65 Linear Grayscale");
1347 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1348 "GIMP");
1349 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1350 "D65 Linear Grayscale");
1351 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1352 "Public Domain");
1354 return profile;
1358 * gimp_color_profile_new_d65_gray_srgb_gray:
1360 * This function creates a profile for babl_model("Y"). Please
1361 * somebody write something smarter here.
1363 * Return value: the linear grayscale #GimpColorProfile.
1365 * Since: 2.10
1367 GimpColorProfile *
1368 gimp_color_profile_new_d65_gray_linear (void)
1370 static GimpColorProfile *profile = NULL;
1372 const guint8 *data;
1373 gsize length;
1375 if (G_UNLIKELY (profile == NULL))
1377 cmsHPROFILE lcms_profile = gimp_color_profile_new_d65_gray_linear_internal ();
1379 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1381 cmsCloseProfile (lcms_profile);
1384 data = gimp_color_profile_get_icc_profile (profile, &length);
1386 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1389 static cmsHPROFILE *
1390 gimp_color_profile_new_d50_gray_lab_trc_internal (void)
1392 cmsHPROFILE profile;
1394 /* white point is D50 from the ICC profile illuminant specs */
1395 cmsCIExyY whitepoint = {0.345702915, 0.358538597, 1.0};
1397 cmsFloat64Number lab_parameters[5] =
1398 { 3.0, 1.0 / 1.16, 0.16 / 1.16, 2700.0 / 24389.0, 0.08000 };
1400 cmsToneCurve *curve = cmsBuildParametricToneCurve (NULL, 4,
1401 lab_parameters);
1403 profile = cmsCreateGrayProfile (&whitepoint, curve);
1405 cmsFreeToneCurve (curve);
1407 gimp_color_profile_set_tag (profile, cmsSigProfileDescriptionTag,
1408 "GIMP built-in D50 Grayscale with LAB L TRC");
1409 gimp_color_profile_set_tag (profile, cmsSigDeviceMfgDescTag,
1410 "GIMP");
1411 gimp_color_profile_set_tag (profile, cmsSigDeviceModelDescTag,
1412 "D50 Grayscale with LAB L TRC");
1413 gimp_color_profile_set_tag (profile, cmsSigCopyrightTag,
1414 "Public Domain");
1416 return profile;
1421 * gimp_color_profile_new_d50_gray_lab_trc
1423 * This function creates a grayscale #GimpColorProfile with the
1424 * D50 ICC profile illuminant as the profile white point and the
1425 * LAB companding curve as the TRC.
1427 * Return value: a gray profile with the D50 ICC profile illuminant
1428 * as the profile white point and the LAB companding curve as the TRC.
1429 * as the TRC.
1431 * Since: 2.10
1433 GimpColorProfile *
1434 gimp_color_profile_new_d50_gray_lab_trc (void)
1436 static GimpColorProfile *profile = NULL;
1438 const guint8 *data;
1439 gsize length;
1441 if (G_UNLIKELY (profile == NULL))
1443 cmsHPROFILE lcms_profile = gimp_color_profile_new_d50_gray_lab_trc_internal ();
1445 profile = gimp_color_profile_new_from_lcms_profile (lcms_profile, NULL);
1447 cmsCloseProfile (lcms_profile);
1450 data = gimp_color_profile_get_icc_profile (profile, &length);
1452 return gimp_color_profile_new_from_icc_profile (data, length, NULL);
1456 * gimp_color_profile_get_space:
1457 * @profile: a #GimpColorProfile
1458 * @intent: a #GimpColorRenderingIntent
1459 * @error: return location for #GError
1461 * This function returns the #Babl space of @profile, for the
1462 * specified @intent.
1464 * Return value: the new #Babl space.
1466 * Since: 2.10.6
1468 const Babl *
1469 gimp_color_profile_get_space (GimpColorProfile *profile,
1470 GimpColorRenderingIntent intent,
1471 GError **error)
1473 const Babl *space;
1474 const gchar *babl_error = NULL;
1476 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
1477 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1479 space = babl_space_from_icc ((const gchar *) profile->priv->data,
1480 profile->priv->length,
1481 (BablIccIntent) intent,
1482 &babl_error);
1484 if (! space)
1485 g_set_error (error, GIMP_COLOR_PROFILE_ERROR, 0,
1486 "%s: %s",
1487 gimp_color_profile_get_label (profile), babl_error);
1489 return space;
1493 * gimp_color_profile_get_format:
1494 * @profile: a #GimpColorProfile
1495 * @format: a #Babl format
1496 * @intent: a #GimpColorRenderingIntent
1497 * @error: return location for #GError
1499 * This function takes a #GimpColorProfile and a #Babl format and
1500 * returns a new #Babl format with @profile's RGB primaries and TRC,
1501 * and @format's pixel layout.
1503 * Return value: the new #Babl format.
1505 * Since: 2.10
1507 const Babl *
1508 gimp_color_profile_get_format (GimpColorProfile *profile,
1509 const Babl *format,
1510 GimpColorRenderingIntent intent,
1511 GError **error)
1513 const Babl *space;
1515 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL);
1516 g_return_val_if_fail (format != NULL, NULL);
1517 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1519 space = gimp_color_profile_get_space (profile, intent, error);
1521 if (! space)
1522 return NULL;
1524 return babl_format_with_space (babl_format_get_encoding (format), space);
1528 * gimp_color_profile_get_lcms_format:
1529 * @format: a #Babl format
1530 * @lcms_format: return location for an lcms format
1532 * This function takes a #Babl format and returns the lcms format to
1533 * be used with that @format. It also returns a #Babl format to be
1534 * used instead of the passed @format, which usually is the same as
1535 * @format, unless lcms doesn't support @format.
1537 * Note that this function currently only supports RGB, RGBA, R'G'B',
1538 * R'G'B'A, Y, YA, Y', Y'A and the cairo-RGB24 and cairo-ARGB32 formats.
1540 * Return value: the #Babl format to be used instead of @format, or %NULL
1541 * if the passed @format is not supported at all.
1543 * Since: 2.10
1545 const Babl *
1546 gimp_color_profile_get_lcms_format (const Babl *format,
1547 guint32 *lcms_format)
1549 const Babl *output_format = NULL;
1550 const Babl *type;
1551 const Babl *model;
1552 gboolean has_alpha;
1553 gboolean rgb = FALSE;
1554 gboolean gray = FALSE;
1555 gboolean cmyk = FALSE;
1556 gboolean linear = FALSE;
1558 g_return_val_if_fail (format != NULL, NULL);
1559 g_return_val_if_fail (lcms_format != NULL, NULL);
1561 has_alpha = babl_format_has_alpha (format);
1562 type = babl_format_get_type (format, 0);
1563 model = babl_format_get_model (format);
1565 if (format == babl_format ("cairo-RGB24"))
1567 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1568 *lcms_format = TYPE_BGRA_8;
1569 #else
1570 *lcms_format = TYPE_ARGB_8;
1571 #endif
1573 return format;
1575 else if (format == babl_format ("cairo-ARGB32"))
1577 rgb = TRUE;
1579 else if (model == babl_model ("RGB") ||
1580 model == babl_model ("RGBA") ||
1581 model == babl_model ("RaGaBaA"))
1583 rgb = TRUE;
1584 linear = TRUE;
1586 else if (model == babl_model ("R'G'B'") ||
1587 model == babl_model ("R'G'B'A") ||
1588 model == babl_model ("R'aG'aB'aA"))
1590 rgb = TRUE;
1592 else if (model == babl_model ("Y") ||
1593 model == babl_model ("YA") ||
1594 model == babl_model ("YaA"))
1596 gray = TRUE;
1597 linear = TRUE;
1599 else if (model == babl_model ("Y'") ||
1600 model == babl_model ("Y'A") ||
1601 model == babl_model ("Y'aA"))
1603 gray = TRUE;
1605 else if (model == babl_model ("CMYK"))
1606 #if 0
1607 /* FIXME missing from babl */
1608 || model == babl_model ("CMYKA"))
1609 #endif
1611 cmyk = TRUE;
1613 else if (model == babl_model ("CIE Lab") ||
1614 model == babl_model ("CIE Lab alpha") ||
1615 model == babl_model ("CIE LCH(ab)") ||
1616 model == babl_model ("CIE LCH(ab) alpha"))
1618 if (has_alpha)
1620 *lcms_format = TYPE_RGBA_FLT;
1622 return babl_format ("RGBA float");
1624 else
1626 *lcms_format = TYPE_RGB_FLT;
1628 return babl_format ("RGB float");
1631 else if (babl_format_is_palette (format))
1633 if (has_alpha)
1635 *lcms_format = TYPE_RGBA_8;
1637 return babl_format ("R'G'B'A u8");
1639 else
1641 *lcms_format = TYPE_RGB_8;
1643 return babl_format ("R'G'B' u8");
1646 else
1648 g_printerr ("format: %s\n"
1649 "has_alpha = %s\n"
1650 "type = %s\n"
1651 "model = %s\n",
1652 babl_get_name (format),
1653 has_alpha ? "TRUE" : "FALSE",
1654 babl_get_name (type),
1655 babl_get_name (model));
1656 g_return_val_if_reached (NULL);
1659 *lcms_format = 0;
1661 #define FIND_FORMAT_FOR_TYPE(babl_t, lcms_t) \
1662 do \
1664 if (has_alpha) \
1666 if (rgb) \
1668 *lcms_format = TYPE_RGBA_##lcms_t; \
1670 if (linear) \
1671 output_format = babl_format ("RGBA " babl_t); \
1672 else \
1673 output_format = babl_format ("R'G'B'A " babl_t); \
1675 else if (gray) \
1677 *lcms_format = TYPE_GRAYA_##lcms_t; \
1679 if (linear) \
1680 output_format = babl_format ("YA " babl_t); \
1681 else \
1682 output_format = babl_format ("Y'A " babl_t); \
1684 else if (cmyk) \
1686 *lcms_format = TYPE_CMYKA_##lcms_t; \
1688 output_format = format; \
1691 else \
1693 if (rgb) \
1695 *lcms_format = TYPE_RGB_##lcms_t; \
1697 if (linear) \
1698 output_format = babl_format ("RGB " babl_t); \
1699 else \
1700 output_format = babl_format ("R'G'B' " babl_t); \
1702 else if (gray) \
1704 *lcms_format = TYPE_GRAY_##lcms_t; \
1706 if (linear) \
1707 output_format = babl_format ("Y " babl_t); \
1708 else \
1709 output_format = babl_format ("Y' " babl_t); \
1711 else if (cmyk) \
1713 *lcms_format = TYPE_CMYK_##lcms_t; \
1715 output_format = format; \
1719 while (FALSE)
1721 if (type == babl_type ("u8"))
1722 FIND_FORMAT_FOR_TYPE ("u8", 8);
1723 else if (type == babl_type ("u16"))
1724 FIND_FORMAT_FOR_TYPE ("u16", 16);
1725 else if (type == babl_type ("half")) /* 16-bit floating point (half) */
1726 FIND_FORMAT_FOR_TYPE ("half", HALF_FLT);
1727 else if (type == babl_type ("float"))
1728 FIND_FORMAT_FOR_TYPE ("float", FLT);
1729 else if (type == babl_type ("double"))
1730 FIND_FORMAT_FOR_TYPE ("double", DBL);
1732 if (*lcms_format == 0)
1734 g_printerr ("%s: format %s not supported, "
1735 "falling back to float\n",
1736 G_STRFUNC, babl_get_name (format));
1738 rgb = ! gray;
1740 FIND_FORMAT_FOR_TYPE ("float", FLT);
1742 g_return_val_if_fail (output_format != NULL, NULL);
1745 #undef FIND_FORMAT_FOR_TYPE
1747 return output_format;