Skip to content

Commit dadd9cd

Browse files
Renjithkannathmrserbaivanov-jdk
committed
8316497: ColorConvertOp - typo for non-ICC conversions needs one-line fix
Co-authored-by: Sergey Bylokhov <[email protected]> Co-authored-by: Alexey Ivanov <[email protected]> Reviewed-by: aivanov, serb
1 parent de237fb commit dadd9cd

File tree

2 files changed

+155
-4
lines changed

2 files changed

+155
-4
lines changed

src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -768,7 +768,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src,
768768
}
769769
float[] srcMinVal = new float[iccSrcNumComp];
770770
float[] srcInvDiffMinMax = new float[iccSrcNumComp];
771-
for (int i = 0; i < srcNumComp; i++) {
771+
for (int i = 0; i < iccSrcNumComp; i++) {
772772
srcMinVal[i] = cs.getMinValue(i);
773773
srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
774774
}
@@ -782,7 +782,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src,
782782
}
783783
float[] dstMinVal = new float[iccDstNumComp];
784784
float[] dstDiffMinMax = new float[iccDstNumComp];
785-
for (int i = 0; i < dstNumComp; i++) {
785+
for (int i = 0; i < iccDstNumComp; i++) {
786786
dstMinVal[i] = cs.getMinValue(i);
787787
dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
788788
}
@@ -835,7 +835,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src,
835835
dstDiffMinMax[i] + dstMinVal[i];
836836
}
837837
if (nonICCDst) {
838-
color = srcColorSpace.fromCIEXYZ(dstColor);
838+
color = dstColorSpace.fromCIEXYZ(dstColor);
839839
for (int i = 0; i < dstNumComp; i++) {
840840
dstColor[i] = color[i];
841841
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.awt.Color;
25+
import java.awt.GradientPaint;
26+
import java.awt.Graphics2D;
27+
import java.awt.Transparency;
28+
import java.awt.color.ColorSpace;
29+
import java.awt.image.BufferedImage;
30+
import java.awt.image.ColorConvertOp;
31+
import java.awt.image.ComponentColorModel;
32+
import java.awt.image.DataBuffer;
33+
import java.awt.image.WritableRaster;
34+
35+
/*
36+
* @test
37+
* @bug 8316497
38+
* @summary Verifies Color filter on non-ICC profile
39+
*/
40+
public final class NonICCFilterTest {
41+
private static final int WIDTH = 100;
42+
private static final int HEIGHT = 100;
43+
44+
private enum ColorSpaceSelector {
45+
GRAY,
46+
RGB,
47+
PYCC,
48+
WRAPPED_GRAY,
49+
WRAPPED_RGB,
50+
WRAPPED_PYCC
51+
}
52+
53+
private static final class TestColorSpace extends ColorSpace {
54+
55+
private final ColorSpace cs;
56+
57+
TestColorSpace(ColorSpace cs) {
58+
super(cs.getType(), cs.getNumComponents());
59+
this.cs = cs;
60+
}
61+
62+
@Override
63+
public float[] toRGB(float[] colorvalue) {
64+
return cs.toRGB(colorvalue);
65+
}
66+
67+
@Override
68+
public float[] fromRGB(float[] rgbvalue) {
69+
return cs.fromRGB(rgbvalue);
70+
}
71+
72+
@Override
73+
public float[] toCIEXYZ(float[] colorvalue) {
74+
return cs.toCIEXYZ(colorvalue);
75+
}
76+
77+
@Override
78+
public float[] fromCIEXYZ(float[] xyzvalue) {
79+
return cs.fromCIEXYZ(xyzvalue);
80+
}
81+
}
82+
83+
private static BufferedImage createTestImage(final ColorSpace cs) {
84+
ComponentColorModel cm = new ComponentColorModel(cs, false, false,
85+
Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
86+
WritableRaster raster = cm.createCompatibleWritableRaster(WIDTH, HEIGHT);
87+
BufferedImage img = new BufferedImage(cm, raster, false, null);
88+
89+
Graphics2D g = img.createGraphics();
90+
GradientPaint gp = new GradientPaint(0, 0, Color.GREEN,
91+
raster.getWidth(), raster.getHeight(), Color.BLUE);
92+
g.setPaint(gp);
93+
g.fillRect(0, 0, raster.getWidth(), raster.getHeight());
94+
g.dispose();
95+
96+
return img;
97+
}
98+
99+
private static ColorSpace createCS(ColorSpaceSelector selector) {
100+
return switch (selector) {
101+
case GRAY -> ColorSpace.getInstance(ColorSpace.CS_GRAY);
102+
case WRAPPED_GRAY -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_GRAY));
103+
104+
case RGB -> ColorSpace.getInstance(ColorSpace.CS_sRGB);
105+
case WRAPPED_RGB -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_sRGB));
106+
107+
case PYCC -> ColorSpace.getInstance(ColorSpace.CS_PYCC);
108+
case WRAPPED_PYCC -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_PYCC));
109+
};
110+
}
111+
112+
private static boolean areImagesEqual(BufferedImage destTest, BufferedImage destGold) {
113+
for (int x = 0; x < destTest.getWidth(); x++) {
114+
for (int y = 0; y < destTest.getHeight(); y++) {
115+
int rgb1 = destTest.getRGB(x, y);
116+
int rgb2 = destGold.getRGB(x, y);
117+
if (rgb1 != rgb2) {
118+
System.err.println("x = " + x + ", y = " + y);
119+
System.err.println("rgb1 = " + Integer.toHexString(rgb1));
120+
System.err.println("rgb2 = " + Integer.toHexString(rgb2));
121+
return false;
122+
}
123+
}
124+
}
125+
return true;
126+
}
127+
128+
public static void main(String[] args) {
129+
BufferedImage srcTest = createTestImage(createCS(ColorSpaceSelector.WRAPPED_GRAY));
130+
BufferedImage destTest = createTestImage(createCS(ColorSpaceSelector.WRAPPED_RGB));
131+
132+
BufferedImage srcGold = createTestImage(createCS(ColorSpaceSelector.GRAY));
133+
BufferedImage destGold = createTestImage(createCS(ColorSpaceSelector.RGB));
134+
135+
ColorConvertOp gold = new ColorConvertOp(createCS(ColorSpaceSelector.PYCC), null);
136+
gold.filter(srcTest, destTest);
137+
gold.filter(srcGold, destGold);
138+
139+
if (!areImagesEqual(destTest, destGold)) {
140+
throw new RuntimeException("ICC test failed");
141+
}
142+
143+
ColorConvertOp test = new ColorConvertOp(createCS(ColorSpaceSelector.WRAPPED_PYCC), null);
144+
test.filter(srcTest, destTest);
145+
test.filter(srcGold, destGold);
146+
147+
if (!areImagesEqual(destTest, destGold)) {
148+
throw new RuntimeException("Wrapper test failed");
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)