Code

parsing and handling of icc-color in feFlood SVG Filters
authorJucaBlues <JucaBlues@users.sourceforge.net>
Sat, 20 Jun 2009 11:49:01 +0000 (11:49 +0000)
committerJucaBlues <JucaBlues@users.sourceforge.net>
Sat, 20 Jun 2009 11:49:01 +0000 (11:49 +0000)
TODO: implement interface to set icc-color to the flood-color parameter

src/display/nr-filter-flood.cpp
src/display/nr-filter-flood.h
src/filters/flood.cpp
src/filters/flood.h
src/svg/svg-color.cpp
src/svg/svg-color.h
src/widgets/sp-color-icc-selector.cpp

index 026cbce169b01b8376aa428b24c397da17992e52..06025392bfc652cf8d41523f27bac026d2128ec8 100644 (file)
@@ -9,8 +9,14 @@
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "display/nr-filter-flood.h"
 #include "display/nr-filter-utils.h"
+#include "svg/svg-icc-color.h"
+#include "svg/svg-color.h"
 
 namespace Inkscape {
 namespace Filters {
@@ -26,6 +32,7 @@ FilterFlood::~FilterFlood()
 {}
 
 int FilterFlood::render(FilterSlot &slot, FilterUnits const &/*units*/) {
+g_message("rendering feflood");
     NRPixBlock *in = slot.get(_input);
     if (!in) {
         g_warning("Missing source image for feFlood (in=%d)", _input);
@@ -43,12 +50,18 @@ int FilterFlood::render(FilterSlot &slot, FilterUnits const &/*units*/) {
                            true);
 
     unsigned char *out_data = NR_PIXBLOCK_PX(out);
-
     unsigned char r,g,b,a;
-    r = CLAMP_D_TO_U8((color >> 24) % 256);
-    g = CLAMP_D_TO_U8((color >> 16) % 256);
-    b = CLAMP_D_TO_U8((color >>  8) % 256);
-    a = CLAMP_D_TO_U8(opacity*255);
+
+
+        r = CLAMP_D_TO_U8((color >> 24) % 256);
+        g = CLAMP_D_TO_U8((color >> 16) % 256);
+        b = CLAMP_D_TO_U8((color >>  8) % 256);
+        a = CLAMP_D_TO_U8(opacity*255);
+
+#if ENABLE_LCMS
+        icc_color_to_sRGB(icc, &r, &g, &b);
+g_message("result: r:%d g:%d b:%d", r, g, b);
+#endif //ENABLE_LCMS
 
     for(i=0; i < 4*in_h*in_w; i+=4){
             out_data[i]=r;
@@ -70,6 +83,10 @@ void FilterFlood::set_opacity(double o) {
     opacity = o;
 }
 
+void FilterFlood::set_icc(SVGICCColor *icc_color) {
+    icc = icc_color;
+}
+
 void FilterFlood::area_enlarge(NRRectL &/*area*/, Geom::Matrix const &/*trans*/)
 {
 }
index 9e6a53abb55dbf6e9364089d1bfb235413358f1e..d38c0d4f5d0833ebb648af6692a5c4a4199f910b 100644 (file)
@@ -15,6 +15,7 @@
 #include "display/nr-filter-primitive.h"
 #include "display/nr-filter-slot.h"
 #include "display/nr-filter-units.h"
+#include "svg/svg-color.h"
 
 namespace Inkscape {
 namespace Filters {
@@ -27,11 +28,13 @@ public:
     
     virtual void set_opacity(double o);
     virtual void set_color(guint32 c);
+    virtual void set_icc(SVGICCColor *icc_color);
     virtual int render(FilterSlot &slot, FilterUnits const &units);
     virtual void area_enlarge(NRRectL &area, Geom::Matrix const &trans);
 private:
     double opacity;
     guint32 color;
+    SVGICCColor *icc;
 };
 
 } /* namespace Filters */
index 625e35d42bf765183611c38561bbe824d25e3258..221b0daf22b84aa31ac1203329fa3ff5834e65bc 100644 (file)
 # include "config.h"
 #endif
 
+#include "strneq.h"
+
 #include "attributes.h"
 #include "svg/svg.h"
 #include "flood.h"
 #include "xml/repr.h"
 #include "helper-fns.h"
-#include "svg/svg-color.h"
 
 /* FeFlood base class */
 
@@ -79,6 +80,7 @@ static void
 sp_feFlood_init(SPFeFlood *feFlood)
 {
     feFlood->opacity = 1;
+    feFlood->icc = NULL;
 }
 
 /**
@@ -120,16 +122,34 @@ sp_feFlood_set(SPObject *object, unsigned int key, gchar const *value)
     gchar *end_ptr = NULL;
     guint32 read_color;
     double read_num;
+    bool dirty = false;
     
     switch(key) {
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
         case SP_PROP_FLOOD_COLOR:
             cend_ptr = NULL;
             read_color = sp_svg_read_color(value, &cend_ptr, 0xffffffff);
+
             if (cend_ptr && read_color != feFlood->color){
                 feFlood->color = read_color;
-                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                dirty=true;
+            }
+
+            if (cend_ptr){
+                while (g_ascii_isspace(*cend_ptr)) {
+                    ++cend_ptr;
+                }
+                if (strneq(cend_ptr, "icc-color(", 10)) {
+                    if (!feFlood->icc) feFlood->icc = new SVGICCColor();
+                    if ( ! sp_svg_read_icc_color( cend_ptr, feFlood->icc ) ) {
+                        delete feFlood->icc;
+                        feFlood->icc = NULL;
+                    }
+                    dirty = true;
+                }
             }
+            if (dirty)
+                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_PROP_FLOOD_OPACITY:
             if (value) {
@@ -208,6 +228,7 @@ static void sp_feFlood_build_renderer(SPFilterPrimitive *primitive, Inkscape::Fi
     
     nr_flood->set_opacity(sp_flood->opacity);
     nr_flood->set_color(sp_flood->color);
+    nr_flood->set_icc(sp_flood->icc);
 }
 
 
index 046c0e868872387cf027fb83e18eb6511b17fb8d..f386e2cd47f56b1509fa5e9904e6e30d42e1cb20 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "sp-filter.h"
 #include "flood-fns.h"
+#include "svg/svg-icc-color.h"
 
 #include "display/nr-filter.h"
 #include "display/nr-filter-flood.h"
@@ -25,6 +26,7 @@ class SPFeFloodClass;
 struct SPFeFlood : public SPFilterPrimitive {
     /** FLOOD ATTRIBUTES HERE */
     guint32 color;
+    SVGICCColor *icc;
     double opacity;
 };
 
index 743d2bbc82b5f31493278e1a6bfb83a6e1715b9d..fcfbbdbd853723a88188a14a71d2e54482a57908 100644 (file)
 #include "svg-color.h"
 #include "svg-icc-color.h"
 
+#if ENABLE_LCMS
+#include <lcms.h>
+#include "color.h"
+#include "color-profile.h"
+#include "document.h"
+#include "inkscape.h"
+#include "profile-manager.h"
+#endif // ENABLE_LCMS
+
 using std::sprintf;
 
 struct SPSVGColor {
@@ -454,6 +463,39 @@ sp_svg_create_color_hash()
     return colors;
 }
 
+//helper function borrowed from src/widgets/sp-color-icc-selector.cpp:
+void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies );
+
+void icc_color_to_sRGB(SVGICCColor* icc, guchar* r, guchar* g, guchar* b){
+    guchar color_out[4];
+    guchar color_in[4];
+    if (icc){
+g_message("profile name: %s", icc->colorProfile.c_str());
+        Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(icc->colorProfile.c_str());
+        if ( prof ) {
+            cmsHTRANSFORM trans = prof->getTransfToSRGB8();
+            if ( trans ) {
+                gchar const** names = 0;
+                gchar const** tips = 0;
+                guint const* scales = 0;
+                getThings( prof->getColorSpace(), names, tips, scales );
+
+                guint count = _cmsChannelsOf( prof->getColorSpace() );
+                if (count>4) count=4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?)
+                for (guint i=0;i<count; i++){
+                    color_in[i] = (guchar) ((((gdouble)icc->colors[i])*256.0) * (gdouble)scales[i]);
+g_message("input[%d]: %d",i, color_in[i]);
+                }
+
+                cmsDoTransform( trans, color_in, color_out, 1 );
+g_message("transform to sRGB done");
+            }
+            *r = color_out[0];
+            *g = color_out[1];
+            *b = color_out[2];
+        }
+    }
+}
 
 bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor* dest )
 {
@@ -508,6 +550,7 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor
                     if ( !errno ) {
                         if ( dest ) {
                             dest->colors.push_back( dbl );
+g_message("color: %f", dbl);
                         }
                         str = endPtr;
                     } else {
@@ -529,7 +572,7 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor
             while ( g_ascii_isspace(*str) ) {
                 str++;
             }
-            good &= *str == ')';
+            good &= (*str == ')');
         }
     }
 
@@ -550,7 +593,7 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor
 
 bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest )
 {
-    sp_svg_read_icc_color(str, NULL, dest);
+    return sp_svg_read_icc_color(str, NULL, dest);
 }
 
 /*
index d1238dcabe46e793d6d166f4b4a2eaaad829e786..a3868c149b9473293d50691b88b3db20bdfd7913 100644 (file)
@@ -11,5 +11,6 @@ void sp_svg_write_color(char *buf, unsigned int buflen, unsigned int rgba32);
 
 bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor* dest );
 bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest );
+void icc_color_to_sRGB(SVGICCColor* dest, guchar* r, guchar* g, guchar* b);
 
 #endif /* !SVG_SVG_COLOR_H_SEEN */
