From d9216cb5e1c75d88dd87e19fdbbf2e4ea0b845cb Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Mon, 15 Apr 2013 16:57:01 +0400 Subject: [PATCH 1/2] 8005930: [lcms] ColorConvertOp: Alpha channel is not transferred from source to destination Reviewed-by: prr --- .../sun/java2d/cmm/lcms/LCMSTransform.java | 14 +-- .../java2d/cmm/ColorConvertOp/AlphaTest.java | 99 +++++++++++++++++++ 2 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 jdk/test/sun/java2d/cmm/ColorConvertOp/AlphaTest.java diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index de8a77c75f3..9f86dc6ade0 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -163,13 +163,15 @@ public class LCMSTransform implements ColorTransform { public void colorConvert(BufferedImage src, BufferedImage dst) { LCMSImageLayout srcIL, dstIL; - dstIL = LCMSImageLayout.createImageLayout(dst); + if (!dst.getColorModel().hasAlpha()) { + dstIL = LCMSImageLayout.createImageLayout(dst); - if (dstIL != null) { - srcIL = LCMSImageLayout.createImageLayout(src); - if (srcIL != null) { - doTransform(srcIL, dstIL); - return; + if (dstIL != null) { + srcIL = LCMSImageLayout.createImageLayout(src); + if (srcIL != null) { + doTransform(srcIL, dstIL); + return; + } } } diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/AlphaTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/AlphaTest.java new file mode 100644 index 00000000000..a532aecc0cc --- /dev/null +++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/AlphaTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8005930 + * @summary Thest verifies that color conversion does not distort + * alpha channel in the destination image. + * + * @run main AlphaTest + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; + +public class AlphaTest { + public static void main(String[] args) { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); + + ColorConvertOp op = new ColorConvertOp(cs, null); + // create source image filled with an opaque color + BufferedImage src = createSrc(); + int srcAlpha = getAlpha(src); + + System.out.printf("Src alpha: 0x%02x\n", srcAlpha); + + // create clear (transparent black) destination image + BufferedImage dst = createDst(); + int dstAlpha = getAlpha(dst); + System.out.printf("Dst alpha: 0x%02x\n", dstAlpha); + + + dst = op.filter(src, dst); + dstAlpha = getAlpha(dst); + // we expect that destination image is opaque + // i.e. alpha is transferred from source to + // the destination + System.out.printf("Result alpha: 0x%02x\n", dstAlpha); + + if (srcAlpha != dstAlpha) { + throw new RuntimeException("Test failed!"); + } + System.out.println("Test passed"); + } + + private static BufferedImage createSrc() { + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g = img.createGraphics(); + g.setColor(Color.red); + g.fillRect(0, 0, w, h); + g.dispose(); + + return img; + } + + private static BufferedImage createDst() { + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g = img.createGraphics(); + g.setComposite(AlphaComposite.Clear); + g.fillRect(0, 0, w, h); + g.dispose(); + + return img; + } + + private static int getAlpha(BufferedImage img) { + int argb = img.getRGB(w / 2, h / 2); + return 0xff & (argb >> 24); + } + + private static final int w = 100; + private static final int h = 100; +} From 92069b97d09488f107032895f67133674a7fd5de Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Mon, 15 Apr 2013 18:10:55 +0400 Subject: [PATCH 2/2] 8011622: Use lcms as the default color management module in jdk8 Reviewed-by: prr, vadim --- jdk/make/sun/cmm/Makefile | 3 +- jdk/make/sun/cmm/kcms/Makefile | 2 +- jdk/make/sun/cmm/lcms/Makefile | 2 +- jdk/makefiles/CompileNativeLibraries.gmk | 2 - jdk/makefiles/CopyIntoClasses.gmk | 4 +- .../sun/java2d/cmm/CMMServiceProvider.java | 37 +++++++++++++++++++ .../classes/sun/java2d/cmm/CMSManager.java | 27 +++++++++----- .../classes/sun/java2d/cmm/lcms/LCMS.java | 36 +++++++++++------- .../java2d/cmm/lcms/LcmsServiceProvider.java | 36 ++++++++++++++++++ .../sun.java2d.cmm.CMMServiceProvider | 2 + .../META-INF/services/sun.java2d.cmm.PCMM | 2 - 11 files changed, 121 insertions(+), 32 deletions(-) create mode 100644 jdk/src/share/classes/sun/java2d/cmm/CMMServiceProvider.java create mode 100644 jdk/src/share/classes/sun/java2d/cmm/lcms/LcmsServiceProvider.java create mode 100644 jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider delete mode 100644 jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM diff --git a/jdk/make/sun/cmm/Makefile b/jdk/make/sun/cmm/Makefile index 4b7710faab7..137b8d3d765 100644 --- a/jdk/make/sun/cmm/Makefile +++ b/jdk/make/sun/cmm/Makefile @@ -27,8 +27,9 @@ BUILDDIR = ../.. PRODUCT = sun include $(BUILDDIR)/common/Defs.gmk +SUBDIRS += lcms + ifdef OPENJDK - SUBDIRS += lcms ICCPROFILE_SRC_DIR = $(SHARE_SRC)/lib/cmm/lcms else # !OPENJDK SUBDIRS += kcms diff --git a/jdk/make/sun/cmm/kcms/Makefile b/jdk/make/sun/cmm/kcms/Makefile index 50b525671c5..65372af5d96 100644 --- a/jdk/make/sun/cmm/kcms/Makefile +++ b/jdk/make/sun/cmm/kcms/Makefile @@ -57,7 +57,7 @@ include $(BUILDDIR)/common/Library.gmk SERVICEDIR = $(CLASSBINDIR)/META-INF/services FILES_copy = \ - $(SERVICEDIR)/sun.java2d.cmm.PCMM + $(SERVICEDIR)/sun.java2d.cmm.CMMServiceProvider build: copy-files diff --git a/jdk/make/sun/cmm/lcms/Makefile b/jdk/make/sun/cmm/lcms/Makefile index 85b02e4960e..15afe61c3d8 100644 --- a/jdk/make/sun/cmm/lcms/Makefile +++ b/jdk/make/sun/cmm/lcms/Makefile @@ -58,7 +58,7 @@ include $(BUILDDIR)/common/Library.gmk SERVICEDIR = $(CLASSBINDIR)/META-INF/services FILES_copy = \ - $(SERVICEDIR)/sun.java2d.cmm.PCMM + $(SERVICEDIR)/sun.java2d.cmm.CMMServiceProvider build: copy-files diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 3bcf2fd6a9b..82115aec735 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -1213,7 +1213,6 @@ BUILD_LIBRARIES += $(BUILD_LIBJSDT) ########################################################################################## -ifdef OPENJDK # TODO: Update awt lib path when awt is converted $(eval $(call SetupNativeCompilation,BUILD_LIBLCMS,\ LIBRARY:=lcms,\ @@ -1246,7 +1245,6 @@ ifdef OPENJDK BUILD_LIBRARIES += $(BUILD_LIBLCMS) $(BUILD_LIBLCMS) : $(BUILD_LIBAWT) -endif ########################################################################################## diff --git a/jdk/makefiles/CopyIntoClasses.gmk b/jdk/makefiles/CopyIntoClasses.gmk index 549a58efd68..1d6e6a0c9ca 100644 --- a/jdk/makefiles/CopyIntoClasses.gmk +++ b/jdk/makefiles/CopyIntoClasses.gmk @@ -185,10 +185,10 @@ SRC_SERVICES_FILES:=$(wildcard $(addsuffix /services/*,$(ALL_META-INF_DIRS))) ifdef OPENJDK SRC_SERVICES_FILES:=$(filter-out %sun/dc/META-INF/services/sun.java2d.pipe.RenderingEngine,$(SRC_SERVICES_FILES)) - SRC_SERVICES_FILES:=$(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.PCMM,$(SRC_SERVICES_FILES)) + SRC_SERVICES_FILES:=$(filter-out %sun/java2d/cmm/kcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider,$(SRC_SERVICES_FILES)) else SRC_SERVICES_FILES:=$(filter-out %sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine,$(SRC_SERVICES_FILES)) - SRC_SERVICES_FILES:=$(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM,$(SRC_SERVICES_FILES)) + SRC_SERVICES_FILES:=$(filter-out %sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider,$(SRC_SERVICES_FILES)) endif # The number of services files are relatively few. If the increase in numbers, then diff --git a/jdk/src/share/classes/sun/java2d/cmm/CMMServiceProvider.java b/jdk/src/share/classes/sun/java2d/cmm/CMMServiceProvider.java new file mode 100644 index 00000000000..c3d37fbd8a9 --- /dev/null +++ b/jdk/src/share/classes/sun/java2d/cmm/CMMServiceProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.java2d.cmm; + +public abstract class CMMServiceProvider { + public final PCMM getColorManagementModule() { + if (CMSManager.canCreateModule()) { + return getModule(); + } + return null; + } + + protected abstract PCMM getModule(); +} diff --git a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java index a6df658796f..1e24504b45a 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java +++ b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java @@ -52,26 +52,29 @@ public class CMSManager { return cmmImpl; } - cmmImpl = (PCMM)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - String cmmClass = System.getProperty( - "sun.java2d.cmm", "sun.java2d.cmm.kcms.CMM"); + CMMServiceProvider spi = AccessController.doPrivileged( + new PrivilegedAction() { + public CMMServiceProvider run() { + String cmmClass = System.getProperty( + "sun.java2d.cmm", "sun.java2d.cmm.lcms.LcmsServiceProvider"); - ServiceLoader cmmLoader - = ServiceLoader.loadInstalled(PCMM.class); + ServiceLoader cmmLoader + = ServiceLoader.loadInstalled(CMMServiceProvider.class); - PCMM service = null; + CMMServiceProvider spi = null; - for (PCMM cmm : cmmLoader) { - service = cmm; + for (CMMServiceProvider cmm : cmmLoader) { + spi = cmm; if (cmm.getClass().getName().equals(cmmClass)) { break; } } - return service; + return spi; } }); + cmmImpl = spi.getColorManagementModule(); + if (cmmImpl == null) { throw new CMMException("Cannot initialize Color Management System."+ "No CM module found"); @@ -86,6 +89,10 @@ public class CMSManager { return cmmImpl; } + static synchronized boolean canCreateModule() { + return (cmmImpl == null); + } + /* CMM trace routines */ public static class CMMTracer implements PCMM { diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java index c6eae65a73a..f7ecc0b67c9 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -148,22 +148,32 @@ public class LCMS implements PCMM { public static native void initLCMS(Class Trans, Class IL, Class Pf); - /* the class initializer which loads the CMM */ - static { + private LCMS() {}; + + private static LCMS theLcms = null; + + static synchronized PCMM getModule() { + if (theLcms != null) { + return theLcms; + } + java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* We need to load awt here because of usage trace and - * disposer frameworks - */ - System.loadLibrary("awt"); - System.loadLibrary("lcms"); - return null; - } - } - ); + new java.security.PrivilegedAction() { + public Object run() { + /* We need to load awt here because of usage trace and + * disposer frameworks + */ + System.loadLibrary("awt"); + System.loadLibrary("lcms"); + return null; + } + }); initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class); + + theLcms = new LCMS(); + + return theLcms; } private static class TagData { diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LcmsServiceProvider.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LcmsServiceProvider.java new file mode 100644 index 00000000000..02cc90bc718 --- /dev/null +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LcmsServiceProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.java2d.cmm.lcms; + +import sun.java2d.cmm.CMMServiceProvider; +import sun.java2d.cmm.PCMM; + +public final class LcmsServiceProvider extends CMMServiceProvider { + @Override + protected PCMM getModule() { + return LCMS.getModule(); + } +} diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider b/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider new file mode 100644 index 00000000000..ce7ea564ffb --- /dev/null +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.CMMServiceProvider @@ -0,0 +1,2 @@ +# Little CMS color management module +sun.java2d.cmm.lcms.LcmsServiceProvider diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM b/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM deleted file mode 100644 index b30209a2220..00000000000 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM +++ /dev/null @@ -1,2 +0,0 @@ -# Little CMS color management module -sun.java2d.cmm.lcms.LCMS