[librsvg/librsvg-2.40] bgo#603550 - Compute the luminance correctly when generating a mask



commit 84f7a64179615a23936022cde148e109ecd56b50
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Dec 12 15:19:42 2016 -0600

    bgo#603550 - Compute the luminance correctly when generating a mask
    
    Thanks to Mike Lewis for the patch.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=603550

 rsvg-cairo-draw.c                                  |   25 ++++-
 .../reftests/bugs/603550-mask-luminance-ref.png    |  Bin 0 -> 4502 bytes
 .../reftests/bugs/603550-mask-luminance.svg        |  130 ++++++++++++++++++++
 3 files changed, 152 insertions(+), 3 deletions(-)
---
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 6c6df1c..c29d071 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -770,9 +770,28 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
         guint8 *row_data = (pixels + (row * rowstride));
         for (i = 0; i < width; i++) {
             guint32 *pixel = (guint32 *) row_data + i;
-            *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
-                       ((*pixel & 0x0000ff00) >> 8) * 46518 +
-                       ((*pixel & 0x000000ff)) * 4688) * state->opacity);
+            /*
+             *  Assuming, the pixel is linear RGB (not sRGB)
+             *  y = luminance
+             *  Y = 0.2126 R + 0.7152 G + 0.0722 B
+             *  1.0 opacity = 255
+             *
+             *  When Y = 1.0, pixel for mask should be 0xFFFFFFFF
+             *         (you get 1.0 luminance from 255 from R, G and B)
+             *
+             * r_mult = 0xFFFFFFFF / (255.0 * 255.0) * .2126 = 14042.45  ~= 14042
+             * g_mult = 0xFFFFFFFF / (255.0 * 255.0) * .7152 = 47239.69  ~= 47240
+             * b_mult = 0xFFFFFFFF / (255.0 * 255.0) * .0722 =  4768.88  ~= 4769
+             *
+             *         This allows for the following expected behaviour:
+             *  (we only care about the most sig byte)
+             * if pixel = 0x00FFFFFF, pixel' = 0xFF......
+             * if pixel = 0x00020202, pixel' = 0x02......
+             * if pixel = 0x00000000, pixel' = 0x00......
+             */
+            *pixel = ((((*pixel & 0x00ff0000) >> 16) * 14042 +
+                       ((*pixel & 0x0000ff00) >>  8) * 47240 +
+                       ((*pixel & 0x000000ff)      ) * 4769    ) * state->opacity);
         }
     }
 
diff --git a/tests/fixtures/reftests/bugs/603550-mask-luminance-ref.png 
b/tests/fixtures/reftests/bugs/603550-mask-luminance-ref.png
new file mode 100644
index 0000000..0f16941
Binary files /dev/null and b/tests/fixtures/reftests/bugs/603550-mask-luminance-ref.png differ
diff --git a/tests/fixtures/reftests/bugs/603550-mask-luminance.svg 
b/tests/fixtures/reftests/bugs/603550-mask-luminance.svg
new file mode 100644
index 0000000..19c40b2
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/603550-mask-luminance.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+       xmlns:svg="http://www.w3.org/2000/svg";
+       xmlns="http://www.w3.org/2000/svg";
+       width="744.09448819"
+       height="1052.3622047">
+       <defs
+               id="defs34">
+               <mask
+                       maskUnits="userSpaceOnUse"
+                       id="masky"
+                       x="0"
+                       y="0"
+                       width='500'
+                       height='500'>
+                       <g>
+                               <rect
+                                       style="fill:white; stroke:none"
+                                       id="rect128"
+                                       width="500"
+                                       height="500"
+                                       x="0"
+                                       y="0" />
+                       </g>
+               </mask>
+       </defs>
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+               <rect
+                       style="fill:#000000;fill-opacity:1;stroke:none"
+                       id="rect42"
+                       width="600"
+                       height="300"
+                       x="0"
+                       y="0"/>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+       <g mask="url(#masky)" >
+               <rect
+                       style="fill:#000000;fill-opacity:1;stroke:none"
+                       id="rect42"
+                       width="600"
+                       height="300"
+                       x="0"
+                       y="300"/>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       </g>
+       <rect
+               style="fill:#000000;fill-opacity:1;stroke:none"
+               id="rect42"
+               width="50"
+               height="600"
+               x="275"
+               y="0"/>
+</svg>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]