/** * gimp_color_profile_is_equal: * @profile1: a #GimpColorProfile * @profile2: a #GimpColorProfile * * Compares two profiles. * * Return value: %TRUE if the profiles are equal, %FALSE otherwise. * * Since: 2.10 **/ gboolean gimp_color_profile_is_equal (GimpColorProfile *profile1, GimpColorProfile *profile2) { const gsize header_len = sizeof (cmsICCHeader); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile1), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile1), FALSE); return (profile1->priv->length == profile2->priv->length && memcmp (profile1->priv->data + header_len, profile2->priv->data + header_len, profile1->priv->length - header_len) == 0); }
/** * gimp_color_profile_new_linear_from_color_profile: * @profile: a #GimpColorProfile * * This function creates a new RGB #GimpColorProfile with a linear TRC * and @profile's RGB chromacities and whitepoint. * * Return value: the new #GimpColorProfile, or %NULL if @profile is not * an RGB profile or not matrix-based. * * Since: 2.10 **/ GimpColorProfile * gimp_color_profile_new_linear_from_color_profile (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); return gimp_color_profile_new_from_color_profile (profile, TRUE); }
/** * gimp_color_profile_is_cmyk: * @profile: a #GimpColorProfile * * Return value: %TRUE if the profile's color space is CMYK, %FALSE * otherwise. * * Since: 2.10 **/ gboolean gimp_color_profile_is_cmyk (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE); return (cmsGetColorSpace (profile->priv->lcms_profile) == cmsSigCmykData); }
gboolean gimp_image_validate_color_profile (GimpImage *image, GimpColorProfile *profile, GError **error) { g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (gimp_image_get_base_type (image) == GIMP_GRAY) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("ICC profile validation failed: " "Cannot attach a color profile to a GRAY image")); return FALSE; } if (! gimp_color_profile_is_rgb (profile)) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("ICC profile validation failed: " "Color profile is not for RGB color space")); return FALSE; } return TRUE; }
/** * gimp_color_profile_new_srgb_trc_from_color_profile: * @profile: a #GimpColorProfile * * This function creates a new RGB #GimpColorProfile with a sRGB gamma * TRC and @profile's RGB chromacities and whitepoint. * * Return value: the new #GimpColorProfile, or %NULL if @profile is not * an RGB profile or not matrix-based. * * Since: 2.10 **/ GimpColorProfile * gimp_color_profile_new_srgb_trc_from_color_profile (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); return gimp_color_profile_new_from_color_profile (profile, FALSE); }
/** * gimp_color_profile_get_lcms_profile: * @profile: a #GimpColorProfile * * This function returns @profile's cmsHPROFILE. The returned * value belongs to @profile and must not be modified or freed. * * Return value: a pointer to the cmsHPROFILE. * * Since: 2.10 **/ gpointer gimp_color_profile_get_lcms_profile (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); return profile->priv->lcms_profile; }
/** * gimp_layer_new_from_gegl_buffer: * @buffer: The buffer to make the new layer from. * @dest_image: The image the new layer will be added to. * @format: The #Babl format of the new layer. * @name: The new layer's name. * @opacity: The new layer's opacity. * @mode: The new layer's mode. * * Copies %buffer to a layer taking into consideration the * possibility of transforming the contents to meet the requirements * of the target image type * * Return value: The new layer. **/ GimpLayer * gimp_layer_new_from_gegl_buffer (GeglBuffer *buffer, GimpImage *dest_image, const Babl *format, const gchar *name, gdouble opacity, GimpLayerModeEffects mode, GimpColorProfile *buffer_profile) { GimpLayer *layer; g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL); g_return_val_if_fail (format != NULL, NULL); g_return_val_if_fail (buffer_profile == NULL || GIMP_IS_COLOR_PROFILE (buffer_profile), NULL); /* do *not* use the buffer's format because this function gets * buffers of any format passed, and converts them */ layer = gimp_layer_new (dest_image, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer), format, name, opacity, mode); gimp_layer_new_convert_buffer (layer, buffer, buffer_profile, NULL); return layer; }
/** * gimp_color_profile_is_linear: * @profile: a #GimpColorProfile * * This function determines is the ICC profile represented by a GimpColorProfile * is a linear RGB profile or not, some profiles that are LUTs though linear * will also return FALSE; * * Return value: %TRUE if the profile is a matrix shaping profile with linear * TRCs, %FALSE otherwise. * * Since: 2.10 **/ gboolean gimp_color_profile_is_linear (GimpColorProfile *profile) { cmsHPROFILE prof; cmsToneCurve *curve; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE); prof = profile->priv->lcms_profile; if (! cmsIsMatrixShaper (prof)) return FALSE; if (cmsIsCLUT (prof, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) return FALSE; if (cmsIsCLUT (prof, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)) return FALSE; curve = cmsReadTag(prof, cmsSigRedTRCTag); if (curve == NULL || ! cmsIsToneCurveLinear (curve)) return FALSE; curve = cmsReadTag (prof, cmsSigGreenTRCTag); if (curve == NULL || ! cmsIsToneCurveLinear (curve)) return FALSE; curve = cmsReadTag (prof, cmsSigBlueTRCTag); if (curve == NULL || ! cmsIsToneCurveLinear (curve)) return FALSE; return TRUE; }
GimpDrawable * gimp_drawable_transform_paste (GimpDrawable *drawable, GeglBuffer *buffer, GimpColorProfile *buffer_profile, gint offset_x, gint offset_y, gboolean new_layer) { GimpImage *image; GimpLayer *layer = NULL; const gchar *undo_desc = NULL; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL); g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (buffer_profile), NULL); image = gimp_item_get_image (GIMP_ITEM (drawable)); if (GIMP_IS_LAYER (drawable)) undo_desc = C_("undo-type", "Transform Layer"); else if (GIMP_IS_CHANNEL (drawable)) undo_desc = C_("undo-type", "Transform Channel"); else return NULL; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc); if (new_layer) { layer = gimp_layer_new_from_gegl_buffer (buffer, image, gimp_drawable_get_format_with_alpha (drawable), _("Transformation"), GIMP_OPACITY_OPAQUE, gimp_image_get_default_new_layer_mode (image), buffer_profile); gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y); floating_sel_attach (layer, drawable); drawable = GIMP_DRAWABLE (layer); } else { gimp_drawable_set_buffer_full (drawable, TRUE, NULL, buffer, offset_x, offset_y, TRUE); } gimp_image_undo_group_end (image); return drawable; }
/** * gimp_color_profile_get_model: * @profile: a #GimpColorProfile * * Return value: a string containing @profile's model. The returned * value belongs to @profile and must not be modified or * freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_model (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->model) profile->priv->model = gimp_color_profile_get_info (profile, cmsInfoModel); return profile->priv->model; }
/** * gimp_color_profile_get_copyright: * @profile: a #GimpColorProfile * * Return value: a string containing @profile's copyright. The * returned value belongs to @profile and must not be * modified or freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_copyright (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->copyright) profile->priv->copyright = gimp_color_profile_get_info (profile, cmsInfoCopyright); return profile->priv->copyright; }
/** * gimp_color_profile_get_manufacturer: * @profile: a #GimpColorProfile * * Return value: a string containing @profile's manufacturer. The * returned value belongs to @profile and must not be * modified or freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_manufacturer (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->manufacturer) profile->priv->manufacturer = gimp_color_profile_get_info (profile, cmsInfoManufacturer); return profile->priv->manufacturer; }
/** * gimp_color_profile_get_description: * @profile: a #GimpColorProfile * * Return value: a string containing @profile's description. The * returned value belongs to @profile and must not be * modified or freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_description (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->description) profile->priv->description = gimp_color_profile_get_info (profile, cmsInfoDescription); return profile->priv->description; }
/** * gimp_color_profile_get_icc_profile: * @profile: a #GimpColorProfile * @length: return location for the number of bytes * @error: return location for #GError * * This function returns @profile as ICC profile data. The returned * memory belongs to @profile and must not be modified or freed. * * Return value: a pointer to the IIC profile data. * * Since: 2.10 **/ const guint8 * gimp_color_profile_get_icc_profile (GimpColorProfile *profile, gsize *length) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); g_return_val_if_fail (length != NULL, NULL); *length = profile->priv->length; return profile->priv->data; }
/** * gimp_color_transform_can_gegl_copy: * @src_format: src profile * @dest_format: dest profile * * This function checks if a GimpColorTransform is needed at all. * * Return value: %TRUE if pixels can be correctly converted between * @src_profile and @dest_profile by simply using * gegl_buffer_copy(), babl_process() or similar. * * Since: 2.10 **/ gboolean gimp_color_transform_can_gegl_copy (GimpColorProfile *src_profile, GimpColorProfile *dest_profile) { static GimpColorProfile *srgb_profile = NULL; static GimpColorProfile *srgb_linear_profile = NULL; static GimpColorProfile *gray_profile = NULL; static GimpColorProfile *gray_linear_profile = NULL; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), FALSE); if (gimp_color_profile_is_equal (src_profile, dest_profile)) return TRUE; if (! srgb_profile) { srgb_profile = gimp_color_profile_new_rgb_srgb (); srgb_linear_profile = gimp_color_profile_new_rgb_srgb_linear (); gray_profile = gimp_color_profile_new_d65_gray_srgb_trc (); gray_linear_profile = gimp_color_profile_new_d65_gray_linear (); } if ((gimp_color_profile_is_equal (src_profile, srgb_profile) || gimp_color_profile_is_equal (src_profile, srgb_linear_profile) || gimp_color_profile_is_equal (src_profile, gray_profile) || gimp_color_profile_is_equal (src_profile, gray_linear_profile)) && (gimp_color_profile_is_equal (dest_profile, srgb_profile) || gimp_color_profile_is_equal (dest_profile, srgb_linear_profile) || gimp_color_profile_is_equal (dest_profile, gray_profile) || gimp_color_profile_is_equal (dest_profile, gray_linear_profile))) { return TRUE; } return FALSE; }
void gimp_buffer_set_color_profile (GimpBuffer *buffer, GimpColorProfile *profile) { g_return_if_fail (GIMP_IS_BUFFER (buffer)); g_return_if_fail (profile == NULL || GIMP_IS_COLOR_PROFILE (profile)); if (profile != buffer->color_profile) { g_clear_object (&buffer->color_profile); if (profile) buffer->color_profile = g_object_ref (profile); } }
GtkWidget * gimp_color_profile_label_new (GimpColorProfile *profile) { GtkWidget *expander; GtkWidget *view; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); expander = gtk_expander_new (gimp_color_profile_get_label (profile)); view = gimp_color_profile_view_new (); gimp_color_profile_view_set_profile (GIMP_COLOR_PROFILE_VIEW (view), profile); gtk_container_add (GTK_CONTAINER (expander), view); gtk_widget_show (view); return expander; }
/** * gimp_color_profile_get_summary: * @profile: a #GimpColorProfile * * This function return a string containing a multi-line summary of * @profile's description, model, manufacturer and copyright, to be * used as detailled information about the profile in a user * interface. * * Return value: the @profile's summary. The returned value belongs to * @profile and must not be modified or freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_summary (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->summary) { GString *string = g_string_new (NULL); const gchar *text; text = gimp_color_profile_get_description (profile); if (text) g_string_append (string, text); text = gimp_color_profile_get_model (profile); if (text) { if (string->len > 0) g_string_append (string, "\n"); g_string_append_printf (string, _("Model: %s"), text); } text = gimp_color_profile_get_manufacturer (profile); if (text) { if (string->len > 0) g_string_append (string, "\n"); g_string_append_printf (string, _("Manufacturer: %s"), text); } text = gimp_color_profile_get_copyright (profile); if (text) { if (string->len > 0) g_string_append (string, "\n"); g_string_append_printf (string, _("Copyright: %s"), text); } profile->priv->summary = g_string_free (string, FALSE); } return profile->priv->summary; }
/** * gimp_color_profile_get_label: * @profile: a #GimpColorProfile * * This function returns a string containing @profile's "title", a * string that can be used to label the profile in a user interface. * * Unlike gimp_color_profile_get_description(), this function always * returns a string (as a fallback, it returns "(unnamed profile)". * * Return value: the @profile's label. The returned value belongs to * @profile and must not be modified or freed. * * Since: 2.10 **/ const gchar * gimp_color_profile_get_label (GimpColorProfile *profile) { g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (! profile->priv->label) { const gchar *label = gimp_color_profile_get_description (profile); if (! label || ! strlen (label)) label = _("(unnamed profile)"); profile->priv->label = g_strdup (label); } return profile->priv->label; }
gboolean gimp_image_set_color_profile (GimpImage *image, GimpColorProfile *profile, GError **error) { const guint8 *data = NULL; gsize length = 0; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (profile == NULL || GIMP_IS_COLOR_PROFILE (profile), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (profile) data = gimp_color_profile_get_icc_profile (profile, &length); return gimp_image_set_icc_profile (image, data, length, error); }
gboolean gimp_image_validate_color_profile (GimpImage *image, GimpColorProfile *profile, gboolean *is_builtin, GError **error) { g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (gimp_image_get_base_type (image) == GIMP_GRAY) { if (! gimp_color_profile_is_gray (profile)) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("ICC profile validation failed: " "Color profile is not for GRAY color space")); return FALSE; } } else { if (! gimp_color_profile_is_rgb (profile)) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("ICC profile validation failed: " "Color profile is not for RGB color space")); return FALSE; } } if (is_builtin) { GimpColorProfile *builtin; builtin = gimp_image_get_builtin_color_profile (image); *is_builtin = gimp_color_profile_is_equal (profile, builtin); } return TRUE; }
static gboolean gimp_color_profile_get_rgb_matrix_colorants (GimpColorProfile *profile, GimpMatrix3 *matrix) { cmsHPROFILE lcms_profile; cmsCIEXYZ *red; cmsCIEXYZ *green; cmsCIEXYZ *blue; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE); lcms_profile = profile->priv->lcms_profile; red = cmsReadTag (lcms_profile, cmsSigRedColorantTag); green = cmsReadTag (lcms_profile, cmsSigGreenColorantTag); blue = cmsReadTag (lcms_profile, cmsSigBlueColorantTag); if (red && green && blue) { if (matrix) { matrix->coeff[0][0] = red->X; matrix->coeff[0][1] = red->Y; matrix->coeff[0][2] = red->Z; matrix->coeff[1][0] = green->X; matrix->coeff[1][1] = green->Y; matrix->coeff[1][2] = green->Z; matrix->coeff[2][0] = blue->X; matrix->coeff[2][1] = blue->Y; matrix->coeff[2][2] = blue->Z; } return TRUE; } return FALSE; }
GimpColorTransform gimp_widget_get_color_transform (GtkWidget *widget, GimpColorConfig *config, GimpColorProfile *src_profile, const Babl **src_format, const Babl **dest_format) { GimpColorTransform transform = NULL; GimpColorProfile *dest_profile = NULL; GimpColorProfile *proof_profile = NULL; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, }; g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL); g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL); g_return_val_if_fail (src_format != NULL, NULL); g_return_val_if_fail (dest_format != NULL, NULL); switch (config->mode) { case GIMP_COLOR_MANAGEMENT_OFF: return NULL; case GIMP_COLOR_MANAGEMENT_SOFTPROOF: proof_profile = gimp_color_config_get_printer_color_profile (config, NULL); /* fallthru */ case GIMP_COLOR_MANAGEMENT_DISPLAY: dest_profile = get_display_profile (widget, config); break; } src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); *src_format = gimp_color_profile_get_format (*src_format, &lcms_src_format); *dest_format = gimp_color_profile_get_format (*dest_format, &lcms_dest_format); if (proof_profile) { cmsHPROFILE proof_lcms; cmsUInt32Number softproof_flags = cmsFLAGS_SOFTPROOFING; proof_lcms = gimp_color_profile_get_lcms_profile (proof_profile); if (config->simulation_use_black_point_compensation) { softproof_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } if (config->simulation_gamut_check) { guchar r, g, b; softproof_flags |= cmsFLAGS_GAMUTCHECK; gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b); alarmCodes[0] = (cmsUInt16Number) r * 256; alarmCodes[1] = (cmsUInt16Number) g * 256; alarmCodes[2] = (cmsUInt16Number) b * 256; cmsSetAlarmCodes (alarmCodes); } transform = cmsCreateProofingTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, proof_lcms, config->simulation_intent, config->display_intent, softproof_flags); g_object_unref (proof_profile); } else if (! gimp_color_profile_is_equal (src_profile, dest_profile)) { cmsUInt32Number display_flags = 0; if (config->display_use_black_point_compensation) { display_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } transform = cmsCreateTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, config->display_intent, display_flags); } g_object_unref (dest_profile); return transform; }
gboolean gimp_image_convert_color_profile (GimpImage *image, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc, GimpProgress *progress, GError **error) { GimpColorProfile *src_profile; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), FALSE); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (! gimp_image_validate_color_profile (image, dest_profile, NULL, error)) return FALSE; src_profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image)); if (! src_profile || gimp_color_profile_is_equal (src_profile, dest_profile)) return TRUE; if (progress) gimp_progress_start (progress, FALSE, _("Converting from '%s' to '%s'"), gimp_color_profile_get_label (src_profile), gimp_color_profile_get_label (dest_profile)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT, _("Color profile conversion")); switch (gimp_image_get_base_type (image)) { case GIMP_RGB: gimp_image_convert_profile_rgb (image, src_profile, dest_profile, intent, bpc, progress); break; case GIMP_GRAY: break; case GIMP_INDEXED: gimp_image_convert_profile_indexed (image, src_profile, dest_profile, intent, bpc, progress); break; } gimp_image_set_color_profile (image, dest_profile, NULL); /* omg... */ gimp_image_parasite_detach (image, "icc-profile-name"); gimp_image_undo_group_end (image); if (progress) gimp_progress_end (progress); return TRUE; }
/** * gimp_color_transform_new_proofing: * @src_profile: * @src_format: * @desr_profile: * @dest_format: * @proof_profile: * @proof_intent: * @display_intent: * @flags: * * This function creates a simulation / proofing color transform. * * Return value: the #GimpColorTransform, or %NULL. * * Since: 2.10 **/ GimpColorTransform * gimp_color_transform_new_proofing (GimpColorProfile *src_profile, const Babl *src_format, GimpColorProfile *dest_profile, const Babl *dest_format, GimpColorProfile *proof_profile, GimpColorRenderingIntent proof_intent, GimpColorRenderingIntent display_intent, GimpColorTransformFlags flags) { GimpColorTransform *transform; GimpColorTransformPrivate *priv; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsHPROFILE proof_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL); g_return_val_if_fail (src_format != NULL, NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), NULL); g_return_val_if_fail (dest_format != NULL, NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (proof_profile), NULL); transform = g_object_new (GIMP_TYPE_COLOR_TRANSFORM, NULL); priv = transform->priv; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); proof_lcms = gimp_color_profile_get_lcms_profile (proof_profile); priv->src_format = gimp_color_profile_get_format (src_format, &lcms_src_format); priv->dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format); lcms_error_clear (); priv->transform = cmsCreateProofingTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, proof_lcms, proof_intent, display_intent, flags | cmsFLAGS_SOFTPROOFING); if (lcms_last_error) { if (priv->transform) { cmsDeleteTransform (priv->transform); priv->transform = NULL; } g_printerr ("%s\n", lcms_last_error); } if (! priv->transform) { g_object_unref (transform); transform = NULL; } return transform; }
GimpColorTransform * gimp_widget_get_color_transform (GtkWidget *widget, GimpColorConfig *config, GimpColorProfile *src_profile, const Babl *src_format, const Babl *dest_format) { static gboolean initialized = FALSE; GimpColorProfile *dest_profile = NULL; GimpColorProfile *proof_profile = NULL; TransformCache *cache; g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL); g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL); g_return_val_if_fail (src_format != NULL, NULL); g_return_val_if_fail (dest_format != NULL, NULL); if (G_UNLIKELY (! initialized)) { initialized = TRUE; debug_cache = g_getenv ("GIMP_DEBUG_TRANSFORM_CACHE") != NULL; } switch (gimp_color_config_get_mode (config)) { case GIMP_COLOR_MANAGEMENT_OFF: return NULL; case GIMP_COLOR_MANAGEMENT_SOFTPROOF: proof_profile = gimp_color_config_get_simulation_color_profile (config, NULL); /* fallthru */ case GIMP_COLOR_MANAGEMENT_DISPLAY: dest_profile = get_display_profile (widget, config); break; } cache = transform_cache_get (config, src_profile, src_format, dest_profile, dest_format, proof_profile); if (cache) { g_object_unref (dest_profile); if (proof_profile) g_object_unref (proof_profile); if (cache->transform) return g_object_ref (cache->transform); return NULL; } if (! proof_profile && gimp_color_profile_is_equal (src_profile, dest_profile)) { g_object_unref (dest_profile); return NULL; } cache = g_new0 (TransformCache, 1); if (debug_cache) g_printerr ("creating cache %p\n", cache); cache->config = g_object_ref (config); cache->src_profile = g_object_ref (src_profile); cache->src_format = src_format; cache->dest_profile = dest_profile; cache->dest_format = dest_format; cache->proof_profile = proof_profile; cache->notify_id = g_signal_connect (cache->config, "notify", G_CALLBACK (transform_cache_config_notify), cache); transform_caches = g_list_prepend (transform_caches, cache); if (cache->proof_profile) { GimpColorTransformFlags flags = 0; if (gimp_color_config_get_simulation_bpc (config)) flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; if (! gimp_color_config_get_simulation_optimize (config)) flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; if (gimp_color_config_get_simulation_gamut_check (config)) { cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, }; guchar r, g, b; flags |= GIMP_COLOR_TRANSFORM_FLAGS_GAMUT_CHECK; gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b); alarmCodes[0] = (cmsUInt16Number) r * 256; alarmCodes[1] = (cmsUInt16Number) g * 256; alarmCodes[2] = (cmsUInt16Number) b * 256; cmsSetAlarmCodes (alarmCodes); } cache->transform = gimp_color_transform_new_proofing (cache->src_profile, cache->src_format, cache->dest_profile, cache->dest_format, cache->proof_profile, gimp_color_config_get_simulation_intent (config), gimp_color_config_get_display_intent (config), flags); } else { GimpColorTransformFlags flags = 0; if (gimp_color_config_get_display_bpc (config)) flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; if (! gimp_color_config_get_display_optimize (config)) flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; cache->transform = gimp_color_transform_new (cache->src_profile, cache->src_format, cache->dest_profile, cache->dest_format, gimp_color_config_get_display_intent (config), flags); } if (cache->transform) return g_object_ref (cache->transform); return NULL; }
GimpColorProfileCallback callback, gpointer user_data) { ProfileDialog *private; GtkWidget *dialog; GtkWidget *frame; GtkWidget *vbox; GtkWidget *expander; GtkWidget *label; const gchar *dest_label; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL); g_return_val_if_fail (current_profile == NULL || GIMP_IS_COLOR_PROFILE (current_profile), NULL); g_return_val_if_fail (default_profile == NULL || GIMP_IS_COLOR_PROFILE (default_profile), NULL); g_return_val_if_fail (callback != NULL, NULL); private = g_slice_new0 (ProfileDialog); private->dialog_type = dialog_type; private->image = image; private->current_profile = current_profile; private->default_profile = default_profile; private->intent = intent; private->bpc = bpc; private->callback = callback; private->user_data = user_data; private->config = image->gimp->config->color_management;
static GimpColorProfile * gimp_color_profile_new_from_color_profile (GimpColorProfile *profile, gboolean linear) { GimpColorProfile *new_profile; cmsHPROFILE target_profile; GimpMatrix3 matrix = { 0, }; cmsCIEXYZ *whitepoint; cmsToneCurve *curve; const gchar *model; gchar *new_model; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), NULL); if (gimp_color_profile_is_rgb (profile)) { if (! gimp_color_profile_get_rgb_matrix_colorants (profile, &matrix)) return NULL; } else if (! gimp_color_profile_is_gray (profile)) { return NULL; } whitepoint = cmsReadTag (profile->priv->lcms_profile, cmsSigMediaWhitePointTag); target_profile = cmsCreateProfilePlaceholder (0); cmsSetProfileVersion (target_profile, 4.3); cmsSetDeviceClass (target_profile, cmsSigDisplayClass); cmsSetPCS (target_profile, cmsSigXYZData); cmsWriteTag (target_profile, cmsSigMediaWhitePointTag, whitepoint); if (linear) { /* linear light */ curve = cmsBuildGamma (NULL, 1.00); gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag, "linear TRC variant generated by GIMP"); } else { cmsFloat64Number srgb_parameters[5] = { 2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045 }; /* sRGB curve */ curve = cmsBuildParametricToneCurve (NULL, 4, srgb_parameters); gimp_color_profile_set_tag (target_profile, cmsSigProfileDescriptionTag, "sRGB TRC variant generated by GIMP"); } if (gimp_color_profile_is_rgb (profile)) { cmsCIEXYZ red; cmsCIEXYZ green; cmsCIEXYZ blue; cmsSetColorSpace (target_profile, cmsSigRgbData); red.X = matrix.coeff[0][0]; red.Y = matrix.coeff[0][1]; red.Z = matrix.coeff[0][2]; green.X = matrix.coeff[1][0]; green.Y = matrix.coeff[1][1]; green.Z = matrix.coeff[1][2]; blue.X = matrix.coeff[2][0]; blue.Y = matrix.coeff[2][1]; blue.Z = matrix.coeff[2][2]; cmsWriteTag (target_profile, cmsSigRedColorantTag, &red); cmsWriteTag (target_profile, cmsSigGreenColorantTag, &green); cmsWriteTag (target_profile, cmsSigBlueColorantTag, &blue); cmsWriteTag (target_profile, cmsSigRedTRCTag, curve); cmsWriteTag (target_profile, cmsSigGreenTRCTag, curve); cmsWriteTag (target_profile, cmsSigBlueTRCTag, curve); } else { cmsSetColorSpace (target_profile, cmsSigGrayData); cmsWriteTag (target_profile, cmsSigGrayTRCTag, curve); } cmsFreeToneCurve (curve); model = gimp_color_profile_get_model (profile); if (model && g_str_has_prefix (model, "Generated from '")) { /* don't add multiple "Generated from 'foo'" */ new_model = g_strdup (model); } else { new_model = g_strdup_printf ("Generated from '%s'", gimp_color_profile_get_description (profile)); } gimp_color_profile_set_tag (target_profile, cmsSigDeviceMfgDescTag, "GIMP"); gimp_color_profile_set_tag (target_profile, cmsSigDeviceModelDescTag, new_model); gimp_color_profile_set_tag (target_profile, cmsSigCopyrightTag, "Public Domain"); g_free (new_model); new_profile = gimp_color_profile_new_from_lcms_profile (target_profile, NULL); cmsCloseProfile (target_profile); return new_profile; }