From 1aba89f0833433d7dfb3c983dcc21d540a5566f5 Mon Sep 17 00:00:00 2001 From: bae Date: Mon, 24 Dec 2012 14:03:04 +0400 Subject: [PATCH] 7124245: [lcms] ColorConvertOp to color space CS_GRAY apparently converts orange to 244,244,0 Reviewed-by: prr --- .../classes/sun/java2d/cmm/lcms/LCMS.java | 4 +- .../sun/java2d/cmm/lcms/LCMSImageLayout.java | 3 +- .../sun/java2d/cmm/lcms/LCMSTransform.java | 17 ++- src/share/native/sun/java2d/cmm/lcms/LCMS.c | 27 ++--- .../java2d/cmm/ColorConvertOp/GrayTest.java | 102 ++++++++++++++++++ 5 files changed, 133 insertions(+), 20 deletions(-) create mode 100644 test/sun/java2d/cmm/ColorConvertOp/GrayTest.java diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/src/share/classes/sun/java2d/cmm/lcms/LCMS.java index 4ce85425f..5cfda3cdb 100644 --- a/src/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/src/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -53,7 +53,9 @@ public class LCMS implements PCMM { public static native long getProfileID(ICC_Profile profile); public static native long createNativeTransform( - long[] profileIDs, int renderType, int inFormatter, int outFormatter, + long[] profileIDs, int renderType, + int inFormatter, boolean isInIntPacked, + int outFormatter, boolean isOutIntPacked, Object disposerRef); /** diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java index c53f0def9..3695a1632 100644 --- a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java +++ b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java @@ -196,7 +196,8 @@ class LCMSImageLayout { case BufferedImage.TYPE_4BYTE_ABGR: byteRaster = (ByteComponentRaster)image.getRaster(); nextRowOffset = byteRaster.getScanlineStride(); - offset = byteRaster.getDataOffset(0); + int firstBand = image.getSampleModel().getNumBands() - 1; + offset = byteRaster.getDataOffset(firstBand); dataArray = byteRaster.getDataStorage(); dataType = DT_BYTE; break; diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index 07b5e4a3c..aa9d0bf05 100644 --- a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -55,8 +55,10 @@ import sun.java2d.cmm.lcms.*; public class LCMSTransform implements ColorTransform { long ID; - private int inFormatter; - private int outFormatter; + private int inFormatter = 0; + private boolean isInIntPacked = false; + private int outFormatter = 0; + private boolean isOutIntPacked = false; ICC_Profile[] profiles; long [] profileIDs; @@ -135,18 +137,23 @@ public class LCMSTransform implements ColorTransform { LCMSImageLayout out) { // update native transfrom if needed if (ID == 0L || - inFormatter != in.pixelType || - outFormatter != out.pixelType) { + inFormatter != in.pixelType || isInIntPacked != in.isIntPacked || + outFormatter != out.pixelType || isOutIntPacked != out.isIntPacked) + { if (ID != 0L) { // Disposer will destroy forgotten transform disposerReferent = new Object(); } inFormatter = in.pixelType; + isInIntPacked = in.isIntPacked; + outFormatter = out.pixelType; + isOutIntPacked = out.isIntPacked; ID = LCMS.createNativeTransform(profileIDs, renderType, - inFormatter, outFormatter, + inFormatter, isInIntPacked, + outFormatter, isOutIntPacked, disposerReferent); } diff --git a/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/src/share/native/sun/java2d/cmm/lcms/LCMS.c index 910969f95..7da0370ba 100644 --- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c +++ b/src/share/native/sun/java2d/cmm/lcms/LCMS.c @@ -159,7 +159,8 @@ void LCMS_freeTransform(JNIEnv *env, jlong ID) */ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform (JNIEnv *env, jclass cls, jlongArray profileIDs, jint renderType, - jint inFormatter, jint outFormatter, jobject disposerRef) + jint inFormatter, jboolean isInIntPacked, + jint outFormatter, jboolean isOutIntPacked, jobject disposerRef) { cmsHPROFILE _iccArray[DF_ICC_BUF_SIZE]; cmsHPROFILE *iccArray = &_iccArray[0]; @@ -170,6 +171,16 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform size = (*env)->GetArrayLength (env, profileIDs); ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0); +#ifdef _LITTLE_ENDIAN + /* Reversing data packed into int for LE archs */ + if (isInIntPacked) { + inFormatter ^= DOSWAP_SH(1); + } + if (isOutIntPacked) { + outFormatter ^= DOSWAP_SH(1); + } +#endif + if (DF_ICC_BUF_SIZE < size*2) { iccArray = (cmsHPROFILE*) malloc( size*2*sizeof(cmsHPROFILE)); @@ -567,7 +578,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert (JNIEnv *env, jclass obj, jobject trans, jobject src, jobject dst) { storeID_t sTrans; - int inFmt, outFmt, srcDType, dstDType; + int srcDType, dstDType; int srcOffset, srcNextRowOffset, dstOffset, dstNextRowOffset; int width, height, i; void* inputBuffer; @@ -576,23 +587,13 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert char* outputRow; jobject srcData, dstData; - inFmt = (*env)->GetIntField (env, src, IL_pixelType_fID); - outFmt = (*env)->GetIntField (env, dst, IL_pixelType_fID); srcOffset = (*env)->GetIntField (env, src, IL_offset_fID); srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID); dstOffset = (*env)->GetIntField (env, dst, IL_offset_fID); dstNextRowOffset = (*env)->GetIntField (env, dst, IL_nextRowOffset_fID); width = (*env)->GetIntField (env, src, IL_width_fID); height = (*env)->GetIntField (env, src, IL_height_fID); -#ifdef _LITTLE_ENDIAN - /* Reversing data packed into int for LE archs */ - if ((*env)->GetBooleanField (env, src, IL_isIntPacked_fID) == JNI_TRUE) { - inFmt ^= DOSWAP_SH(1); - } - if ((*env)->GetBooleanField (env, dst, IL_isIntPacked_fID) == JNI_TRUE) { - outFmt ^= DOSWAP_SH(1); - } -#endif + sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID); if (sTrans.xf == NULL) { diff --git a/test/sun/java2d/cmm/ColorConvertOp/GrayTest.java b/test/sun/java2d/cmm/ColorConvertOp/GrayTest.java new file mode 100644 index 000000000..06d829e60 --- /dev/null +++ b/test/sun/java2d/cmm/ColorConvertOp/GrayTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012, 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 7124245 + * @summary Test verifies that color conversion does not distort + * colors in destination image of standard type. + * + * @run main GrayTest + */ + +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 GrayTest { + public static void main(String[] args) { + GrayTest t = new GrayTest(); + + t.doTest(BufferedImage.TYPE_INT_RGB); + t.doTest(BufferedImage.TYPE_INT_BGR); + t.doTest(BufferedImage.TYPE_INT_ARGB); + t.doTest(BufferedImage.TYPE_3BYTE_BGR); + t.doTest(BufferedImage.TYPE_4BYTE_ABGR); + System.out.println("Test passed."); + } + + private static final int w = 3; + private static final int h = 3; + + private BufferedImage src; + private BufferedImage dst; + + private ColorConvertOp op; + + public GrayTest() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); + op = new ColorConvertOp(cs, null); + } + + private void render(Graphics2D g) { + g.setColor(Color.red); + g.fillRect(0, 0, w, h); + } + + private BufferedImage initImage(int type) { + BufferedImage img = new BufferedImage(w, h, type); + Graphics2D g = img.createGraphics(); + + render(g); + + g.dispose(); + + return img; + } + + public void doTest(int type) { + System.out.println("Test for type: " + type); + src = initImage(type); + + dst = initImage(type); + + dst = op.filter(src, dst); + + int pixel = dst.getRGB(1, 1); + int r = 0xff & (pixel >> 16); + int g = 0xff & (pixel >> 8); + int b = 0xff & (pixel ); + + System.out.printf("dst: r:%02x, g: %02x, %02x\n", + r, g, b); + + if (r != g || r != b) { + String msg = String.format("Invalid pixel: %08x", pixel); + throw new RuntimeException(msg); + } + System.out.println("Done."); + } +} -- GitLab