1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
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/>.
33 #include "libgimpbase/gimpbase.h"
35 #include "gimpcolortypes.h"
37 #include "gimpcolorprofile.h"
39 #include "libgimp/libgimp-intl.h"
43 #define TYPE_RGBA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(0))
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))
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))
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))
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))
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))
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))
71 #define TYPE_CMYKA_16 (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(2))
76 * SECTION: gimpcolorprofile
77 * @title: GimpColorProfile
78 * @short_description: Definitions and Functions relating to LCMS.
80 * Definitions and Functions relating to LCMS.
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
92 struct _GimpColorProfilePrivate
94 cmsHPROFILE lcms_profile
;
107 static void gimp_color_profile_finalize (GObject
*object
);
110 G_DEFINE_TYPE (GimpColorProfile
, gimp_color_profile
,
113 #define parent_class gimp_color_profile_parent_class
116 #define GIMP_COLOR_PROFILE_ERROR gimp_color_profile_error_quark ()
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");
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
));
140 gimp_color_profile_init (GimpColorProfile
*profile
)
142 profile
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (profile
,
143 GIMP_TYPE_COLOR_PROFILE
,
144 GimpColorProfilePrivate
);
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:
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.
181 gimp_color_profile_new_from_file (GFile
*file
,
184 GimpColorProfile
*profile
= NULL
;
185 cmsHPROFILE lcms_profile
= NULL
;
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
);
199 mapped
= g_mapped_file_new (path
, FALSE
, error
);
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
);
216 info
= g_file_query_info (file
,
217 G_FILE_ATTRIBUTE_STANDARD_SIZE
,
218 G_FILE_QUERY_INFO_NONE
,
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
));
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
);
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
;
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
));
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.
285 gimp_color_profile_new_from_icc_profile (const guint8
*data
,
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
);
296 lcms_profile
= cmsOpenProfileFromMem (data
, length
);
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
;
308 g_set_error_literal (error
, GIMP_COLOR_PROFILE_ERROR
, 0,
309 _("Data does not appear to be an ICC color 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
325 * Return value: the #GimpColorProfile, or %NULL.
330 gimp_color_profile_new_from_lcms_profile (gpointer lcms_profile
,
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
))
346 lcms_profile
= cmsOpenProfileFromMem (data
, length
);
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
;
365 g_set_error_literal (error
, GIMP_COLOR_PROFILE_ERROR
, 0,
366 _("Could not save color profile to memory"));
372 * gimp_color_profile_save_to_file:
373 * @profile: a #GimpColorProfile
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.
384 gimp_color_profile_save_to_file (GimpColorProfile
*profile
,
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
,
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.
415 gimp_color_profile_get_icc_profile (GimpColorProfile
*profile
,
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.
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
;
446 gimp_color_profile_get_info (GimpColorProfile
*profile
,
449 cmsUInt32Number size
;
452 size
= cmsGetProfileInfoASCII (profile
->priv
->lcms_profile
, info
,
453 "en", "US", NULL
, 0);
456 gchar
*data
= g_new (gchar
, size
+ 1);
458 size
= cmsGetProfileInfoASCII (profile
->priv
->lcms_profile
, info
,
459 "en", "US", data
, size
);
461 text
= gimp_any_to_utf8 (data
, -1, NULL
);
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
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
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
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
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.
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
600 * Return value: the @profile's summary. The returned value belongs to
601 * @profile and must not be modified or freed.
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
);
615 text
= gimp_color_profile_get_description (profile
);
617 g_string_append (string
, text
);
619 text
= gimp_color_profile_get_model (profile
);
623 g_string_append (string
, "\n");
625 g_string_append_printf (string
, _("Model: %s"), text
);
628 text
= gimp_color_profile_get_manufacturer (profile
);
632 g_string_append (string
, "\n");
634 g_string_append_printf (string
, _("Manufacturer: %s"), text
);
637 text
= gimp_color_profile_get_copyright (profile
);
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.
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
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
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
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.
745 gimp_color_profile_is_linear (GimpColorProfile
*profile
)
750 g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile
), FALSE
);
752 prof
= profile
->priv
->lcms_profile
;
754 if (! cmsIsMatrixShaper (prof
))
757 if (cmsIsCLUT (prof
, INTENT_PERCEPTUAL
, LCMS_USED_AS_INPUT
))
760 if (cmsIsCLUT (prof
, INTENT_PERCEPTUAL
, LCMS_USED_AS_OUTPUT
))
763 if (gimp_color_profile_is_rgb (profile
))
765 curve
= cmsReadTag(prof
, cmsSigRedTRCTag
);
766 if (curve
== NULL
|| ! cmsIsToneCurveLinear (curve
))
769 curve
= cmsReadTag (prof
, cmsSigGreenTRCTag
);
770 if (curve
== NULL
|| ! cmsIsToneCurveLinear (curve
))
773 curve
= cmsReadTag (prof
, cmsSigBlueTRCTag
);
774 if (curve
== NULL
|| ! cmsIsToneCurveLinear (curve
))
777 else if (gimp_color_profile_is_gray (profile
))
779 curve
= cmsReadTag(prof
, cmsSigGrayTRCTag
);
780 if (curve
== NULL
|| ! cmsIsToneCurveLinear (curve
))
792 gimp_color_profile_set_tag (cmsHPROFILE profile
,
798 mlu
= cmsMLUalloc (NULL
, 1);
799 cmsMLUsetASCII (mlu
, "en", "US", tag
);
800 cmsWriteTag (profile
, sig
, mlu
);
805 gimp_color_profile_get_rgb_matrix_colorants (GimpColorProfile
*profile
,
808 cmsHPROFILE lcms_profile
;
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
)
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
;
844 static GimpColorProfile
*
845 gimp_color_profile_new_from_color_profile (GimpColorProfile
*profile
,
848 GimpColorProfile
*new_profile
;
849 cmsHPROFILE target_profile
;
850 GimpMatrix3 matrix
= { { { 0, } } };
851 cmsCIEXYZ
*whitepoint
;
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
))
863 else if (! gimp_color_profile_is_gray (profile
))
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
);
882 curve
= cmsBuildGamma (NULL
, 1.00);
884 gimp_color_profile_set_tag (target_profile
, cmsSigProfileDescriptionTag
,
885 "linear TRC variant generated by GIMP");
889 cmsFloat64Number srgb_parameters
[5] =
890 { 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 };
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
))
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
);
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
);
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
,
951 gimp_color_profile_set_tag (target_profile
, cmsSigDeviceModelDescTag
,
953 gimp_color_profile_set_tag (target_profile
, cmsSigCopyrightTag
,
958 new_profile
= gimp_color_profile_new_from_lcms_profile (target_profile
, NULL
);
960 cmsCloseProfile (target_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.
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.
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];
1033 curve
[0] = curve
[1] = curve
[2] = cmsBuildParametricToneCurve (NULL
, 4,
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
,
1044 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1046 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
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
1056 * cmsSetProfileVersion (srgb_profile, 2.1);
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.
1094 gimp_color_profile_new_rgb_srgb (void)
1096 static GimpColorProfile
*profile
= NULL
;
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
);
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];
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
,
1150 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1152 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
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.
1169 gimp_color_profile_new_rgb_srgb_linear (void)
1171 static GimpColorProfile
*profile
= NULL
;
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 }
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];
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
,
1230 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1231 "Compatible with Adobe RGB (1998)");
1232 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
1239 * gimp_color_profile_new_rgb_adobe:
1241 * This function creates a profile compatible with AbobeRGB (1998).
1243 * Return value: the AdobeRGB-compatible #GimpColorProfile.
1248 gimp_color_profile_new_rgb_adobe (void)
1250 static GimpColorProfile
*profile
= NULL
;
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,
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
,
1291 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1292 "D65 Grayscale with sRGB TRC");
1293 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
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.
1310 gimp_color_profile_new_d65_gray_srgb_trc (void)
1312 static GimpColorProfile
*profile
= NULL
;
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
);
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
,
1349 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1350 "D65 Linear Grayscale");
1351 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
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.
1368 gimp_color_profile_new_d65_gray_linear (void)
1370 static GimpColorProfile
*profile
= NULL
;
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,
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
,
1411 gimp_color_profile_set_tag (profile
, cmsSigDeviceModelDescTag
,
1412 "D50 Grayscale with LAB L TRC");
1413 gimp_color_profile_set_tag (profile
, cmsSigCopyrightTag
,
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.
1434 gimp_color_profile_new_d50_gray_lab_trc (void)
1436 static GimpColorProfile
*profile
= NULL
;
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.
1469 gimp_color_profile_get_space (GimpColorProfile
*profile
,
1470 GimpColorRenderingIntent intent
,
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
,
1485 g_set_error (error
, GIMP_COLOR_PROFILE_ERROR
, 0,
1487 gimp_color_profile_get_label (profile
), babl_error
);
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.
1508 gimp_color_profile_get_format (GimpColorProfile
*profile
,
1510 GimpColorRenderingIntent intent
,
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
);
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.
1546 gimp_color_profile_get_lcms_format (const Babl
*format
,
1547 guint32
*lcms_format
)
1549 const Babl
*output_format
= NULL
;
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
;
1570 *lcms_format
= TYPE_ARGB_8
;
1575 else if (format
== babl_format ("cairo-ARGB32"))
1579 else if (model
== babl_model ("RGB") ||
1580 model
== babl_model ("RGBA") ||
1581 model
== babl_model ("RaGaBaA"))
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"))
1592 else if (model
== babl_model ("Y") ||
1593 model
== babl_model ("YA") ||
1594 model
== babl_model ("YaA"))
1599 else if (model
== babl_model ("Y'") ||
1600 model
== babl_model ("Y'A") ||
1601 model
== babl_model ("Y'aA"))
1605 else if (model
== babl_model ("CMYK"))
1607 /* FIXME missing from babl */
1608 || model
== babl_model ("CMYKA"))
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"))
1620 *lcms_format
= TYPE_RGBA_FLT
;
1622 return babl_format ("RGBA float");
1626 *lcms_format
= TYPE_RGB_FLT
;
1628 return babl_format ("RGB float");
1631 else if (babl_format_is_palette (format
))
1635 *lcms_format
= TYPE_RGBA_8
;
1637 return babl_format ("R'G'B'A u8");
1641 *lcms_format
= TYPE_RGB_8
;
1643 return babl_format ("R'G'B' u8");
1648 g_printerr ("format: %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
);
1661 #define FIND_FORMAT_FOR_TYPE(babl_t, lcms_t) \
1668 *lcms_format = TYPE_RGBA_##lcms_t; \
1671 output_format = babl_format ("RGBA " babl_t); \
1673 output_format = babl_format ("R'G'B'A " babl_t); \
1677 *lcms_format = TYPE_GRAYA_##lcms_t; \
1680 output_format = babl_format ("YA " babl_t); \
1682 output_format = babl_format ("Y'A " babl_t); \
1686 *lcms_format = TYPE_CMYKA_##lcms_t; \
1688 output_format = format; \
1695 *lcms_format = TYPE_RGB_##lcms_t; \
1698 output_format = babl_format ("RGB " babl_t); \
1700 output_format = babl_format ("R'G'B' " babl_t); \
1704 *lcms_format = TYPE_GRAY_##lcms_t; \
1707 output_format = babl_format ("Y " babl_t); \
1709 output_format = babl_format ("Y' " babl_t); \
1713 *lcms_format = TYPE_CMYK_##lcms_t; \
1715 output_format = format; \
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
));
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
;