8279216: Investigate implementation of premultiplied alpha in the Little-CMS 2.13
Reviewed-by: prr
This commit is contained in:
parent
723037a79d
commit
117c5b116b
src/java.desktop/share/classes/sun/java2d/cmm/lcms
test/jdk/sun/java2d/cmm/ColorConvertOp
@ -52,16 +52,22 @@ final class LCMSImageLayout {
|
||||
static int CHANNELS_SH(int x) {
|
||||
return x << 3;
|
||||
}
|
||||
|
||||
static int PREMUL_SH(int x) {
|
||||
return x << 23;
|
||||
}
|
||||
private static final int SWAPFIRST = 1 << 14;
|
||||
private static final int DOSWAP = 1 << 10;
|
||||
private static final int PT_GRAY_8 = CHANNELS_SH(1) | BYTES_SH(1);
|
||||
private static final int PT_GRAY_16 = CHANNELS_SH(1) | BYTES_SH(2);
|
||||
private static final int PT_RGB_8 = CHANNELS_SH(3) | BYTES_SH(1);
|
||||
private static final int PT_RGBA_8 = PT_RGB_8 | EXTRA_SH(1);
|
||||
private static final int PT_ARGB_8 = PT_RGBA_8 | SWAPFIRST;
|
||||
private static final int PT_BGR_8 = PT_RGB_8 | DOSWAP;
|
||||
private static final int PT_ABGR_8 = PT_BGR_8 | EXTRA_SH(1);
|
||||
// private static final int PT_BGRA_8 = PT_ABGR_8 | SWAPFIRST;
|
||||
private static final int PT_GRAY_8 = CHANNELS_SH(1) | BYTES_SH(1);
|
||||
private static final int PT_GRAY_16 = CHANNELS_SH(1) | BYTES_SH(2);
|
||||
private static final int PT_RGB_8 = CHANNELS_SH(3) | BYTES_SH(1);
|
||||
private static final int PT_RGBA_8 = PT_RGB_8 | EXTRA_SH(1);
|
||||
private static final int PT_ARGB_8 = PT_RGBA_8 | SWAPFIRST;
|
||||
private static final int PT_ARGB_8_PREMUL = PT_ARGB_8 | PREMUL_SH(1);
|
||||
private static final int PT_BGR_8 = PT_RGB_8 | DOSWAP;
|
||||
private static final int PT_ABGR_8 = PT_BGR_8 | EXTRA_SH(1);
|
||||
private static final int PT_ABGR_8_PREMUL = PT_ABGR_8 | PREMUL_SH(1);
|
||||
// private static final int PT_BGRA_8 = PT_ABGR_8 | SWAPFIRST;
|
||||
private static final int SWAP_ENDIAN =
|
||||
ByteOrder.nativeOrder() == LITTLE_ENDIAN ? DOSWAP : 0;
|
||||
private static final int DT_BYTE = 0;
|
||||
@ -148,6 +154,9 @@ final class LCMSImageLayout {
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN;
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
l.pixelType = PT_ARGB_8_PREMUL ^ SWAP_ENDIAN;
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN;
|
||||
break;
|
||||
@ -160,6 +169,9 @@ final class LCMSImageLayout {
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
l.pixelType = PT_ABGR_8;
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
l.pixelType = PT_ABGR_8_PREMUL;
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
l.pixelType = PT_GRAY_8;
|
||||
break;
|
||||
@ -172,10 +184,7 @@ final class LCMSImageLayout {
|
||||
* has to be supported.
|
||||
*/
|
||||
ColorModel cm = image.getColorModel();
|
||||
// lcms as of now does not support pre-alpha
|
||||
if (!cm.isAlphaPremultiplied()
|
||||
&& cm instanceof ComponentColorModel ccm)
|
||||
{
|
||||
if (cm instanceof ComponentColorModel ccm) {
|
||||
// verify whether the component size is fine
|
||||
int[] cs = ccm.getComponentSize();
|
||||
for (int s : cs) {
|
||||
@ -183,7 +192,7 @@ final class LCMSImageLayout {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return createImageLayout(image.getRaster(), cm.hasAlpha());
|
||||
return createImageLayout(image.getRaster(), cm);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -194,6 +203,7 @@ final class LCMSImageLayout {
|
||||
switch (image.getType()) {
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
do {
|
||||
IntegerComponentRaster intRaster = (IntegerComponentRaster)
|
||||
@ -209,13 +219,14 @@ final class LCMSImageLayout {
|
||||
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
do {
|
||||
ByteComponentRaster byteRaster = (ByteComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = byteRaster.getScanlineStride();
|
||||
l.nextPixelOffset = byteRaster.getPixelStride();
|
||||
|
||||
int firstBand = image.getSampleModel().getNumBands() - 1;
|
||||
int firstBand = byteRaster.getSampleModel().getNumBands() - 1;
|
||||
l.offset = byteRaster.getDataOffset(firstBand);
|
||||
l.dataArray = byteRaster.getDataStorage();
|
||||
l.dataArrayLength = byteRaster.getDataStorage().length;
|
||||
@ -320,7 +331,7 @@ final class LCMSImageLayout {
|
||||
return checkIndex(res, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
static LCMSImageLayout createImageLayout(Raster r, boolean hasAlpha) {
|
||||
static LCMSImageLayout createImageLayout(Raster r, ColorModel cm) {
|
||||
LCMSImageLayout l = new LCMSImageLayout();
|
||||
if (r instanceof ByteComponentRaster &&
|
||||
r.getSampleModel() instanceof ComponentSampleModel) {
|
||||
@ -329,8 +340,12 @@ final class LCMSImageLayout {
|
||||
ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel();
|
||||
|
||||
int numBands = br.getNumBands();
|
||||
boolean hasAlpha = cm != null && cm.hasAlpha();
|
||||
l.pixelType = (hasAlpha ? CHANNELS_SH(numBands - 1) | EXTRA_SH(1)
|
||||
: CHANNELS_SH(numBands)) | BYTES_SH(1);
|
||||
if (hasAlpha && cm.isAlphaPremultiplied()) {
|
||||
l.pixelType |= PREMUL_SH(1);
|
||||
}
|
||||
|
||||
int[] bandOffsets = csm.getBandOffsets();
|
||||
BandOrder order = BandOrder.getBandOrder(bandOffsets);
|
||||
|
@ -127,19 +127,15 @@ final class LCMSTransform implements ColorTransform {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if lcms may supports this format directly.
|
||||
* Returns {@code true} if lcms may support this format directly.
|
||||
*/
|
||||
private static boolean isLCMSSupport(BufferedImage src, BufferedImage dst) {
|
||||
if (!dst.getColorModel().hasAlpha()) {
|
||||
return true;
|
||||
}
|
||||
// lcms as of now does not support pre-alpha
|
||||
if (src.isAlphaPremultiplied() || dst.isAlphaPremultiplied()) {
|
||||
return false;
|
||||
}
|
||||
boolean dstAlpha = dst.getColorModel().hasAlpha();
|
||||
boolean srcAlpha = src.getColorModel().hasAlpha();
|
||||
boolean srcPre = srcAlpha && src.getColorModel().isAlphaPremultiplied();
|
||||
// lcms does not convert pre-alpha for transparent src if dst is opaque
|
||||
// lcms does not set correct alpha for transparent dst if src is opaque
|
||||
// is it feature or bug?
|
||||
return dst.getColorModel().hasAlpha() == src.getColorModel().hasAlpha();
|
||||
return !dstAlpha && !srcPre || dstAlpha == srcAlpha;
|
||||
}
|
||||
|
||||
public void colorConvert(BufferedImage src, BufferedImage dst) {
|
||||
@ -424,9 +420,9 @@ final class LCMSTransform implements ColorTransform {
|
||||
public void colorConvert(Raster src, WritableRaster dst) {
|
||||
|
||||
LCMSImageLayout srcIL, dstIL;
|
||||
dstIL = LCMSImageLayout.createImageLayout(dst, false);
|
||||
dstIL = LCMSImageLayout.createImageLayout(dst, null);
|
||||
if (dstIL != null) {
|
||||
srcIL = LCMSImageLayout.createImageLayout(src, false);
|
||||
srcIL = LCMSImageLayout.createImageLayout(src, null);
|
||||
if (srcIL != null) {
|
||||
doTransform(srcIL, dstIL);
|
||||
return;
|
||||
|
@ -23,11 +23,18 @@
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
|
||||
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
|
||||
@ -45,7 +52,7 @@ import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012229 8300725
|
||||
* @bug 8012229 8300725 8279216
|
||||
* @summary one more test to check the alpha channel
|
||||
*/
|
||||
public final class ColCvtAlphaDifferentSrcDst {
|
||||
@ -53,11 +60,19 @@ public final class ColCvtAlphaDifferentSrcDst {
|
||||
private static final int WIDTH = 256;
|
||||
private static final int HEIGHT = 256;
|
||||
|
||||
private static final int TYPE_CUSTOM_4BYTE_ABGR_PRE = -1;
|
||||
private static final int TYPE_CUSTOM_4BYTE_ARGB_PRE = -2;
|
||||
private static final int TYPE_CUSTOM_4BYTE_RGBA_PRE = -3;
|
||||
private static final int TYPE_CUSTOM_4BYTE_GABR_PRE = -4;
|
||||
private static final int TYPE_CUSTOM_INT_ARGB_PRE = -5;
|
||||
private static final int TYPE_CUSTOM_INT_GABR_PRE = -6;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
differentToOpaqueDst();
|
||||
differentToTransparentDst(TYPE_INT_ARGB);
|
||||
differentToTransparentDst(TYPE_4BYTE_ABGR);
|
||||
differentToTransparentDst(TYPE_INT_ARGB_PRE);
|
||||
differentToTransparentDst(TYPE_4BYTE_ABGR_PRE);
|
||||
differentToNullDst();
|
||||
}
|
||||
|
||||
@ -97,7 +112,16 @@ public final class ColCvtAlphaDifferentSrcDst {
|
||||
opaqueDst(TYPE_INT_ARGB, TYPE_INT_BGR);
|
||||
opaqueDst(TYPE_4BYTE_ABGR, TYPE_INT_BGR);
|
||||
|
||||
// It is unclear how to hangle pre colors in the opaque DST
|
||||
// compare the "fast" and "slow" paths
|
||||
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ABGR_PRE);
|
||||
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ARGB_PRE);
|
||||
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_RGBA_PRE);
|
||||
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_GABR_PRE);
|
||||
|
||||
opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_ARGB_PRE);
|
||||
opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_GABR_PRE);
|
||||
|
||||
// It is unclear how to handle pre colors in the opaque DST
|
||||
//opaqueDst(TYPE_INT_ARGB_PRE, TYPE_4BYTE_ABGR_PRE);
|
||||
//opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_INT_BGR);
|
||||
}
|
||||
@ -196,7 +220,15 @@ public final class ColCvtAlphaDifferentSrcDst {
|
||||
}
|
||||
|
||||
private static BufferedImage createSrc(int type) {
|
||||
BufferedImage img = new BufferedImage(WIDTH, HEIGHT, type);
|
||||
BufferedImage img = switch (type) {
|
||||
case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE();
|
||||
case TYPE_CUSTOM_INT_ARGB_PRE -> TYPE_INT_ARGB_PRE();
|
||||
case TYPE_CUSTOM_INT_GABR_PRE -> TYPE_INT_GABR_PRE();
|
||||
default -> new BufferedImage(WIDTH, HEIGHT, type);
|
||||
};
|
||||
fill(img);
|
||||
return img;
|
||||
}
|
||||
@ -220,4 +252,92 @@ public final class ColCvtAlphaDifferentSrcDst {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_RGBA_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {0, 1, 2, 3};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
WIDTH, HEIGHT,
|
||||
WIDTH * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_ABGR_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {3, 2, 1, 0};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
WIDTH, HEIGHT,
|
||||
WIDTH * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_ARGB_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {1, 2, 3, 0};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
WIDTH, HEIGHT,
|
||||
WIDTH * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_GABR_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {3, 0, 2, 1};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
WIDTH, HEIGHT,
|
||||
WIDTH * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_INT_ARGB_PRE() {
|
||||
ColorModel colorModel = new DirectColorModel(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
32,
|
||||
0x00ff0000, // Red
|
||||
0x0000ff00, // Green
|
||||
0x000000ff, // Blue
|
||||
0xff000000, // Alpha
|
||||
true, // Alpha Premultiplied
|
||||
DataBuffer.TYPE_INT
|
||||
);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH,
|
||||
HEIGHT);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_INT_GABR_PRE() {
|
||||
ColorModel colorModel = new DirectColorModel(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
32,
|
||||
0x000000ff, // Red
|
||||
0xff000000, // Green
|
||||
0x0000ff00, // Blue
|
||||
0x00ff0000, // Alpha
|
||||
true, // Alpha Premultiplied
|
||||
DataBuffer.TYPE_INT
|
||||
);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH,
|
||||
HEIGHT);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
}
|
||||
|
264
test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java
Normal file
264
test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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.
|
||||
*/
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
|
||||
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8279216
|
||||
* @summary Verifies implementation of premultiplied alpha
|
||||
*/
|
||||
public final class PremultipliedAlpha {
|
||||
|
||||
private static final int SIZE = 256;
|
||||
|
||||
private static final int COLOR_TOLERANCE = 2;
|
||||
|
||||
private enum Type {
|
||||
TYPE_ARGB_PRE,
|
||||
TYPE_4BYTE_ABGR_PRE,
|
||||
TYPE_CUSTOM_ARGB_PRE,
|
||||
TYPE_CUSTOM_GABR_PRE,
|
||||
TYPE_CUSTOM_4BYTE_ABGR_PRE,
|
||||
TYPE_CUSTOM_4BYTE_ARGB_PRE,
|
||||
TYPE_CUSTOM_4BYTE_RGBA_PRE,
|
||||
TYPE_CUSTOM_4BYTE_GABR_PRE,
|
||||
TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE,
|
||||
TYPE_CUSTOM_4INT_8bit_ARGB_PRE,
|
||||
}
|
||||
|
||||
private static final ColorSpace[] CSs = {
|
||||
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ),
|
||||
ColorSpace.getInstance(ColorSpace.CS_GRAY),
|
||||
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
|
||||
ColorSpace.getInstance(ColorSpace.CS_PYCC),
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB)
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (ColorSpace cs : CSs) {
|
||||
for (Type dst : Type.values()) {
|
||||
BufferedImage gold = null;
|
||||
for (Type src : Type.values()) {
|
||||
BufferedImage from = createSrc(src);
|
||||
BufferedImage to = createDst(dst);
|
||||
ColorConvertOp op = new ColorConvertOp(cs, null);
|
||||
op.filter(from, to);
|
||||
if (gold == null) {
|
||||
gold = to;
|
||||
} else {
|
||||
validate(gold, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(BufferedImage img1, BufferedImage img2) {
|
||||
for (int a = 0; a < SIZE; a++) {
|
||||
for (int c = 0; c < SIZE; c++) {
|
||||
int[] pixel1 = img1.getRaster().getPixel(c, a, (int[]) null);
|
||||
int[] pixel2 = img2.getRaster().getPixel(c, a, (int[]) null);
|
||||
if (pixel1.length != pixel2.length) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
for (int i = 0 ; i < pixel1.length; ++i) {
|
||||
if (Math.abs(pixel1[i] - pixel2[i]) >= COLOR_TOLERANCE) {
|
||||
System.out.println("c = " + c);
|
||||
System.out.println("a = " + a);
|
||||
System.err.println("rgb1 = " + Arrays.toString(pixel1));
|
||||
System.err.println("rgb2 = " + Arrays.toString(pixel2));
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BufferedImage createDst(Type type) {
|
||||
BufferedImage img = createSrc(type);
|
||||
Graphics2D g = img.createGraphics();
|
||||
g.setComposite(AlphaComposite.Clear);
|
||||
g.fillRect(0, 0, SIZE, SIZE);
|
||||
g.dispose();
|
||||
return img;
|
||||
}
|
||||
|
||||
private static BufferedImage createSrc(Type type) {
|
||||
BufferedImage bi = switch (type) {
|
||||
case TYPE_ARGB_PRE -> new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB_PRE);
|
||||
case TYPE_CUSTOM_ARGB_PRE -> TYPE_ARGB_PRE();
|
||||
case TYPE_CUSTOM_GABR_PRE -> TYPE_GABR_PRE();
|
||||
case TYPE_4BYTE_ABGR_PRE -> new BufferedImage(SIZE, SIZE, TYPE_4BYTE_ABGR_PRE);
|
||||
case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE();
|
||||
case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE();
|
||||
case TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE -> TYPE_4USHORT_ARGB_8bit_PRE();
|
||||
case TYPE_CUSTOM_4INT_8bit_ARGB_PRE -> TYPE_4INT_ARGB_8bit_PRE();
|
||||
};
|
||||
fill(bi);
|
||||
return bi;
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_ARGB_PRE() {
|
||||
ColorModel colorModel = new DirectColorModel(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
32,
|
||||
0x00ff0000, // Red
|
||||
0x0000ff00, // Green
|
||||
0x000000ff, // Blue
|
||||
0xff000000, // Alpha
|
||||
true, // Alpha Premultiplied
|
||||
DataBuffer.TYPE_INT
|
||||
);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
|
||||
SIZE);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_GABR_PRE() {
|
||||
ColorModel colorModel = new DirectColorModel(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
32,
|
||||
0x000000ff, // Red
|
||||
0xff000000, // Green
|
||||
0x0000ff00, // Blue
|
||||
0x00ff0000, // Alpha
|
||||
true, // Alpha Premultiplied
|
||||
DataBuffer.TYPE_INT
|
||||
);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
|
||||
SIZE);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_RGBA_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {0, 1, 2, 3};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
SIZE, SIZE,
|
||||
SIZE * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_ABGR_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {3, 2, 1, 0};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
SIZE, SIZE,
|
||||
SIZE * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_ARGB_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {1, 2, 3, 0};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
SIZE, SIZE,
|
||||
SIZE * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4BYTE_GABR_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
int[] bOffs = {3, 0, 2, 1};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
SIZE, SIZE,
|
||||
SIZE * 4, 4,
|
||||
bOffs, null);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4INT_ARGB_8bit_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_INT);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
|
||||
SIZE);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static BufferedImage TYPE_4USHORT_ARGB_8bit_PRE() {
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
int[] nBits = {8, 8, 8, 8};
|
||||
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
|
||||
Transparency.TRANSLUCENT,
|
||||
DataBuffer.TYPE_USHORT);
|
||||
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
|
||||
SIZE);
|
||||
return new BufferedImage(colorModel, raster, true, null);
|
||||
}
|
||||
|
||||
private static void fill(BufferedImage image) {
|
||||
// Graphics2D g = image.createGraphics();
|
||||
// g.setComposite(AlphaComposite.Src);
|
||||
for (int a = 0; a < SIZE; ++a) {
|
||||
for (int c = 0; c < SIZE; ++c) {
|
||||
Color c1 = new Color(a, c, c, a);
|
||||
// g.setColor(c1);
|
||||
//TODO CANNOT USE fillrect, does not work for custom types!
|
||||
// g.fillRect(c, a, 1, 1);
|
||||
image.setRGB(c,a , c1.getRGB());
|
||||
}
|
||||
}
|
||||
// g.dispose();
|
||||
}
|
||||
}
|
83
test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java
Normal file
83
test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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.
|
||||
*/
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.SampleModel;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8279216
|
||||
* @summary behavior checked by this test is not specified, this test just
|
||||
* defends against accidental changes
|
||||
*/
|
||||
public final class SkipSampleModel {
|
||||
|
||||
private static int[] TYPES = {
|
||||
BufferedImage.TYPE_INT_RGB,
|
||||
BufferedImage.TYPE_INT_ARGB,
|
||||
BufferedImage.TYPE_INT_ARGB_PRE,
|
||||
BufferedImage.TYPE_INT_BGR,
|
||||
BufferedImage.TYPE_3BYTE_BGR,
|
||||
BufferedImage.TYPE_4BYTE_ABGR,
|
||||
BufferedImage.TYPE_4BYTE_ABGR_PRE,
|
||||
BufferedImage.TYPE_USHORT_565_RGB,
|
||||
BufferedImage.TYPE_USHORT_555_RGB,
|
||||
BufferedImage.TYPE_BYTE_GRAY,
|
||||
BufferedImage.TYPE_USHORT_GRAY,
|
||||
BufferedImage.TYPE_BYTE_BINARY,
|
||||
BufferedImage.TYPE_BYTE_INDEXED
|
||||
};
|
||||
|
||||
private static final ColorSpace[] CSs = {
|
||||
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ),
|
||||
ColorSpace.getInstance(ColorSpace.CS_GRAY),
|
||||
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
|
||||
ColorSpace.getInstance(ColorSpace.CS_PYCC),
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB)
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (ColorSpace cs : CSs) {
|
||||
ColorConvertOp op = new ColorConvertOp(cs, null);
|
||||
for (int srcType : TYPES) {
|
||||
for (int dstType : TYPES) {
|
||||
BufferedImage src = new BufferedImage(1, 1, srcType) {
|
||||
@Override
|
||||
public SampleModel getSampleModel() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
};
|
||||
BufferedImage dst = new BufferedImage(1, 1, dstType) {
|
||||
@Override
|
||||
public SampleModel getSampleModel() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
};
|
||||
op.filter(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user