X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fsp-image.cpp;h=5804089e687cf9efc1ef658cb01ab2274c574c73;hb=2c2560e6c5a9be8babb1266318bddb90437a5f1b;hp=17f969b537c6f9d8229a76f719d7de910b6a5c1d;hpb=1a26cc231b5787497d9290ba58a19988d142bfde;p=inkscape.git diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 17f969b53..5804089e6 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -36,7 +36,15 @@ #include "io/sys.h" #include - +#if ENABLE_LCMS +#include "color-profile-fns.h" +#include "color-profile.h" +//#define DEBUG_LCMS +#ifdef DEBUG_LCMS +#include "prefs-utils.h" +#include +#endif // DEBUG_LCMS +#endif // ENABLE_LCMS /* * SPImage */ @@ -75,6 +83,36 @@ extern "C" } + +#ifdef DEBUG_LCMS +extern guint update_in_progress; +#define DEBUG_MESSAGE(key, ...) \ +{\ + gint dump = prefs_get_int_attribute_limited("options.scislac", #key, 0, 0, 1);\ + gint dumpD = prefs_get_int_attribute_limited("options.scislac", #key"D", 0, 0, 1);\ + gint dumpD2 = prefs_get_int_attribute_limited("options.scislac", #key"D2", 0, 0, 1);\ + dumpD &= ( (update_in_progress == 0) || dumpD2 );\ + if ( dump )\ + {\ + g_message( __VA_ARGS__ );\ +\ + }\ + if ( dumpD )\ + {\ + GtkWidget *dialog = gtk_message_dialog_new(NULL,\ + GTK_DIALOG_DESTROY_WITH_PARENT, \ + GTK_MESSAGE_INFO, \ + GTK_BUTTONS_OK, \ + __VA_ARGS__ \ + );\ + g_signal_connect_swapped(dialog, "response",\ + G_CALLBACK(gtk_widget_destroy), \ + dialog); \ + gtk_widget_show_all( dialog );\ + }\ +} +#endif // DEBUG_LCMS + namespace Inkscape { namespace IO { @@ -478,6 +516,7 @@ sp_image_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *rep sp_object_read_attr (object, "width"); sp_object_read_attr (object, "height"); sp_object_read_attr (object, "preserveAspectRatio"); + sp_object_read_attr (object, "color-profile"); /* Register */ sp_document_add_resource (document, "image", object); @@ -505,6 +544,13 @@ sp_image_release (SPObject *object) image->pixbuf = NULL; } +#if ENABLE_LCMS + if (image->color_profile) { + g_free (image->color_profile); + image->color_profile = NULL; + } +#endif // ENABLE_LCMS + if (((SPObjectClass *) parent_class)->release) ((SPObjectClass *) parent_class)->release (object); } @@ -608,6 +654,23 @@ sp_image_set (SPObject *object, unsigned int key, const gchar *value) image->aspect_clip = clip; } break; +#if ENABLE_LCMS + case SP_PROP_COLOR_PROFILE: + if ( image->color_profile ) { + g_free (image->color_profile); + } + image->color_profile = (value) ? g_strdup (value) : NULL; +#ifdef DEBUG_LCMS + if ( value ) { + DEBUG_MESSAGE( lcmsFour, " color-profile set to '%s'", value ); + } else { + DEBUG_MESSAGE( lcmsFour, " color-profile cleared" ); + } +#endif // DEBUG_LCMS + // TODO check on this HREF_MODIFIED flag + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); + break; +#endif // ENABLE_LCMS default: if (((SPObjectClass *) (parent_class))->set) ((SPObjectClass *) (parent_class))->set (object, key, value); @@ -635,6 +698,83 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) pixbuf = sp_image_repr_read_image (object->repr); if (pixbuf) { pixbuf = sp_image_pixbuf_force_rgba (pixbuf); +// BLIP +#if ENABLE_LCMS + if ( image->color_profile ) + { + int imagewidth = gdk_pixbuf_get_width( pixbuf ); + int imageheight = gdk_pixbuf_get_height( pixbuf ); + int rowstride = gdk_pixbuf_get_rowstride( pixbuf ); + guchar* px = gdk_pixbuf_get_pixels( pixbuf ); + + if ( px ) { +#ifdef DEBUG_LCMS + DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); +#endif // DEBUG_LCMS + guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; + cmsHPROFILE prof = Inkscape::colorprofile_get_handle( SP_OBJECT_DOCUMENT( object ), + &profIntent, + image->color_profile ); + if ( prof ) { + icProfileClassSignature profileClass = cmsGetDeviceClass( prof ); + if ( profileClass != icSigNamedColorClass ) { + int intent = INTENT_PERCEPTUAL; + switch ( profIntent ) { + case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC: + intent = INTENT_RELATIVE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_SATURATION: + intent = INTENT_SATURATION; + break; + case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC: + intent = INTENT_ABSOLUTE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_PERCEPTUAL: + case Inkscape::RENDERING_INTENT_UNKNOWN: + case Inkscape::RENDERING_INTENT_AUTO: + default: + intent = INTENT_PERCEPTUAL; + } + cmsHPROFILE destProf = cmsCreate_sRGBProfile(); + cmsHTRANSFORM transf = cmsCreateTransform( prof, + TYPE_RGBA_8, + destProf, + TYPE_RGBA_8, + intent, 0 ); + if ( transf ) { + guchar* currLine = px; + for ( int y = 0; y < imageheight; y++ ) { + // Since the types are the same size, we can do the transformation in-place + cmsDoTransform( transf, currLine, currLine, imagewidth ); + currLine += rowstride; + } + + cmsDeleteTransform( transf ); + } +#ifdef DEBUG_LCMS + else + { + DEBUG_MESSAGE( lcmsSix, "in 's sp_image_update. Unable to create LCMS transform." ); + } +#endif // DEBUG_LCMS + cmsCloseProfile( destProf ); + } +#ifdef DEBUG_LCMS + else + { + DEBUG_MESSAGE( lcmsSeven, "in 's sp_image_update. Profile type is named color. Can't transform." ); + } +#endif // DEBUG_LCMS + } +#ifdef DEBUG_LCMS + else + { + DEBUG_MESSAGE( lcmsEight, "in 's sp_image_update. No profile found." ); + } +#endif // DEBUG_LCMS + } + } +#endif // ENABLE_LCMS image->pixbuf = pixbuf; } } @@ -751,6 +891,9 @@ sp_image_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) if (image->width._set) sp_repr_set_svg_double(repr, "width", image->width.computed); if (image->height._set) sp_repr_set_svg_double(repr, "height", image->height.computed); repr->setAttribute("preserveAspectRatio", object->repr->attribute("preserveAspectRatio")); +#if ENABLE_LCMS + if (image->color_profile) repr->setAttribute("color-profile", image->color_profile); +#endif // ENABLE_LCMS if (((SPObjectClass *) (parent_class))->write) ((SPObjectClass *) (parent_class))->write (object, repr, flags);