index 144e42aa2a194d60a2df07774cbf21d0de9be796..ae837117afcd1df2d36a204b2b1198e2b858e60a 100644 (file)
 #if ENABLE_LCMS
 #include "color-profile-fns.h"
 #include "color-profile.h"
-//#define DEBUG_LCMS
-#if 1 //DEBUG_LCMS
+#define DEBUG_LCMS
+#ifdef DEBUG_LCMS
 #include "preferences.h"
 #include <gtk/gtkmessagedialog.h>
 #endif // DEBUG_LCMS
 #endif // ENABLE_LCMS
 
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
 extern guint update_in_progress;
 #define DEBUG_MESSAGE(key, ...) \
 {\
@@ -475,11 +475,11 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
 
     if ( name ) {
         if ( tmp.icc && tmp.icc->colorProfile == name ) {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
              g_message("Already at name [%s]", name );
 #endif // DEBUG_LCMS
         } else {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
              g_message("Need to switch to profile [%s]", name );
 #endif // DEBUG_LCMS
             if ( tmp.icc ) {
@@ -498,12 +498,12 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
                         SP_RGBA32_G_U(val),
                         SP_RGBA32_B_U(val),
                         255};
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
                     g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
 #endif // DEBUG_LCMS
                     icUInt16Number post[4] = {0,0,0,0};
                     cmsDoTransform( trans, pre, post, 1 );
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
                     g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]);
 #endif // DEBUG_LCMS
                     guint count = _cmsChannelsOf( newProf->getColorSpace() );
@@ -515,7 +515,7 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
 
                     for ( guint i = 0; i < count; i++ ) {
                         gdouble val = (((gdouble)post[i])/65535.0) * (gdouble)scales[i];
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
                         g_message("     scaled %d by %d to be %f", i, scales[i], val);
 #endif // DEBUG_LCMS
                         tmp.icc->colors.push_back(val);
@@ -523,7 +523,7 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
                     cmsHTRANSFORM retrans = newProf->getTransfToSRGB8();
                     if ( retrans ) {
                         cmsDoTransform( retrans, post, pre, 1 );
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
                         g_message("  back out [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
 #endif // DEBUG_LCMS
                         tmp.set(SP_RGBA32_U_COMPOSE(pre[0], pre[1], pre[2], 0xff));
@@ -533,7 +533,7 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
             dirty = true;
         }
     } else {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
          g_message("NUKE THE ICC");
 #endif // DEBUG_LCMS
         if ( tmp.icc ) {
@@ -542,21 +542,21 @@ void ColorICCSelector::_switchToProfile( gchar const* name )
             dirty = true;
             _fixupHit( 0, this );
         } else {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
              g_message("No icc to nuke");
 #endif // DEBUG_LCMS
         }
     }
 
     if ( dirty ) {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
         g_message("+----------------");
         g_message("+   new color is [%s]", tmp.toString().c_str());
 #endif // DEBUG_LCMS
         _setProfile( tmp.icc );
         //_adjustmentChanged( _fooAdj[0], SP_COLOR_ICC_SELECTOR(_csel) );
         setColorAlpha( tmp, _alpha, true );
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
         g_message("+_________________");
 #endif // DEBUG_LCMS
     }
@@ -605,13 +605,13 @@ void ColorICCSelector::_colorChanged()
     _updating = TRUE;
      //sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color );
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message( "/^^^^^^^^^  %p::_colorChanged(%08x:%s)", this,
                _color.toRGBA32(_alpha), ( (_color.icc) ? _color.icc->colorProfile.c_str(): "<null>" )
                );
 #endif // DEBUG_LCMS
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message("FLIPPIES!!!!     %p   '%s'", _color.icc, (_color.icc ? _color.icc->colorProfile.c_str():"<null>"));
 #endif // DEBUG_LCMS
 
@@ -642,7 +642,7 @@ void ColorICCSelector::_colorChanged()
         if ( other != _color.toRGBA32(255) ) {
             _fixupNeeded = other;
             gtk_widget_set_sensitive( _fixupBtn, TRUE );
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
             g_message("Color needs to change 0x%06x to 0x%06x", _color.toRGBA32(255) >> 8, other >> 8 );
 #endif // DEBUG_LCMS
         }
@@ -654,7 +654,7 @@ void ColorICCSelector::_colorChanged()
 
 
     _updating = FALSE;
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message( "\\_________  %p::_colorChanged()", this );
 #endif // DEBUG_LCMS
 }
@@ -662,7 +662,7 @@ void ColorICCSelector::_colorChanged()
 #if ENABLE_LCMS
 void ColorICCSelector::_setProfile( SVGICCColor* profile )
 {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message( "/^^^^^^^^^  %p::_setProfile(%s)", this,
                ( (profile) ? profile->colorProfile.c_str() : "<null>")
                );
@@ -730,7 +730,7 @@ void ColorICCSelector::_setProfile( SVGICCColor* profile )
         }
     }
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message( "\\_________  %p::_setProfile()", this );
 #endif // DEBUG_LCMS
 }
