| /* |
| * Copyright (c) 2009, 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 4893408 |
| * |
| * @summary Test verifies that Image I/O jpeg reader correctly handles |
| * destination types if number of color components in destination |
| * differs from number of color components in the jpeg image. |
| * Particularly, it verifies reading YCbCr image as a grayscaled |
| * and reading grayscaled jpeg as a RGB. |
| * |
| * @run main ReadAsGrayTest |
| */ |
| |
| import java.awt.Color; |
| import java.awt.Graphics2D; |
| import java.awt.color.ColorSpace; |
| import java.awt.image.BufferedImage; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Iterator; |
| import javax.imageio.ImageIO; |
| import javax.imageio.ImageReadParam; |
| import javax.imageio.ImageReader; |
| import javax.imageio.ImageTypeSpecifier; |
| import javax.imageio.stream.ImageInputStream; |
| import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR; |
| import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY; |
| import static java.awt.color.ColorSpace.TYPE_GRAY; |
| import static java.awt.color.ColorSpace.CS_sRGB; |
| |
| public class ReadAsGrayTest { |
| static Color[] colors = new Color[] { |
| Color.white, Color.red, Color.green, |
| Color.blue, Color.black }; |
| |
| static final int dx = 50; |
| static final int h = 100; |
| |
| static ColorSpace sRGB = ColorSpace.getInstance(CS_sRGB); |
| |
| |
| public static void main(String[] args) throws IOException { |
| System.out.println("Type TYPE_BYTE_GRAY"); |
| doTest(TYPE_BYTE_GRAY); |
| |
| System.out.println("Type TYPE_3BYTE_BGR"); |
| doTest(TYPE_3BYTE_BGR); |
| |
| System.out.println("Test PASSED."); |
| } |
| |
| private static void doTest(int type) throws IOException { |
| BufferedImage src = createTestImage(type); |
| |
| File f = new File("test.jpg"); |
| |
| if (!ImageIO.write(src, "jpg", f)) { |
| throw new RuntimeException("Failed to write test image."); |
| } |
| |
| ImageInputStream iis = ImageIO.createImageInputStream(f); |
| ImageReader reader = ImageIO.getImageReaders(iis).next(); |
| reader.setInput(iis); |
| |
| Iterator<ImageTypeSpecifier> types = reader.getImageTypes(0); |
| ImageTypeSpecifier srgb = null; |
| ImageTypeSpecifier gray = null; |
| // look for gray and srgb types |
| while ((srgb == null || gray == null) && types.hasNext()) { |
| ImageTypeSpecifier t = types.next(); |
| if (t.getColorModel().getColorSpace().getType() == TYPE_GRAY) { |
| gray = t; |
| } |
| if (t.getColorModel().getColorSpace() == sRGB) { |
| srgb = t; |
| } |
| } |
| if (gray == null) { |
| throw new RuntimeException("No gray type available."); |
| } |
| if (srgb == null) { |
| throw new RuntimeException("No srgb type available."); |
| } |
| |
| System.out.println("Read as GRAY..."); |
| testType(reader, gray, src); |
| |
| System.out.println("Read as sRGB..."); |
| testType(reader, srgb, src); |
| } |
| |
| private static void testType(ImageReader reader, |
| ImageTypeSpecifier t, |
| BufferedImage src) |
| throws IOException |
| { |
| ImageReadParam p = reader.getDefaultReadParam(); |
| p.setDestinationType(t); |
| BufferedImage dst = reader.read(0, p); |
| |
| verify(src, dst, t); |
| } |
| |
| private static void verify(BufferedImage src, |
| BufferedImage dst, |
| ImageTypeSpecifier type) |
| { |
| BufferedImage test = |
| type.createBufferedImage(src.getWidth(), src.getHeight()); |
| Graphics2D g = test.createGraphics(); |
| g.drawImage(src, 0, 0, null); |
| g.dispose(); |
| |
| for (int i = 0; i < colors.length; i++) { |
| int x = i * dx + dx / 2; |
| int y = h / 2; |
| |
| Color c_test = new Color(test.getRGB(x, y)); |
| Color c_dst = new Color(dst.getRGB(x, y)); |
| |
| if (!compareWithTolerance(c_test, c_dst, 0.01f)) { |
| String msg = String.format("Invalid color: %x instead of %x", |
| c_dst.getRGB(), c_test.getRGB()); |
| throw new RuntimeException("Test failed: " + msg); |
| } |
| } |
| System.out.println("Verified."); |
| } |
| |
| private static boolean compareWithTolerance(Color a, Color b, float delta) { |
| float[] a_rgb = new float[3]; |
| a_rgb = a.getRGBColorComponents(a_rgb); |
| float[] b_rgb = new float[3]; |
| b_rgb = b.getRGBColorComponents(b_rgb); |
| |
| for (int i = 0; i < 3; i++) { |
| if (Math.abs(a_rgb[i] - b_rgb[i]) > delta) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private static BufferedImage createTestImage(int type) { |
| BufferedImage img = new BufferedImage(dx * colors.length, h, type); |
| |
| Graphics2D g = img.createGraphics(); |
| for (int i = 0; i < colors.length; i++) { |
| g.setColor(colors[i]); |
| g.fillRect(i * dx, 0, dx, h); |
| } |
| g.dispose(); |
| |
| return img; |
| } |
| } |