Skip to content

Commit 78a08a0

Browse files
committed
8295430: Use cmsDoTransformLineStride instead of cmsDoTransform in the loop
Reviewed-by: prr
1 parent f0a6e71 commit 78a08a0

File tree

6 files changed

+344
-38
lines changed

6 files changed

+344
-38
lines changed

src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java

-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ public ColorTransform createTransform(int renderingIntent,
140140
static native void colorConvert(long trans, int width, int height,
141141
int srcOffset, int srcNextRowOffset,
142142
int dstOffset, int dstNextRowOffset,
143-
boolean srcAtOnce, boolean dstAtOnce,
144143
Object srcData, Object dstData,
145144
int srcType, int dstType);
146145

src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java

-24
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ public static int CHANNELS_SH(int x) {
7979
private int nextPixelOffset;
8080
int offset;
8181

82-
/* This flag indicates whether the image can be processed
83-
* at once by doTransfrom() native call. Otherwise, the
84-
* image is processed scan by scan.
85-
*/
86-
boolean imageAtOnce = false;
8782
Object dataArray;
8883

8984
private int dataArrayLength; /* in bytes */
@@ -234,10 +229,6 @@ public static LCMSImageLayout createImageLayout(BufferedImage image) throws Imag
234229
l.dataArray = intRaster.getDataStorage();
235230
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
236231
l.dataType = DT_INT;
237-
238-
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
239-
l.imageAtOnce = true;
240-
}
241232
} while (false);
242233
break;
243234

@@ -254,9 +245,6 @@ public static LCMSImageLayout createImageLayout(BufferedImage image) throws Imag
254245
l.dataArray = byteRaster.getDataStorage();
255246
l.dataArrayLength = byteRaster.getDataStorage().length;
256247
l.dataType = DT_BYTE;
257-
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
258-
l.imageAtOnce = true;
259-
}
260248
} while (false);
261249
break;
262250

@@ -271,10 +259,6 @@ public static LCMSImageLayout createImageLayout(BufferedImage image) throws Imag
271259
l.offset = byteRaster.getDataOffset(0);
272260
l.dataArray = byteRaster.getDataStorage();
273261
l.dataType = DT_BYTE;
274-
275-
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
276-
l.imageAtOnce = true;
277-
}
278262
} while (false);
279263
break;
280264

@@ -289,10 +273,6 @@ public static LCMSImageLayout createImageLayout(BufferedImage image) throws Imag
289273
l.dataArray = shortRaster.getDataStorage();
290274
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
291275
l.dataType = DT_SHORT;
292-
293-
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
294-
l.imageAtOnce = true;
295-
}
296276
} while (false);
297277
break;
298278
default:
@@ -409,10 +389,6 @@ public static LCMSImageLayout createImageLayout(Raster r) {
409389

410390
l.width = br.getWidth();
411391
l.height = br.getHeight();
412-
413-
if (l.nextRowOffset == l.width * br.getPixelStride()) {
414-
l.imageAtOnce = true;
415-
}
416392
return l;
417393
}
418394
return null;

src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java

-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ private void doTransform(LCMSImageLayout in, LCMSImageLayout out) {
133133
}
134134
LCMS.colorConvert(tfm.ID, in.width, in.height, in.offset,
135135
in.nextRowOffset, out.offset, out.nextRowOffset,
136-
in.imageAtOnce, out.imageAtOnce,
137136
in.dataArray, out.dataArray,
138137
in.dataType, out.dataType);
139138
Reference.reachabilityFence(tfm); // prevent deallocation of "tfm.ID"

src/java.desktop/share/native/liblcms/LCMS.c

