You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ss...@apache.org on 2017/09/11 08:51:52 UTC

svn commit: r1808000 - /xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java

Author: ssteiner
Date: Mon Sep 11 08:51:52 2017
New Revision: 1808000

URL: http://svn.apache.org/viewvc?rev=1808000&view=rev
Log:
BATIK-1170: Incorrect ColorConvertOp alpha handling breaks masking

Modified:
    xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java

Modified: xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java?rev=1808000&r1=1807999&r2=1808000&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java (original)
+++ xmlgraphics/batik/trunk/batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/rendered/Any2LumRed.java Mon Sep 11 08:51:52 2017
@@ -19,6 +19,9 @@
 package org.apache.batik.ext.awt.image.rendered;
 
 
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Transparency;
 import java.awt.color.ColorSpace;
@@ -45,19 +48,23 @@ import org.apache.batik.ext.awt.image.Gr
  * @version $Id$ */
 public class Any2LumRed extends AbstractRed {
 
+    boolean isColorConvertOpAplhaSupported;
+
     /**
      * Construct a luminace image from src.
      *
      * @param src The image to convert to a luminance image
      */
     public Any2LumRed(CachableRed src) {
-        super(src,src.getBounds(), 
+        super(src,src.getBounds(),
               fixColorModel(src),
               fixSampleModel(src),
               src.getTileGridXOffset(),
               src.getTileGridYOffset(),
               null);
 
+        isColorConvertOpAplhaSupported = getColorConvertOpAplhaSupported();
+
         props.put(ColorSpaceHintKey.PROPERTY_COLORSPACE,
                   ColorSpaceHintKey.VALUE_COLORSPACE_GREY);
     }
@@ -88,31 +95,29 @@ public class Any2LumRed extends Abstract
             WritableRaster srcWr  = (WritableRaster)srcRas;
 
             // Divide out alpha if we have it.  We need to do this since
-            // the color convert may not be a linear operation which may 
+            // the color convert may not be a linear operation which may
             // lead to out of range values.
             if (srcCM.hasAlpha())
                 GraphicsUtil.coerceData(srcWr, srcCM, false);
 
             BufferedImage srcBI, dstBI;
-            srcBI = new BufferedImage(srcCM, 
+            srcBI = new BufferedImage(srcCM,
                                       srcWr.createWritableTranslatedChild(0,0),
-                                      false, 
+                                      false,
                                       null);
             ColorModel dstCM = getColorModel();
-            if (!dstCM.hasAlpha()) {
-                // No alpha ao we don't have to work around the bug
-                // in the color convert op.
-                dstBI = new BufferedImage
-                    (dstCM, wr.createWritableTranslatedChild(0,0),
-                     dstCM.isAlphaPremultiplied(), null);
-            } else {
+
+            if (dstCM.hasAlpha() && !isColorConvertOpAplhaSupported) {
+
                 // All this nonsense is to work around the fact that the
                 // Color convert op doesn't properly copy the Alpha from
-                // src to dst.
+                // src to dst:
+                // https://bugs.openjdk.java.net/browse/JDK-8005930
+
                 PixelInterleavedSampleModel dstSM;
                 dstSM = (PixelInterleavedSampleModel)wr.getSampleModel();
                 SampleModel smna = new PixelInterleavedSampleModel
-                    (dstSM.getDataType(),    
+                    (dstSM.getDataType(),
                      dstSM.getWidth(),       dstSM.getHeight(),
                      dstSM.getPixelStride(), dstSM.getScanlineStride(),
                      new int [] { 0 });
@@ -126,14 +131,20 @@ public class Any2LumRed extends Abstract
                      wr.getMinY()-wr.getSampleModelTranslateY(),
                      wr.getWidth(), wr.getHeight(),
                      0, 0, null);
-                
+
                 ColorModel cmna = new ComponentColorModel
                     (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                      new int [] {8}, false, false,
-                     Transparency.OPAQUE, 
+                     Transparency.OPAQUE,
                      DataBuffer.TYPE_BYTE);
 
                 dstBI = new BufferedImage(cmna, dstWr, false, null);
+            } else {
+                // No alpha ao we don't have to work around the bug
+                // in the color convert op.
+                dstBI = new BufferedImage
+                    (dstCM, wr.createWritableTranslatedChild(0,0),
+                     dstCM.isAlphaPremultiplied(), null);
             }
 
             ColorConvertOp op = new ColorConvertOp(null);
@@ -163,15 +174,15 @@ public class Any2LumRed extends Abstract
                     (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                      new int [] {8,8}, true,
                      cm.isAlphaPremultiplied(),
-                     Transparency.TRANSLUCENT, 
+                     Transparency.TRANSLUCENT,
                      DataBuffer.TYPE_BYTE);
 
             return new ComponentColorModel
                 (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                  new int [] {8}, false, false,
-                 Transparency.OPAQUE, 
+                 Transparency.OPAQUE,
                  DataBuffer.TYPE_BYTE);
-        } 
+        }
         else {
             // No ColorModel so try to make some intelligent
             // decisions based just on the number of bands...
@@ -184,13 +195,13 @@ public class Any2LumRed extends Abstract
                 return new ComponentColorModel
                     (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                      new int [] {8,8}, true,
-                     true, Transparency.TRANSLUCENT, 
+                     true, Transparency.TRANSLUCENT,
                      DataBuffer.TYPE_BYTE);
 
             return new ComponentColorModel
                 (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                  new int [] {8}, false, false,
-                 Transparency.OPAQUE, 
+                 Transparency.OPAQUE,
                  DataBuffer.TYPE_BYTE);
         }
     }
@@ -208,7 +219,7 @@ public class Any2LumRed extends Abstract
 
         ColorModel  cm = src.getColorModel();
         if (cm != null) {
-            if (cm.hasAlpha()) 
+            if (cm.hasAlpha())
                 return new PixelInterleavedSampleModel
                     (DataBuffer.TYPE_BYTE, width, height, 2, 2*width,
                      new int [] { 0, 1 });
@@ -233,4 +244,38 @@ public class Any2LumRed extends Abstract
                  new int [] { 0 });
         }
     }
+
+    protected static boolean getColorConvertOpAplhaSupported() {
+        int size = 50;
+
+        // create source image filled with an opaque color
+        BufferedImage srcImage = new BufferedImage(
+                size, size, BufferedImage.TYPE_INT_ARGB);
+
+        Graphics2D srcGraphics = srcImage.createGraphics();
+        srcGraphics.setColor(Color.red);
+        srcGraphics.fillRect(0, 0, size, size);
+        srcGraphics.dispose();
+
+        // create clear (transparent black) destination image
+        BufferedImage dstImage = new BufferedImage(
+                size, size, BufferedImage.TYPE_INT_ARGB);
+
+        Graphics2D dstGraphics = dstImage.createGraphics();
+        dstGraphics.setComposite(AlphaComposite.Clear);
+        dstGraphics.fillRect(0, 0, size, size);
+        dstGraphics.dispose();
+
+        ColorSpace grayColorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+        ColorConvertOp op = new ColorConvertOp(grayColorSpace, null);
+        op.filter(srcImage, dstImage);
+
+        return getAlpha(srcImage) == getAlpha(dstImage);
+    }
+
+    protected static int getAlpha(BufferedImage bufferedImage) {
+        int x = bufferedImage.getWidth() / 2;
+        int y = bufferedImage.getHeight() / 2;
+        return 0xff & (bufferedImage.getRGB(x, y) >> 24);
+    }
 }