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