Code

improving displacement map renderer.
authorjucablues <jucablues@users.sourceforge.net>
Thu, 26 Jul 2007 02:00:51 +0000 (02:00 +0000)
committerjucablues <jucablues@users.sourceforge.net>
Thu, 26 Jul 2007 02:00:51 +0000 (02:00 +0000)
src/display/nr-filter-displacement-map.cpp

index ec8681ad1fa5c03d1dcf1118fe1eadcf8ada29dd..7d32ce2e0abdff7acf9958f0f1880006dad5a677 100644 (file)
 
 #include "display/nr-filter-displacement-map.h"
 #include "display/nr-filter-types.h"
+#include "libnr/nr-pixops.h"
 
 namespace NR {
 
 FilterDisplacementMap::FilterDisplacementMap()
-: Xchannel(3),
-  Ychannel(3),
-  scale(0),
-  _input2(NR_FILTER_SLOT_NOT_SET)
+: scale(0),
+  _input2(NR_FILTER_SLOT_NOT_SET),
+   Xchannel(3),
+  Ychannel(3)
 {}
 
 FilterPrimitive * FilterDisplacementMap::create() {
@@ -50,22 +51,45 @@ int FilterDisplacementMap::render(FilterSlot &slot, Matrix const &trans) {
     unsigned char *out_data = NR_PIXBLOCK_PX(out);
     int x, y, x0, y0, x1, y1, width;
     double coordx, coordy;
-   
+//    unsigned int alpha; //used for demultiplication
+    
     x0 = out->area.x0;
     y0 = out->area.y0;
     x1 = out->area.x1;
     y1 = out->area.y1;
     width = x1 - x0;
-        
+
     for (x=x0 + scale/2; x < x1 - scale/2; x++){
         for (y=y0 + scale/2; y < y1 - scale/2; y++){
-            coordx = x-x0 + scale * ( ((double)map_data[4*((x-x0) + width*(y-y0)) + Xchannel])/255 - 0.5);
-            coordy = y-y0 + scale * ( ((double)map_data[4*((x-x0) + width*(y-y0)) + Ychannel])/255 - 0.5);
-            
-            out_data[4*((x-x0) + width*(y-y0))] = texture_data[4*(int)(coordx + coordy*width)];
-            out_data[4*((x-x0) + width*(y-y0)) + 1] = texture_data[4*(int)(coordx + coordy*width) + 1];
-            out_data[4*((x-x0) + width*(y-y0)) + 2] = texture_data[4*(int)(coordx + coordy*width) + 2];
-            out_data[4*((x-x0) + width*(y-y0)) + 3] = texture_data[4*(int)(coordx + coordy*width) + 3];
+/* SVG spec states that pixel values must be alpha-demultiplied before processing this filter operation.
+The following code does it, but when we DON'T do it, output is more similar to output from Batik.
+
+Batik output:
+ http://bighead.poli.usp.br/~juca/code/inkscape/batik-fed02.png
+Inkscape output without demultiplication:
+ http://bighead.poli.usp.br/~juca/code/inkscape/displacement-map-test.png
+ There is also this other bug that can be seen in the above screenshot: the lower and the right portions are not rendered, I dont know why.
+
+ --JucaBlues
+  
+            if (map->mode == NR_PIXBLOCK_MODE_R8G8B8A8P){
+                alpha = (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 3];
+                if (alpha==0){
+                    coordx = x-x0;
+                    coordy = y-y0;
+                } else {
+                    coordx = x-x0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Xchannel], alpha))/255 - 0.5 );
+                    coordy = y-y0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Ychannel], alpha))/255 - 0.5 );
+                }
+            } else {*/
+            coordx = x-x0 + scale * ( ((double) map_data[4*((x-x0) + width*(y-y0)) + Xchannel])/255 - 0.5 );
+            coordy = y-y0 + scale * ( ((double) map_data[4*((x-x0) + width*(y-y0)) + Ychannel])/255 - 0.5 );
+
+            out_data[4*((x-x0) + width*(y-y0))] = texture_data[4*((int)coordx + ((int)coordy)*width)];
+            out_data[4*((x-x0) + width*(y-y0)) + 1] = texture_data[4*((int)coordx + ((int)coordy)*width) + 1];
+            out_data[4*((x-x0) + width*(y-y0)) + 2] = texture_data[4*((int)coordx + ((int)coordy)*width) + 2];
+            out_data[4*((x-x0) + width*(y-y0)) + 3] = texture_data[4*((int)coordx + ((int)coordy)*width) + 3];
         }
     }