1 /* 2 * Copyright (c) 2012, 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 /* 25 * @test 26 * @bug 7188093 8000176 27 * @summary Tests each of the 3 possible methods for rendering an upscaled 28 * image via rendering hints for default, xrender and opengl pipelines. 29 * 30 * @author Vadim.Pakhnushev@oracle.com 31 * @run main/othervm -Dsun.java2d.xrender=false InterpolationQualityTest 32 * @run main/othervm -Dsun.java2d.xrender=True InterpolationQualityTest 33 * @run main/othervm -Dsun.java2d.opengl=True InterpolationQualityTest 34 * @run main/othervm -Dsun.java2d.d3d=false InterpolationQualityTest 35 * @run main/othervm -Dsun.java2d.d3d=True InterpolationQualityTest 36 */ 37 38 import java.awt.*; 39 import java.awt.image.*; 40 import java.io.File; 41 import java.io.IOException; 42 import javax.imageio.ImageIO; 43 44 public class InterpolationQualityTest { 45 46 private static final int testSize = 4, scaleFactor = 20, tolerance = 3; 47 private static final int sw = testSize * scaleFactor; 48 private static final int sh = testSize * scaleFactor; 49 50 private Image testImage; 51 private VolatileImage vImg; 52 53 public InterpolationQualityTest() { 54 testImage = createTestImage(); 55 } 56 57 private Image createTestImage() { 58 BufferedImage bi = new BufferedImage(testSize, testSize, BufferedImage.TYPE_INT_ARGB); 59 Graphics2D g = bi.createGraphics(); 60 g.setColor(Color.BLACK); 61 g.fillRect(0, 0, testSize, testSize); 62 for (int i = 0; i < testSize; i++) { 63 bi.setRGB(i, i, Color.WHITE.getRGB()); 64 } 65 return bi; 66 } 67 68 private BufferedImage createReferenceImage(Object hint) { 69 BufferedImage bi = new BufferedImage(sw, sh, BufferedImage.TYPE_INT_ARGB); 70 Graphics2D g2d = bi.createGraphics(); 71 drawImage(g2d, hint); 72 return bi; 73 } 74 75 private void drawImage(Graphics2D g2d, Object hint) { 76 g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); 77 g2d.drawImage(testImage, 0, 0, sw, sh, null); 78 } 79 80 private GraphicsConfiguration getDefaultGC() { 81 return GraphicsEnvironment.getLocalGraphicsEnvironment(). 82 getDefaultScreenDevice().getDefaultConfiguration(); 83 } 84 85 private void createVImg() { 86 vImg = getDefaultGC().createCompatibleVolatileImage(sw, sh); 87 } 88 89 private void renderOffscreen(Object hint) { 90 Graphics2D g = vImg.createGraphics(); 91 drawImage(g, hint); 92 g.dispose(); 93 } 94 95 private BufferedImage renderImage(Object hint) { 96 BufferedImage snapshot; 97 createVImg(); 98 renderOffscreen(hint); 99 100 do { 101 int status = vImg.validate(getDefaultGC()); 102 if (status != VolatileImage.IMAGE_OK) { 103 if (status == VolatileImage.IMAGE_INCOMPATIBLE) { 104 createVImg(); 105 } 106 renderOffscreen(hint); 107 } 108 snapshot = vImg.getSnapshot(); 109 } while (vImg.contentsLost()); 110 vImg.flush(); 111 return snapshot; 112 } 113 114 private boolean compareComponent(int comp1, int comp2) { 115 return Math.abs(comp1 - comp2) <= tolerance; 116 } 117 118 private boolean compareRGB(int rgb1, int rgb2) { 119 Color col1 = new Color(rgb1); 120 Color col2 = new Color(rgb2); 121 return compareComponent(col1.getRed(), col2.getRed()) && 122 compareComponent(col1.getBlue(), col2.getBlue()) && 123 compareComponent(col1.getGreen(), col2.getGreen()) && 124 compareComponent(col1.getAlpha(), col2.getAlpha()); 125 } 126 127 private boolean compareImages(BufferedImage img, BufferedImage ref, String imgName) { 128 for (int y = 0; y < ref.getHeight(); y++) { 129 for (int x = 0; x < ref.getWidth(); x++) { 130 if (!compareRGB(ref.getRGB(x, y), img.getRGB(x, y))) { 131 System.out.println(imgName + ".getRGB(" + x + ", " + y + ") = " 132 + new Color(img.getRGB(x, y)) + " != " 133 + new Color(ref.getRGB(x, y))); 134 return false; 135 } 136 } 137 } 138 return true; 139 } 140 141 private boolean test(Object hint) { 142 BufferedImage refImage = createReferenceImage(hint); 143 BufferedImage resImage = renderImage(hint); 144 145 boolean passed = compareImages(resImage, refImage, "resImage"); 146 System.out.println(getHintName(hint) + (passed ? " passed." : " failed.")); 147 if (!passed) { 148 dumpImage(refImage, "out_" + getHintName(hint) + "_ref.png"); 149 dumpImage(resImage, "out_" + getHintName(hint) + ".png"); 150 } 151 return passed; 152 } 153 154 public void test() { 155 boolean passed = true; 156 passed &= test(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 157 passed &= test(RenderingHints.VALUE_INTERPOLATION_BILINEAR); 158 passed &= test(RenderingHints.VALUE_INTERPOLATION_BICUBIC); 159 if (passed) { 160 System.out.println("Test PASSED."); 161 } else { 162 throw new RuntimeException("Test FAILED."); 163 } 164 } 165 166 private String getHintName(Object hint) { 167 if (hint == RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR) { 168 return "nearest"; 169 } 170 else if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) { 171 return "bilinear"; 172 } 173 else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) { 174 return "bicubic"; 175 } 176 else { 177 return "null"; 178 } 179 } 180 181 private void dumpImage(BufferedImage bi, String name) { 182 try { 183 ImageIO.write(bi, "PNG", new File(name)); 184 } catch (IOException ex) { 185 } 186 } 187 188 public static void main(String[] argv) { 189 InterpolationQualityTest test = new InterpolationQualityTest(); 190 test.test(); 191 } 192 }