1 /*
   2  * Copyright (c) 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.embed.swing;
  27 
  28 import java.awt.image.BufferedImage;
  29 import java.util.concurrent.CountDownLatch;
  30 import java.util.concurrent.TimeUnit;
  31 import javafx.application.Application;
  32 import javafx.application.Platform;
  33 import javafx.embed.swing.SwingFXUtils;
  34 import javafx.scene.image.Image;
  35 import javafx.scene.image.PixelFormat;
  36 import javafx.scene.image.PixelReader;
  37 import javafx.stage.Stage;
  38 import junit.framework.AssertionFailedError;
  39 import org.junit.AfterClass;
  40 import static org.junit.Assert.assertEquals;
  41 import static org.junit.Assert.assertNotNull;
  42 import static org.junit.Assert.assertTrue;
  43 import org.junit.BeforeClass;
  44 import org.junit.Test;
  45 
  46 public class SwingFXUtilsTest {
  47     static final boolean verbose = false;
  48 
  49     // Used to launch the application before running any test
  50     private static final CountDownLatch launchLatch = new CountDownLatch(1);
  51 
  52     // Application class. An instance is created and initialized before running
  53     // the first test, and it lives through the execution of all tests.
  54     public static class MyApp extends Application {
  55         @Override
  56         public void start(Stage primaryStage) throws Exception {
  57             Platform.setImplicitExit(false);
  58             assertTrue(Platform.isFxApplicationThread());
  59             assertNotNull(primaryStage);
  60 
  61             launchLatch.countDown();
  62         }
  63     }
  64 
  65     @BeforeClass
  66     public static void doSetupOnce() {
  67         // Start the Application
  68         new Thread(() -> Application.launch(MyApp.class, (String[]) null)).start();
  69 
  70         try {
  71             if (!launchLatch.await(5000, TimeUnit.MILLISECONDS)) {
  72                 throw new AssertionFailedError("Timeout waiting for Application to launch");
  73             }
  74         } catch (InterruptedException ex) {
  75             AssertionFailedError err = new AssertionFailedError("Unexpected exception");
  76             err.initCause(ex);
  77             throw err;
  78         }
  79 
  80         assertEquals(0, launchLatch.getCount());
  81     }
  82 
  83     @AfterClass
  84     public static void doTeardownOnce() {
  85         Platform.exit();
  86     }
  87 
  88     @Test
  89     public void testFromFXImg() {
  90         testFromFXImg("alpha.png");
  91         testFromFXImg("opaque.gif");
  92         testFromFXImg("opaque.jpg");
  93         testFromFXImg("opaque.png");
  94         testFromFXImg("trans.gif");
  95     }
  96 
  97     static void testFromFXImg(String imgfilename) {
  98         Image img = new Image("javafx/embed/swing/"+imgfilename);
  99         boolean rgbrequired = (img.getPixelReader().getPixelFormat().getType() == PixelFormat.Type.BYTE_RGB);
 100         BufferedImage bimg = SwingFXUtils.fromFXImage(img, null);
 101         checkBimg(img, bimg);
 102         boolean reusesitself = reusesBimg(img, bimg, true);
 103         boolean reusesxrgb = reusesBimg(img, BufferedImage.TYPE_INT_RGB, rgbrequired);
 104         boolean reusesargb = reusesBimg(img, BufferedImage.TYPE_INT_ARGB, true);
 105         boolean reusesargbpre = reusesBimg(img, BufferedImage.TYPE_INT_ARGB_PRE, true);
 106         if (verbose) {
 107             System.out.println(imgfilename+" type = "+img.getPixelReader().getPixelFormat());
 108             System.out.println(imgfilename+" bimg type = "+bimg.getType());
 109             System.out.println(imgfilename+" reuses own bimg = "+reusesitself);
 110             System.out.println(imgfilename+" reuses rgb bimg = "+reusesxrgb);
 111             System.out.println(imgfilename+" reuses argb bimg = "+reusesargb);
 112             System.out.println(imgfilename+" reuses argb pre bimg = "+reusesargbpre);
 113             System.out.println();
 114         }
 115     }
 116 
 117     static boolean reusesBimg(Image img, int type, boolean required) {
 118         int iw = (int) img.getWidth();
 119         int ih = (int) img.getHeight();
 120         BufferedImage bimg = new BufferedImage(iw, ih, type);
 121         return reusesBimg(img, bimg, required);
 122     }
 123 
 124     static boolean reusesBimg(Image img, BufferedImage bimg, boolean required) {
 125         BufferedImage ret = SwingFXUtils.fromFXImage(img, bimg);
 126         checkBimg(img, ret);
 127         if (required) {
 128             assertTrue(bimg == ret);
 129         }
 130         return (bimg == ret);
 131     }
 132 
 133     static void checkBimg(Image img, BufferedImage bimg) {
 134         PixelReader pr = img.getPixelReader();
 135         int iw = (int) img.getWidth();
 136         int ih = (int) img.getHeight();
 137         for (int y = 0; y < ih; y++) {
 138             for (int x = 0; x < iw; x++) {
 139                 int imgargb = pr.getArgb(x, y);
 140                 int bimgargb = bimg.getRGB(x, y);
 141                 if (imgargb != bimgargb) {
 142                     System.err.println(">>>> wrong color in bimg: "+hex(bimgargb)+
 143                                        " at "+x+", "+y+
 144                                        " should be: "+hex(imgargb));
 145                     assertEquals(imgargb, bimgargb);
 146                 }
 147             }
 148         }
 149     }
 150 
 151     static String hex(int i) {
 152         return String.format("0x%08x", i);
 153     }
 154 }