1 /* 2 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 package j2dbench.tests.iio; 42 43 import java.awt.Graphics; 44 import java.awt.image.BufferedImage; 45 import java.io.BufferedOutputStream; 46 import java.io.ByteArrayOutputStream; 47 import java.io.File; 48 import java.io.FileOutputStream; 49 import java.io.IOException; 50 import java.io.OutputStream; 51 import java.util.ArrayList; 52 import java.util.List; 53 import javax.imageio.ImageIO; 54 import javax.imageio.ImageWriter; 55 import javax.imageio.event.IIOWriteProgressListener; 56 import javax.imageio.spi.IIORegistry; 57 import javax.imageio.spi.ImageWriterSpi; 58 import javax.imageio.stream.ImageOutputStream; 59 60 import j2dbench.Group; 61 import j2dbench.Modifier; 62 import j2dbench.Option; 63 import j2dbench.Result; 64 import j2dbench.Test; 65 import j2dbench.TestEnvironment; 66 67 abstract class OutputImageTests extends OutputTests { 68 69 private static final int TEST_IMAGEIO = 1; 70 private static final int TEST_IMAGEWRITER = 2; 71 72 private static Group imageRoot; 73 74 private static Group imageioRoot; 75 private static Group imageioOptRoot; 76 private static ImageWriterSpi[] imageioWriterSpis; 77 private static String[] imageioWriteFormatShortNames; 78 private static Option imageioWriteFormatList; 79 private static Group imageioTestRoot; 80 81 private static Group imageWriterRoot; 82 private static Group imageWriterOptRoot; 83 private static Option installListenerTog; 84 private static Group imageWriterTestRoot; 85 86 public static void init() { 87 imageRoot = new Group(outputRoot, "image", "Image Writing Benchmarks"); 88 imageRoot.setTabbed(); 89 90 // Image I/O Benchmarks 91 if (hasImageIO) { 92 imageioRoot = new Group(imageRoot, "imageio", "Image I/O"); 93 94 // Image I/O Options 95 imageioOptRoot = new Group(imageioRoot, "opts", 96 "Image I/O Options"); 97 initIIOWriteFormats(); 98 imageioWriteFormatList = 99 new Option.ObjectList(imageioOptRoot, 100 "format", "Image Format", 101 imageioWriteFormatShortNames, 102 imageioWriterSpis, 103 imageioWriteFormatShortNames, 104 imageioWriteFormatShortNames, 105 0x0); 106 107 // Image I/O Tests 108 imageioTestRoot = new Group(imageioRoot, "tests", 109 "Image I/O Tests"); 110 new ImageIOWrite(); 111 112 // ImageWriter Options 113 imageWriterRoot = new Group(imageioRoot, "writer", 114 "ImageWriter Benchmarks"); 115 imageWriterOptRoot = new Group(imageWriterRoot, "opts", 116 "ImageWriter Options"); 117 installListenerTog = 118 new Option.Toggle(imageWriterOptRoot, 119 "installListener", 120 "Install Progress Listener", 121 Option.Toggle.Off); 122 123 // ImageWriter Tests 124 imageWriterTestRoot = new Group(imageWriterRoot, "tests", 125 "ImageWriter Tests"); 126 new ImageWriterWrite(); 127 } 128 } 129 130 private static void initIIOWriteFormats() { 131 List spis = new ArrayList(); 132 List shortNames = new ArrayList(); 133 134 ImageIO.scanForPlugins(); 135 IIORegistry registry = IIORegistry.getDefaultInstance(); 136 java.util.Iterator writerspis = 137 registry.getServiceProviders(ImageWriterSpi.class, false); 138 while (writerspis.hasNext()) { 139 // REMIND: there could be more than one non-core plugin for 140 // a particular format, as is the case for JPEG2000 in the JAI 141 // IIO Tools package, so we should support that somehow 142 ImageWriterSpi spi = (ImageWriterSpi)writerspis.next(); 143 String klass = spi.getClass().getName(); 144 String format = spi.getFormatNames()[0].toLowerCase(); 145 String suffix = spi.getFileSuffixes()[0].toLowerCase(); 146 if (suffix == null || suffix.equals("")) { 147 suffix = format; 148 } 149 String shortName; 150 if (klass.startsWith("com.sun.imageio.plugins")) { 151 shortName = "core-" + suffix; 152 } else { 153 shortName = "ext-" + suffix; 154 } 155 spis.add(spi); 156 shortNames.add(shortName); 157 } 158 159 imageioWriterSpis = new ImageWriterSpi[spis.size()]; 160 imageioWriterSpis = (ImageWriterSpi[])spis.toArray(imageioWriterSpis); 161 imageioWriteFormatShortNames = new String[shortNames.size()]; 162 imageioWriteFormatShortNames = 163 (String[])shortNames.toArray(imageioWriteFormatShortNames); 164 } 165 166 protected OutputImageTests(Group parent, 167 String nodeName, String description) 168 { 169 super(parent, nodeName, description); 170 } 171 172 public void cleanupTest(TestEnvironment env, Object ctx) { 173 Context iioctx = (Context)ctx; 174 iioctx.cleanup(env); 175 } 176 177 private static class Context extends OutputTests.Context { 178 String format; 179 BufferedImage image; 180 ImageWriter writer; 181 182 Context(TestEnvironment env, Result result, int testType) { 183 super(env, result); 184 185 String content = (String)env.getModifier(contentList); 186 if (content == null) { 187 content = CONTENT_BLANK; 188 } 189 // REMIND: add option for non-opaque images 190 image = createBufferedImage(size, size, content, false); 191 192 result.setUnits(size*size); 193 result.setUnitName("pixel"); 194 195 if (testType == TEST_IMAGEIO || testType == TEST_IMAGEWRITER) { 196 ImageWriterSpi writerspi = 197 (ImageWriterSpi)env.getModifier(imageioWriteFormatList); 198 format = writerspi.getFileSuffixes()[0].toLowerCase(); 199 if (testType == TEST_IMAGEWRITER) { 200 try { 201 writer = writerspi.createWriterInstance(); 202 } catch (IOException e) { 203 System.err.println("error creating writer"); 204 e.printStackTrace(); 205 } 206 if (env.isEnabled(installListenerTog)) { 207 writer.addIIOWriteProgressListener( 208 new WriteProgressListener()); 209 } 210 } 211 if (format.equals("wbmp")) { 212 // REMIND: this is a hack to create an image that the 213 // WBMPImageWriter can handle (a better approach 214 // would involve checking the ImageTypeSpecifier 215 // of the writer's default image param) 216 BufferedImage newimg = 217 new BufferedImage(size, size, 218 BufferedImage.TYPE_BYTE_BINARY); 219 Graphics g = newimg.createGraphics(); 220 g.drawImage(image, 0, 0, null); 221 g.dispose(); 222 image = newimg; 223 } 224 } else { // testType == TEST_JPEGCODEC 225 format = "jpeg"; 226 } 227 228 initOutput(); 229 } 230 231 void initContents(File f) throws IOException { 232 ImageIO.write(image, format, f); 233 } 234 235 void initContents(OutputStream out) throws IOException { 236 ImageIO.write(image, format, out); 237 } 238 239 void cleanup(TestEnvironment env) { 240 super.cleanup(env); 241 if (writer != null) { 242 writer.dispose(); 243 writer = null; 244 } 245 } 246 } 247 248 private static class ImageIOWrite extends OutputImageTests { 249 public ImageIOWrite() { 250 super(imageioTestRoot, 251 "imageioWrite", 252 "ImageIO.write()"); 253 addDependency(generalDestRoot, 254 new Modifier.Filter() { 255 public boolean isCompatible(Object val) { 256 // ImageIO.write() handles FILE and ARRAY, but 257 // not FILECHANNEL (well, I suppose we could create 258 // an ImageOutputStream from a FileChannel source, 259 // but that's not a common use case; FileChannel is 260 // better handled by the ImageWriter tests below) 261 OutputType t = (OutputType)val; 262 return (t.getType() != OUTPUT_FILECHANNEL); 263 } 264 }); 265 addDependencies(imageioOptRoot, true); 266 } 267 268 public Object initTest(TestEnvironment env, Result result) { 269 return new Context(env, result, TEST_IMAGEIO); 270 } 271 272 public void runTest(Object ctx, int numReps) { 273 final Context ictx = (Context)ctx; 274 final Object output = ictx.output; 275 final BufferedImage image = ictx.image; 276 final String format = ictx.format; 277 final int outputType = ictx.outputType; 278 switch (outputType) { 279 case OUTPUT_FILE: 280 do { 281 try { 282 ImageIO.write(image, format, (File)output); 283 } catch (Exception e) { 284 e.printStackTrace(); 285 } 286 } while (--numReps >= 0); 287 break; 288 case OUTPUT_ARRAY: 289 do { 290 try { 291 ByteArrayOutputStream baos = 292 new ByteArrayOutputStream(); 293 BufferedOutputStream bos = 294 new BufferedOutputStream(baos); 295 ImageIO.write(image, format, bos); 296 baos.close(); 297 } catch (Exception e) { 298 e.printStackTrace(); 299 } 300 } while (--numReps >= 0); 301 break; 302 default: 303 throw new IllegalArgumentException("Invalid output type"); 304 } 305 } 306 } 307 308 private static class ImageWriterWrite extends OutputImageTests { 309 public ImageWriterWrite() { 310 super(imageWriterTestRoot, 311 "write", 312 "ImageWriter.write()"); 313 addDependency(generalDestRoot); 314 addDependencies(imageioGeneralOptRoot, true); 315 addDependencies(imageioOptRoot, true); 316 addDependencies(imageWriterOptRoot, true); 317 } 318 319 public Object initTest(TestEnvironment env, Result result) { 320 return new Context(env, result, TEST_IMAGEWRITER); 321 } 322 323 public void runTest(Object ctx, int numReps) { 324 final Context ictx = (Context)ctx; 325 final ImageWriter writer = ictx.writer; 326 final BufferedImage image = ictx.image; 327 do { 328 try { 329 ImageOutputStream ios = ictx.createImageOutputStream(); 330 writer.setOutput(ios); 331 writer.write(image); 332 writer.reset(); 333 ios.close(); 334 ictx.closeOriginalStream(); 335 } catch (IOException e) { 336 e.printStackTrace(); 337 } 338 } while (--numReps >= 0); 339 } 340 } 341 342 private static class WriteProgressListener 343 implements IIOWriteProgressListener 344 { 345 public void imageStarted(ImageWriter source, int imageIndex) {} 346 public void imageProgress(ImageWriter source, 347 float percentageDone) {} 348 public void imageComplete(ImageWriter source) {} 349 public void thumbnailStarted(ImageWriter source, 350 int imageIndex, int thumbnailIndex) {} 351 public void thumbnailProgress(ImageWriter source, 352 float percentageDone) {} 353 public void thumbnailComplete(ImageWriter source) {} 354 public void writeAborted(ImageWriter source) {} 355 } 356 }