@@ -800,7 +800,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC
 //         gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
 //     }
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message( "/^^^^^^^^^  %p::_adjustmentChanged()", cs );
 #endif // DEBUG_LCMS
 
@@ -816,7 +816,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC
      SPColor newColor( iccSelector->_color );
      gfloat scaled = ColorScales::getScaled( iccSelector->_adj );
      if ( iccSelector->_adj == adjustment ) {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
          g_message("ALPHA");
 #endif // DEBUG_LCMS
      } else {
@@ -828,7 +828,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC
              }
          }
          if ( match >= 0 ) {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
              g_message(" channel %d", match );
 #endif // DEBUG_LCMS
          }
@@ -852,7 +852,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC
          guint32 newer = other.toRGBA32(255);
 
          if ( prior != newer ) {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
              g_message("Transformed color from 0x%08x to 0x%08x", prior, newer );
              g_message("      ~~~~ FLIP");
 #endif // DEBUG_LCMS
@@ -875,7 +875,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC
      iccSelector->_updateSliders( match );
 
      iccSelector->_updating = FALSE;
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
      g_message( "\\_________  %p::_adjustmentChanged()", cs );
 #endif // DEBUG_LCMS
 }
@@ -900,13 +900,13 @@ void ColorICCSelector::_sliderReleased( SPColorSlider */*slider*/, SPColorICCSel
 //     }
 }
 
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
 void ColorICCSelector::_sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs )
 #else
 void ColorICCSelector::_sliderChanged( SPColorSlider */*slider*/, SPColorICCSelector */*cs*/ )
 #endif // DEBUG_LCMS
 {
-#if 1 //DEBUG_LCMS
+#ifdef DEBUG_LCMS
     g_message("Changed  %p and %p", slider, cs );
 #endif // DEBUG_LCMS
 //     ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base);