1 /*
   2  * Copyright (c) 2011, 2013, 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 com.sun.javafx.iio;
  27 
  28 import java.awt.Canvas;
  29 import java.awt.Dimension;
  30 import java.awt.Frame;
  31 import java.awt.Graphics;
  32 import java.awt.Image;
  33 import java.awt.event.WindowAdapter;
  34 import java.awt.event.WindowEvent;
  35 import java.awt.image.BufferedImage;
  36 import java.awt.image.DataBufferByte;
  37 import java.io.IOException;
  38 import java.nio.ByteBuffer;
  39 import org.junit.After;
  40 import org.junit.AfterClass;
  41 import org.junit.Before;
  42 import org.junit.BeforeClass;
  43 import org.junit.Test;
  44 
  45 /**
  46  *
  47  * @author bpb
  48  */
  49 public class ImageStorageTest {
  50 
  51     private static final boolean WRITE_OUTPUT = false;
  52 
  53     private static final float MINIFY_FRACTION = 0.57F;
  54     private static final float MAGNIFY_FRACTION = 1.47F;
  55 
  56     private static int rawWidth = -1;
  57     private static int rawHeight = -1;
  58 
  59     public static final void main(String[] args) throws Throwable {
  60         String input = args[0];
  61         String output = null;
  62         if (args.length > 1) {
  63             output = args[1];
  64         }
  65         ImageStorageTest test = new ImageStorageTest();
  66         int width = 111;
  67         int height = 97;
  68         boolean preserveAspectRatio = true;
  69         boolean smooth = true;
  70         test.loadAllTest(input, output, width, height, preserveAspectRatio, smooth);
  71         Thread.sleep(3000);
  72         System.exit(0);
  73     }
  74 
  75     public static final BufferedImage getAsBufferedImage(ImageFrame frame) {
  76         BufferedImage image = null;
  77         int width = frame.getWidth();
  78         int height = frame.getHeight();
  79         int scanlineStride = frame.getStride();
  80         ByteBuffer bbuf = (ByteBuffer) frame.getImageData();
  81         byte[] pixels = null;
  82         if (bbuf.hasArray()) {
  83             pixels = bbuf.array();
  84         } else {
  85             pixels = new byte[bbuf.capacity()];
  86             bbuf.get(pixels);
  87         }
  88         switch (frame.getImageType()) {
  89             case GRAY: {
  90                 image = new BufferedImage(width, height,
  91                         BufferedImage.TYPE_BYTE_GRAY);
  92                 DataBufferByte db =
  93                         (DataBufferByte) image.getRaster().getDataBuffer();
  94                 byte[] data = db.getData();
  95                 int inLine = 0;
  96                 int outLine = 0;
  97                 for (int y = 0; y < height; y++) {
  98                     System.arraycopy(pixels, inLine, data, outLine, width);
  99                     inLine += scanlineStride;
 100                     outLine += width;
 101                 }
 102 
 103             }
 104             break;
 105 //            case PALETTE:
 106 //            case PALETTE_ALPHA: {
 107 //                byte[][] p = frame.getPalette();
 108 //                IndexColorModel icm =
 109 //                        frame.getImageType() == ImageType.PALETTE ? new IndexColorModel(8, p[0].length,
 110 //                        p[0], p[1], p[2]) : new IndexColorModel(8, p[0].length,
 111 //                        p[0], p[1], p[2], p[3]);
 112 //                image = new BufferedImage(width, height,
 113 //                        BufferedImage.TYPE_BYTE_INDEXED, icm);
 114 //                DataBufferByte db =
 115 //                        (DataBufferByte) image.getRaster().getDataBuffer();
 116 //                byte[] data = db.getData();
 117 //                int inLine = 0;
 118 //                int outLine = 0;
 119 //                for (int y = 0; y < height; y++) {
 120 //                    System.arraycopy(pixels, inLine, data, outLine, width);
 121 //                    inLine += scanlineStride;
 122 //                    outLine += width;
 123 //                }
 124 //            }
 125 //            break;
 126             case RGB: {
 127                 image = new BufferedImage(width, height,
 128                         BufferedImage.TYPE_3BYTE_BGR);
 129                 for (int y = 0; y < height; y++) {
 130                     int off = y * scanlineStride;
 131                     for (int x = 0; x < width; x++) {
 132                         int rgb = ((pixels[off++] & 0xff) << 16) |
 133                                 ((pixels[off++] & 0xff) << 8) |
 134                                 (pixels[off++] & 0xff);
 135                         image.setRGB(x, y, rgb);
 136                     }
 137                 }
 138             }
 139             break;
 140             case RGBA_PRE: {
 141                 image = new BufferedImage(width, height,
 142                         BufferedImage.TYPE_INT_ARGB_PRE);
 143                 for (int y = 0; y < height; y++) {
 144                     int off = y * scanlineStride;
 145                     for (int x = 0; x < width; x++) {
 146                         byte red = pixels[off++];
 147                         byte green = pixels[off++];
 148                         byte blue = pixels[off++];
 149                         byte alpha = pixels[off++];
 150 //                        float f = alpha/255.0F;
 151 //                        red = (byte)((red & 0xff)/f);
 152 //                        green = (byte)((green & 0xff)/f);
 153 //                        blue = (byte)((blue & 0xff)/f);
 154                         int rgb = ((alpha & 0xff) << 24) |
 155                                 ((red & 0xff) << 16) |
 156                                 ((green & 0xff) << 8) |
 157                                 (blue & 0xff);
 158                         image.setRGB(x, y, rgb);
 159                     }
 160                 }
 161 //                DataBufferByte db =
 162 //                        (DataBufferByte) image.getRaster().getDataBuffer();
 163 //                byte[] data = db.getData();
 164 //                for (int y = 0; y < height; y++) {
 165 //                    int offPrism = y * scanlineStride;
 166 //                    int offImage = y * width * 4;
 167 //                    for (int x = 0; x < width; x++) {
 168 //                        data[offImage++] = pixels[offPrism + 3]; // A
 169 //                        data[offImage++] = pixels[offPrism + 2]; // B
 170 //                        data[offImage++] = pixels[offPrism + 1]; // G
 171 //                        data[offImage++] = pixels[offPrism];     // R
 172 //                        offPrism += 4;
 173 //                    }
 174 //                }
 175             }
 176             break;
 177             default:
 178                 throw new UnsupportedOperationException("Unsupported test case " +
 179                         frame.getImageType());
 180         }
 181 
 182         return image;
 183     }
 184 
 185     public static void show(Image img, String label) {
 186         final Frame f = new Frame();
 187         f.addWindowListener(new WindowAdapter() {
 188 
 189             public void windowClosing(WindowEvent e) {
 190                 f.setVisible(false);
 191                 f.dispose();
 192             }
 193         });
 194         f.setTitle(label);
 195         f.add(new ImageCanvas(img));
 196         f.pack();
 197         f.setVisible(true);
 198     }
 199 
 200     public static class ImageCanvas extends Canvas {
 201 
 202         private static final long serialVersionUID = 1L;
 203         Image image;
 204 
 205         public ImageCanvas(Image img) {
 206             this.image = img;
 207         }
 208 
 209         public Dimension getPreferredSize() {
 210             return new Dimension(image.getWidth(null), image.getHeight(null));
 211         }
 212 
 213         public void paint(Graphics g) {
 214             g.drawImage(image, 0, 0, this);
 215         }
 216     }
 217 
 218     public ImageStorageTest() {
 219     }
 220 
 221     @BeforeClass
 222     public static void setUpClass() throws Exception {
 223     }
 224 
 225     @AfterClass
 226     public static void tearDownClass() throws Exception {
 227     }
 228 
 229     @Before
 230     public void setUp() {
 231     }
 232 
 233     @After
 234     public void tearDown() {
 235     }
 236 
 237     /**
 238      * Test of loadAll method, of class ImageStorage.
 239      */
 240     @Test
 241     public void testLoadRaw() throws IOException, InterruptedException {
 242         loadTest("testLoadRaw", "Output", 0, 0, false, false);
 243     }
 244 
 245     /**
 246      * Test of loadAll method, of class ImageStorage.
 247      */
 248     @Test
 249     public void testLoadMagnifyNoAspectRough() throws IOException, InterruptedException {
 250         loadTest("testLoadMagnifyNoAspectRough", "Output_scaled",
 251                 (int)(MAGNIFY_FRACTION*rawHeight), (int)(MAGNIFY_FRACTION*rawWidth),
 252                 false, false);
 253     }
 254 
 255     /**
 256      * Test of loadAll method, of class ImageStorage.
 257      */
 258     @Test
 259     public void testLoadMagnifyAspectRough() throws IOException, InterruptedException {
 260         loadTest("testLoadMagnifyAspectRough", "Output_scaled",
 261                 (int)(MAGNIFY_FRACTION*rawHeight), (int)(MAGNIFY_FRACTION*rawWidth),
 262                 true, false);
 263     }
 264 
 265     /**
 266      * Test of loadAll method, of class ImageStorage.
 267      */
 268     @Test
 269     public void testLoadMagnifyNoAspectSmooth() throws IOException, InterruptedException {
 270         loadTest("testLoadMagnifyNoAspectSmooth", "Output_scaled",
 271                 (int)(MAGNIFY_FRACTION*rawHeight), (int)(MAGNIFY_FRACTION*rawWidth),
 272                 false, true);
 273     }
 274 
 275     /**
 276      * Test of loadAll method, of class ImageStorage.
 277      */
 278     @Test
 279     public void testLoadMagnifyAspectSmooth() throws IOException, InterruptedException {
 280         loadTest("testLoadMagnifyAspectSmooth", "Output_scaled",
 281                 (int)(MAGNIFY_FRACTION*rawHeight), (int)(MAGNIFY_FRACTION*rawWidth),
 282                 true, true);
 283     }
 284 
 285     /**
 286      * Test of loadAll method, of class ImageStorage.
 287      */
 288     @Test
 289     public void testLoadMinifyNoAspectRough() throws IOException, InterruptedException {
 290         loadTest("testLoadMinifyNoAspectRough", "Output_scaled",
 291                 (int)(MINIFY_FRACTION*rawHeight), (int)(MINIFY_FRACTION*rawWidth),
 292                 false, false);
 293     }
 294 
 295     /**
 296      * Test of loadAll method, of class ImageStorage.
 297      */
 298     @Test
 299     public void testLoadMinifyAspectRough() throws IOException, InterruptedException {
 300         loadTest("testLoadMinifyAspectRough", "Output_scaled",
 301                 (int)(MINIFY_FRACTION*rawHeight), (int)(MINIFY_FRACTION*rawWidth),
 302                 true, false);
 303     }
 304 
 305     /**
 306      * Test of loadAll method, of class ImageStorage.
 307      */
 308     @Test
 309     public void testLoadMinifyNoAspectSmooth() throws IOException, InterruptedException {
 310         loadTest("testLoadMinifyNoAspectSmooth", "Output_scaled",
 311                 (int)(MINIFY_FRACTION*rawHeight), (int)(MINIFY_FRACTION*rawWidth),
 312                 false, true);
 313     }
 314 
 315     /**
 316      * Test of loadAll method, of class ImageStorage.
 317      */
 318     @Test
 319     public void testLoadMinifyAspectSmooth() throws IOException, InterruptedException {
 320         loadTest("testLoadMinifyAspectSmooth", "Output_scaled",
 321                 (int)(MINIFY_FRACTION*rawHeight), (int)(MINIFY_FRACTION*rawWidth),
 322                 true, true);
 323     }
 324 
 325     private void loadTest(String testName, String outbasename, int width, int height,
 326             boolean preserveAspectRatio, boolean smooth)
 327             throws IOException, InterruptedException {
 328         System.out.println(testName+", "+width+"x"+height+
 329                 ", preserveAspectRatio: "+preserveAspectRatio+
 330                 ", smooth: "+smooth);
 331         String input = System.getProperty("image.input.url");
 332         String outBase = System.getProperty("user.home") +
 333                 System.getProperty("file.separator") + outbasename;
 334         loadAllTest(input, outBase, width, height, preserveAspectRatio, smooth);
 335         Thread.sleep(3000);
 336     }
 337 
 338     private void loadAllTest(String input, String output,
 339             int width, int height, boolean preserveAspectRatio, boolean smooth)
 340             throws IOException {
 341         ImageLoadListener listener = new ImageLoadListener() {
 342 
 343             public void imageLoadProgress(ImageLoader loader, float percentageComplete) {
 344                 if (percentageComplete == 0.0) {
 345                     System.out.println("Image loading started (" + percentageComplete + "%).");
 346                 } else if (percentageComplete == 100.0) {
 347                     System.out.println("Image loading completed (" + percentageComplete + "%).");
 348                 } else {
 349                     System.out.println(percentageComplete + "% complete ...");
 350                 }
 351             }
 352 
 353             public void imageLoadWarning(ImageLoader loader, String message) {
 354                 System.err.println("WARNING: " + loader + ": " + message);
 355             }
 356 
 357             public void imageLoadMetaData(ImageLoader loader, ImageMetadata metadata) {
 358                 System.out.println("metadata ready = " + metadata);
 359             }
 360         };
 361 
 362         ImageFrame[] prismImages = null;
 363         try {
 364             long startTime = System.nanoTime();
 365             prismImages = ImageStorage.loadAll(input, listener, width, height, preserveAspectRatio, smooth);
 366             long finishTime = System.nanoTime();
 367             System.out.println("Execution time: " + ((finishTime - startTime) / 1000000.0F) + " ms");
 368         } catch (IOException e) {
 369             System.err.print("ERROR!: ");
 370             Throwable t = e.getCause();
 371             e.printStackTrace();
 372             if (t != null) {
 373                 t.printStackTrace();
 374             }
 375         }
 376 
 377         if (prismImages != null) {
 378 
 379             for (int i = 0; i < prismImages.length; i++) {
 380                 ImageFrame im = prismImages[i];
 381                 System.out.println(im.getImageType() + " " + im.getWidth() + "x" + im.getHeight());
 382                 if (rawWidth < 0) {
 383                     rawWidth = im.getWidth();
 384                     rawHeight = im.getHeight();
 385                 }
 386                 ImageMetadata md = im.getMetadata();
 387                 if (md != null) {
 388                     System.out.println(im.getMetadata());
 389                 }
 390                 if (output != null) {
 391                     BufferedImage bi = getAsBufferedImage(im);
 392                     show(bi, input);
 393                     if (WRITE_OUTPUT) {
 394                         try {
 395                             Class.forName("javax.imageio.ImageIO");
 396                             javax.imageio.ImageIO.write(bi, "PNG",
 397                                     new java.io.File(output + "_" + i + ".png"));
 398                         } catch(Exception e) {
 399                             System.err.println("Cannot locate javax.imageio.ImageIO: output write skipped");
 400                         }
 401                     }
 402                 }
 403             }
 404         } else {
 405             System.out.println("No images loaded from " + input + "!");
 406         }
 407     }
 408 }