+4-12
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,6 @@ static void releaseILData(JNIEnv *env, void *pData, jint type, jobject data,
522522
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
523523
(JNIEnv *env, jclass cls, jlong ID, jint width, jint height, jint srcOffset,
524524
jint srcNextRowOffset, jint dstOffset, jint dstNextRowOffset,
525-
jboolean srcAtOnce, jboolean dstAtOnce,
526525
jobject srcData, jobject dstData, jint srcDType, jint dstDType)
527526
{
528527
cmsHTRANSFORM sTrans = jlong_to_ptr(ID);
@@ -548,18 +547,11 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
548547
return;
549548
}
550549

551-
char *inputRow = (char *) inputBuffer + srcOffset;
552-
char *outputRow = (char *) outputBuffer + dstOffset;
550+
char *input = (char *) inputBuffer + srcOffset;
551+
char *output = (char *) outputBuffer + dstOffset;
553552

554-
if (srcAtOnce && dstAtOnce) {
555-
cmsDoTransform(sTrans, inputRow, outputRow, width * height);
556-
} else {
557-
for (int i = 0; i < height; i++) {
558-
cmsDoTransform(sTrans, inputRow, outputRow, width);
559-
inputRow += srcNextRowOffset;
560-
outputRow += dstNextRowOffset;
561-
}
562-
}
553+
cmsDoTransformLineStride(sTrans, input, output, width, height,
554+
srcNextRowOffset, dstNextRowOffset, 0, 0);
563555

564556
releaseILData(env, inputBuffer, srcDType, srcData, JNI_ABORT);
565557
releaseILData(env, outputBuffer, dstDType, dstData, 0);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/*
2+
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
3+
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
import java.awt.AlphaComposite;
26+
import java.awt.Color;
27+
import java.awt.Graphics2D;
28+
import java.awt.Image;
29+
import java.awt.Transparency;
30+
import java.awt.color.ColorSpace;
31+
import java.awt.image.BufferedImage;
32+
import java.awt.image.ColorConvertOp;
33+
import java.awt.image.ColorModel;
34+
import java.awt.image.ComponentColorModel;
35+
import java.awt.image.DataBuffer;
36+
import java.awt.image.Raster;
37+
import java.awt.image.WritableRaster;
38+
import java.io.File;
39+
40+
import javax.imageio.ImageIO;
41+
42+
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
43+
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
44+
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
45+
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
46+
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
47+
import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
48+
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
49+
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
50+
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
51+
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
52+
import static java.awt.image.BufferedImage.TYPE_USHORT_555_RGB;
53+
import static java.awt.image.BufferedImage.TYPE_USHORT_565_RGB;
54+
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
55+
56+
/**
57+
* @test
58+
* @bug 8295430
59+
* @summary Tests various conversions from/to custom 3BYTE_BGR image
60+
*/
61+
public final class FilterImageLineGap {
62+
63+
private static final int[] TYPES = {
64+
TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
65+
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE,
66+
TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
67+
TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, TYPE_BYTE_INDEXED
68+
};
69+
70+
private static final int[] CSS = {
71+
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
72+
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
73+
};
74+
75+
private static final int W = 511;
76+
private static final int H = 255;
77+
78+
public static void main(String[] args) throws Exception {
79+
for (int fromIndex : CSS) {
80+
for (int toIndex : CSS) {
81+
customToCustom(fromIndex, toIndex);
82+
customToAny(fromIndex, toIndex);
83+
anytoCustom(fromIndex, toIndex);
84+
}
85+
}
86+
}
87+
88+
private static void customToCustom(int fromIndex, int toIndex)
89+
throws Exception
90+
{
91+
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
92+
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
93+
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
94+
BufferedImage src = makeCustom3BYTE_BGR();
95+
BufferedImage dst = makeCustom3BYTE_BGR();
96+
97+
BufferedImage srcGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
98+
BufferedImage dstGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
99+
fill(src);
100+
fill(srcGold);
101+
102+
op.filter(src, dst);
103+
op.filter(srcGold, dstGold);
104+
// validate images
105+
for (int x = 0; x < W; ++x) {
106+
for (int y = 0; y < H; ++y) {
107+
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
108+
ImageIO.write(dst, "png", new File("custom.png"));
109+
ImageIO.write(dstGold, "png", new File("gold.png"));
110+
throw new RuntimeException("Test failed.");
111+
}
112+
}
113+
}
114+
}
115+
116+
private static void customToAny(int fromIndex, int toIndex) throws Exception
117+
{
118+
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
119+
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
120+
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
121+
for (int type : TYPES) {
122+
BufferedImage src = makeCustom3BYTE_BGR();
123+
BufferedImage dst = new BufferedImage(W, H, type);
124+
125+
BufferedImage srcGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
126+
BufferedImage dstGold = new BufferedImage(W, H, type);
127+
fill(src);
128+
fill(srcGold);
129+
130+
op.filter(src, dst);
131+
op.filter(srcGold, dstGold);
132+
// validate images
133+
for (int x = 0; x < W; ++x) {
134+
for (int y = 0; y < H; ++y) {
135+
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
136+
ImageIO.write(dst, "png", new File("custom.png"));
137+
ImageIO.write(dstGold, "png", new File("gold.png"));
138+
throw new RuntimeException("Test failed.");
139+
}
140+
}
141+
}
142+
}
143+
}
144+
145+
private static void anytoCustom(int fromIndex, int toIndex) throws Exception
146+
{
147+
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
148+
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
149+
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
150+
for (int type : TYPES) {
151+
BufferedImage src = new BufferedImage(W, H, type);
152+
BufferedImage dst = makeCustom3BYTE_BGR();
153+
154+
BufferedImage srcGold = new BufferedImage(W, H, type);
155+
BufferedImage dstGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
156+
fill(src);
157+
fill(srcGold);
158+
159+
op.filter(src, dst);
160+
op.filter(srcGold, dstGold);
161+
// validate images
162+
for (int x = 0; x < W; ++x) {
163+
for (int y = 0; y < H; ++y) {
164+
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
165+
ImageIO.write(dst, "png", new File("custom.png"));
166+
ImageIO.write(dstGold, "png", new File("gold.png"));
167+
throw new RuntimeException("Test failed.");
168+
}
169+
}
170+
}
171+
}
172+
}
173+
174+
/**
175+
* Returns the custom buffered image, which mostly identical to
176+
* BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
177+
* This means that the raster will have gaps, between the rows.
178+
*/
179+
private static BufferedImage makeCustom3BYTE_BGR() {
180+
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
181+
int[] nBits = {8, 8, 8};
182+
int[] bOffs = {2, 1, 0};
183+
ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
184+
Transparency.OPAQUE,
185+
DataBuffer.TYPE_BYTE);
186+
WritableRaster raster = Raster.createInterleavedRaster(
187+
DataBuffer.TYPE_BYTE, W, H, W * 3 + 2, 3, bOffs, null);
188+
return new BufferedImage(colorModel, raster, true, null);
189+
}
190+
191+
private static void fill(Image image) {
192+
Graphics2D graphics = (Graphics2D) image.getGraphics();
193+
graphics.setComposite(AlphaComposite.Src);
194+
for (int i = 0; i < image.getHeight(null); ++i) {
195+
graphics.setColor(new Color(i, 0, 255 - i));
196+
graphics.fillRect(0, i, image.getWidth(null), 1);
197+
}
198+
graphics.dispose();
199+
}
200+
}

0 commit comments

Comments
 (0)