Code

remove spurious fit_and_split wrapper
[inkscape.git] / src / sp-image.cpp
index 86998156720ec511c979cf1196e719436ee78c0b..5804089e687cf9efc1ef658cb01ab2274c574c73 100644 (file)
 
 #include "io/sys.h"
 #include <png.h>
-
+#if ENABLE_LCMS
+#include "color-profile-fns.h"
+#include "color-profile.h"
+//#define DEBUG_LCMS
+#ifdef DEBUG_LCMS
+#include "prefs-utils.h"
+#include <gtk/gtkmessagedialog.h>
+#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 {
 
@@ -118,7 +156,7 @@ public:
                     //g_message( " __read %d bytes", (int)got );
                     if ( !gdk_pixbuf_loader_write( loader, scratch + used, got, &err ) )
                     {
-                        //g_message("_error writing pixbuf data"); 
+                        //g_message("_error writing pixbuf data");
                     }
                 }
 
@@ -306,7 +344,7 @@ GdkPixbuf*  pixbuf_new_from_file( const char *filename, GError **error )
                                         "unknown", // PNG_SCALE_UNKNOWN
                                         "meter", // PNG_SCALE_METER
                                         "radian", // PNG_SCALE_RADIAN
-                                        "last", // 
+                                        "last", //
                                         NULL
                                     };
 
@@ -382,7 +420,7 @@ GdkPixbuf*  pixbuf_new_from_file( const char *filename, GError **error )
     }
     else
     {
-        g_warning ("unable to open file: %s", filename);
+        g_warning ("Unable to open linked file: %s", filename);
     }
 
 /*
@@ -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, "<image> color-profile set to '%s'", value );
+                } else {
+                    DEBUG_MESSAGE( lcmsFour, "<image> 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 <image>'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 <image>'s sp_image_update. Unable to create LCMS transform." );
+                                                }
+#endif // DEBUG_LCMS
+                                                cmsCloseProfile( destProf );
+                                            }
+#ifdef DEBUG_LCMS
+                                            else
+                                            {
+                                                DEBUG_MESSAGE( lcmsSeven, "in <image>'s sp_image_update. Profile type is named color. Can't transform." );
+                                            }
+#endif // DEBUG_LCMS
+                                        }
+#ifdef DEBUG_LCMS
+                                        else
+                                        {
+                                            DEBUG_MESSAGE( lcmsEight, "in <image>'s sp_image_update. No profile found." );
+                                        }
+#endif // DEBUG_LCMS
+                                    }
+                                }
+#endif // ENABLE_LCMS
                                image->pixbuf = pixbuf;
                        }
                }
@@ -729,7 +869,7 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags)
                                }
                        }
        }
-       
+
        sp_image_update_canvas_image ((SPImage *) object);
 }
 
@@ -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);
@@ -788,13 +931,13 @@ sp_image_print (SPItem *item, SPPrintContext *ctx)
 
        if (!image->pixbuf) return;
        if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return;
-       
+
        px = gdk_pixbuf_get_pixels (image->pixbuf);
        w = gdk_pixbuf_get_width (image->pixbuf);
        h = gdk_pixbuf_get_height (image->pixbuf);
        rs = gdk_pixbuf_get_rowstride (image->pixbuf);
        pixskip = gdk_pixbuf_get_n_channels (image->pixbuf) * gdk_pixbuf_get_bits_per_sample (image->pixbuf) / 8;
-       
+
        if (image->aspect_align == SP_ASPECT_NONE) {
                /* fixme: (Lauris) */
                nr_matrix_set_translate (&tp, image->x.computed, image->y.computed);
@@ -821,13 +964,13 @@ sp_image_description(SPItem *item)
        SPImage *image = SP_IMAGE(item);
        char *href_desc;
         if (image->href) {
-            href_desc = (strncmp(image->href, "data:", 5) == 0) 
+            href_desc = (strncmp(image->href, "data:", 5) == 0)
                 ? g_strdup(_("embedded"))
                 : xml_quote_strdup(image->href);
         } else {
             g_warning("Attempting to call strncmp() with a null pointer.");
             href_desc = g_strdup(_("(null_pointer)")); // we call g_free() on href_desc
-        }                
+        }
 
        char *ret = ( image->pixbuf == NULL
                      ? g_strdup_printf(_("<b>Image with bad reference</b>: %s"), href_desc)