From 42e17f20632ab55466687d2fb98e8f597e199aab Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Fri, 11 Oct 2019 16:56:00 +0200 Subject: [PATCH] #501: Fix for TYPE_USHORT_555/565_RGB, ColorModel now 16 bits --- .../imageio/util/ImageTypeSpecifiers.java | 36 +++++++++++++++---- .../imageio/util/ImageTypeSpecifiersTest.java | 26 ++++++++++---- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiers.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiers.java index aaaa618c..14a240a1 100644 --- a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiers.java +++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiers.java @@ -54,6 +54,28 @@ public final class ImageTypeSpecifiers { private ImageTypeSpecifiers() {} public static ImageTypeSpecifier createFromBufferedImageType(final int bufferedImageType) { + switch (bufferedImageType) { + // ImageTypeSpecifier unconditionally uses bits == 32, we'll use a workaround for the USHORT types + case BufferedImage.TYPE_USHORT_565_RGB: + return createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB), + 0xF800, + 0x07E0, + 0x001F, + 0x0, + DataBuffer.TYPE_USHORT, + false); + + case BufferedImage.TYPE_USHORT_555_RGB: + return createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB), + 0x7C00, + 0x03E0, + 0x001F, + 0x0, + DataBuffer.TYPE_USHORT, + false); + default: + } + return ImageTypeSpecifier.createFromBufferedImageType(bufferedImageType); } @@ -147,21 +169,21 @@ public final class ImageTypeSpecifiers { int numEntries = 1 << bits; - byte[] arr = new byte[numEntries]; - byte[] arg = new byte[numEntries]; - byte[] arb = new byte[numEntries]; + byte[] r = new byte[numEntries]; + byte[] g = new byte[numEntries]; + byte[] b = new byte[numEntries]; // Scale array values according to color profile.. for (int i = 0; i < numEntries; i++) { float[] gray = new float[]{i / (float) (numEntries - 1)}; float[] rgb = colorSpace.toRGB(gray); - arr[i] = (byte) (rgb[0] * 255); - arg[i] = (byte) (rgb[1] * 255); - arb[i] = (byte) (rgb[2]* 255); + r[i] = (byte) (rgb[0] * 255); + g[i] = (byte) (rgb[1] * 255); + b[i] = (byte) (rgb[2] * 255); } - ColorModel colorModel = new IndexColorModel(bits, numEntries, arr, arg, arb); + ColorModel colorModel = new IndexColorModel(bits, numEntries, r, g, b); SampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, 1, 1, bits); return new ImageTypeSpecifier(colorModel, sampleModel); diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiersTest.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiersTest.java index 2210b90a..9369d4b6 100644 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiersTest.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageTypeSpecifiersTest.java @@ -61,10 +61,21 @@ public class ImageTypeSpecifiersTest { @Test public void testCreateFromBufferedImageType() { for (int type = BufferedImage.TYPE_INT_RGB; type < BufferedImage.TYPE_BYTE_INDEXED; type++) { - assertEquals( - ImageTypeSpecifier.createFromBufferedImageType(type), - ImageTypeSpecifiers.createFromBufferedImageType(type) - ); + ImageTypeSpecifier expected; + + switch (type) { + // Special handling for USHORT_565 and 555, due to bug in ImageTypeSpecifier for these types (DirectColorModel is 32 bits) + case BufferedImage.TYPE_USHORT_565_RGB: + expected = createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false); + break; + case BufferedImage.TYPE_USHORT_555_RGB: + expected = createPacked(sRGB, DCM_555_RED_MASK, DCM_555_GRN_MASK, DCM_555_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false); + break; + default: + expected = ImageTypeSpecifier.createFromBufferedImageType(type); + } + + assertEquals(expected, ImageTypeSpecifiers.createFromBufferedImageType(type)); } } @@ -119,7 +130,7 @@ public class ImageTypeSpecifiersTest { // Extra: Make sure color models bits is actually 16 (ImageTypeSpecifier equivalent returns 32) assertEquals(16, ImageTypeSpecifiers.createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false).getColorModel().getPixelSize()); - } + } @Test public void testCreatePacked8() { @@ -531,6 +542,7 @@ public class ImageTypeSpecifiersTest { @Test public void testCreatePackedGrayscale1() { + // TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries assertEquals( ImageTypeSpecifier.createGrayscale(1, DataBuffer.TYPE_BYTE, false), ImageTypeSpecifiers.createPackedGrayscale(GRAY, 1, DataBuffer.TYPE_BYTE) @@ -539,6 +551,7 @@ public class ImageTypeSpecifiersTest { @Test public void testCreatePackedGrayscale2() { + // TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries assertEquals( ImageTypeSpecifier.createGrayscale(2, DataBuffer.TYPE_BYTE, false), ImageTypeSpecifiers.createPackedGrayscale(GRAY, 2, DataBuffer.TYPE_BYTE) @@ -546,7 +559,8 @@ public class ImageTypeSpecifiersTest { } @Test - public void testCreatePackedGrayscale4() { + public void testCreatePackedGrayscale4() throws Exception { + // TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries assertEquals( ImageTypeSpecifier.createGrayscale(4, DataBuffer.TYPE_BYTE, false), ImageTypeSpecifiers.createPackedGrayscale(GRAY, 4, DataBuffer.TYPE_BYTE)