/*
* Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This source code is provided to illustrate the usage of a given feature
* or technique and has been deliberately simplified. Additional steps
* required for a production-quality application, such as security checks,
* input validation and proper error handling, might not be present in
* this sample code.
*/
package j2dbench.tests.iio;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import j2dbench.Group;
import j2dbench.Modifier;
import j2dbench.Option;
import j2dbench.Result;
import j2dbench.Test;
import j2dbench.TestEnvironment;
abstract class InputImageTests extends InputTests {
private static final int TEST_TOOLKIT = 1;
private static final int TEST_IMAGEIO = 2;
private static final int TEST_IMAGEREADER = 3;
private static Group imageRoot;
private static Group toolkitRoot;
private static Group toolkitOptRoot;
private static Option toolkitReadFormatList;
private static Group toolkitTestRoot;
private static Group imageioRoot;
private static Group imageioOptRoot;
private static ImageReaderSpi[] imageioReaderSpis;
private static String[] imageioReadFormatShortNames;
private static Option imageioReadFormatList;
private static Group imageioTestRoot;
private static Group imageReaderRoot;
private static Group imageReaderOptRoot;
private static Option seekForwardOnlyTog;
private static Option ignoreMetadataTog;
private static Option installListenerTog;
private static Group imageReaderTestRoot;
public static void init() {
imageRoot = new Group(inputRoot, "image", "Image Reading Benchmarks");
imageRoot.setTabbed();
// Toolkit Benchmarks
toolkitRoot = new Group(imageRoot, "toolkit", "Toolkit");
toolkitOptRoot = new Group(toolkitRoot, "opts", "Toolkit Options");
String[] tkFormats = new String[] {"gif", "jpg", "png"};
toolkitReadFormatList =
new Option.ObjectList(toolkitOptRoot,
"format", "Image Format",
tkFormats, tkFormats,
tkFormats, tkFormats,
0x0);
toolkitTestRoot = new Group(toolkitRoot, "tests", "Toolkit Tests");
new ToolkitCreateImage();
// Image I/O Benchmarks
if (hasImageIO) {
imageioRoot = new Group(imageRoot, "imageio", "Image I/O");
// Image I/O Options
imageioOptRoot = new Group(imageioRoot, "opts",
"Image I/O Options");
initIIOReadFormats();
imageioReadFormatList =
new Option.ObjectList(imageioOptRoot,
"format", "Image Format",
imageioReadFormatShortNames,
imageioReaderSpis,
imageioReadFormatShortNames,
imageioReadFormatShortNames,
0x0);
// Image I/O Tests
imageioTestRoot = new Group(imageioRoot, "tests",
"Image I/O Tests");
new ImageIORead();
// ImageReader Options
imageReaderRoot = new Group(imageioRoot, "reader",
"ImageReader Benchmarks");
imageReaderOptRoot = new Group(imageReaderRoot, "opts",
"ImageReader Options");
seekForwardOnlyTog =
new Option.Toggle(imageReaderOptRoot,
"seekForwardOnly",
"Seek Forward Only",
Option.Toggle.On);
ignoreMetadataTog =
new Option.Toggle(imageReaderOptRoot,
"ignoreMetadata",
"Ignore Metadata",
Option.Toggle.On);
installListenerTog =
new Option.Toggle(imageReaderOptRoot,
"installListener",
"Install Progress Listener",
Option.Toggle.Off);
// ImageReader Tests
imageReaderTestRoot = new Group(imageReaderRoot, "tests",
"ImageReader Tests");
new ImageReaderRead();
new ImageReaderGetImageMetadata();
}
}
private static void initIIOReadFormats() {
List spis = new ArrayList();
List shortNames = new ArrayList();
ImageIO.scanForPlugins();
IIORegistry registry = IIORegistry.getDefaultInstance();
java.util.Iterator readerspis =
registry.getServiceProviders(ImageReaderSpi.class, false);
while (readerspis.hasNext()) {
// REMIND: there could be more than one non-core plugin for
// a particular format, as is the case for JPEG2000 in the JAI
// IIO Tools package, so we should support that somehow
ImageReaderSpi spi = (ImageReaderSpi)readerspis.next();
String klass = spi.getClass().getName();
String format = spi.getFormatNames()[0].toLowerCase();
String suffix = spi.getFileSuffixes()[0].toLowerCase();
if (suffix == null || suffix.equals("")) {
suffix = format;
}
String shortName;
if (klass.startsWith("com.sun.imageio.plugins")) {
shortName = "core-" + suffix;
} else {
shortName = "ext-" + suffix;
}
spis.add(spi);
shortNames.add(shortName);
}
imageioReaderSpis = new ImageReaderSpi[spis.size()];
imageioReaderSpis = (ImageReaderSpi[])spis.toArray(imageioReaderSpis);
imageioReadFormatShortNames = new String[shortNames.size()];
imageioReadFormatShortNames =
(String[])shortNames.toArray(imageioReadFormatShortNames);
}
protected InputImageTests(Group parent,
String nodeName, String description)
{
super(parent, nodeName, description);
}
public void cleanupTest(TestEnvironment env, Object ctx) {
Context iioctx = (Context)ctx;
iioctx.cleanup(env);
}
private static class Context extends InputTests.Context {
String format;
BufferedImage image;
ImageReader reader;
boolean seekForwardOnly;
boolean ignoreMetadata;
Context(TestEnvironment env, Result result, int testType) {
super(env, result);
String content = (String)env.getModifier(contentList);
if (content == null) {
content = CONTENT_BLANK;
}
// REMIND: add option for non-opaque images
image = createBufferedImage(size, size, content, false);
result.setUnits(size*size);
result.setUnitName("pixel");
if (testType == TEST_IMAGEIO || testType == TEST_IMAGEREADER) {
ImageReaderSpi readerspi =
(ImageReaderSpi)env.getModifier(imageioReadFormatList);
format = readerspi.getFileSuffixes()[0].toLowerCase();
if (testType == TEST_IMAGEREADER) {
seekForwardOnly = env.isEnabled(seekForwardOnlyTog);
ignoreMetadata = env.isEnabled(ignoreMetadataTog);
try {
reader = readerspi.createReaderInstance();
} catch (IOException e) {
System.err.println("error creating reader");
e.printStackTrace();
}
if (env.isEnabled(installListenerTog)) {
reader.addIIOReadProgressListener(
new ReadProgressListener());
}
}
if (format.equals("wbmp")) {
// REMIND: this is a hack to create an image that the
// WBMPImageWriter can handle (a better approach
// would involve checking the ImageTypeSpecifier
// of the writer's default image param)
BufferedImage newimg =
new BufferedImage(size, size,
BufferedImage.TYPE_BYTE_BINARY);
Graphics g = newimg.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
image = newimg;
}
} else if (testType == TEST_TOOLKIT) {
format = (String)env.getModifier(toolkitReadFormatList);
} else { // testType == TEST_JPEGCODEC
format = "jpeg";
}
initInput();
}
void initContents(File f) throws IOException {
ImageIO.write(image, format, f);
}
void initContents(OutputStream out) throws IOException {
ImageIO.write(image, format, out);
}
void cleanup(TestEnvironment env) {
super.cleanup(env);
if (reader != null) {
reader.dispose();
reader = null;
}
}
}
private static class ToolkitCreateImage extends InputImageTests {
private static final Component canvas = new Component() {};
public ToolkitCreateImage() {
super(toolkitTestRoot,
"createImage",
"Toolkit.createImage()");
addDependency(generalSourceRoot,
new Modifier.Filter() {
public boolean isCompatible(Object val) {
// Toolkit handles FILE, URL, and ARRAY, but
// not FILECHANNEL
InputType t = (InputType)val;
return (t.getType() != INPUT_FILECHANNEL);
}
});
addDependencies(toolkitOptRoot, true);
}
public Object initTest(TestEnvironment env, Result result) {
return new Context(env, result, TEST_TOOLKIT);
}
public void runTest(Object ctx, int numReps) {
final Context ictx = (Context)ctx;
final Object input = ictx.input;
final int inputType = ictx.inputType;
final Toolkit tk = Toolkit.getDefaultToolkit();
final MediaTracker mt = new MediaTracker(canvas);
switch (inputType) {
case INPUT_FILE:
String filename = ((File)input).getAbsolutePath();
do {
try {
Image img = tk.createImage(filename);
mt.addImage(img, 0);
mt.waitForID(0, 0);
mt.removeImage(img, 0);
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
case INPUT_URL:
do {
try {
Image img = tk.createImage((URL)input);
mt.addImage(img, 0);
mt.waitForID(0, 0);
mt.removeImage(img, 0);
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
case INPUT_ARRAY:
do {
try {
Image img = tk.createImage((byte[])input);
mt.addImage(img, 0);
mt.waitForID(0, 0);
mt.removeImage(img, 0);
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
default:
throw new IllegalArgumentException("Invalid input type");
}
}
}
private static class ImageIORead extends InputImageTests {
public ImageIORead() {
super(imageioTestRoot,
"imageioRead",
"ImageIO.read()");
addDependency(generalSourceRoot,
new Modifier.Filter() {
public boolean isCompatible(Object val) {
// ImageIO.read() handles FILE, URL, and ARRAY, but
// not FILECHANNEL (well, I suppose we could create
// an ImageInputStream from a FileChannel source,
// but that's not a common use case; FileChannel is
// better handled by the ImageReader tests below)
InputType t = (InputType)val;
return (t.getType() != INPUT_FILECHANNEL);
}
});
addDependencies(imageioOptRoot, true);
}
public Object initTest(TestEnvironment env, Result result) {
return new Context(env, result, TEST_IMAGEIO);
}
public void runTest(Object ctx, int numReps) {
final Context ictx = (Context)ctx;
final Object input = ictx.input;
final int inputType = ictx.inputType;
switch (inputType) {
case INPUT_FILE:
do {
try {
ImageIO.read((File)input);
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
case INPUT_URL:
do {
try {
ImageIO.read((URL)input);
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
case INPUT_ARRAY:
do {
try {
ByteArrayInputStream bais =
new ByteArrayInputStream((byte[])input);
BufferedInputStream bis =
new BufferedInputStream(bais);
ImageIO.read(bis);
bais.close();
} catch (Exception e) {
e.printStackTrace();
}
} while (--numReps >= 0);
break;
default:
throw new IllegalArgumentException("Invalid input type");
}
}
}
private static class ImageReaderRead extends InputImageTests {
public ImageReaderRead() {
super(imageReaderTestRoot,
"read",
"ImageReader.read()");
addDependency(generalSourceRoot);
addDependencies(imageioGeneralOptRoot, true);
addDependencies(imageioOptRoot, true);
addDependencies(imageReaderOptRoot, true);
}
public Object initTest(TestEnvironment env, Result result) {
return new Context(env, result, TEST_IMAGEREADER);
}
public void runTest(Object ctx, int numReps) {
final Context ictx = (Context)ctx;
final ImageReader reader = ictx.reader;
final boolean seekForwardOnly = ictx.seekForwardOnly;
final boolean ignoreMetadata = ictx.ignoreMetadata;
do {
try {
ImageInputStream iis = ictx.createImageInputStream();
reader.setInput(iis, seekForwardOnly, ignoreMetadata);
reader.read(0);
reader.reset();
iis.close();
ictx.closeOriginalStream();
} catch (IOException e) {
e.printStackTrace();
}
} while (--numReps >= 0);
}
}
private static class ImageReaderGetImageMetadata extends InputImageTests {
public ImageReaderGetImageMetadata() {
super(imageReaderTestRoot,
"getImageMetadata",
"ImageReader.getImageMetadata()");
addDependency(generalSourceRoot);
addDependencies(imageioGeneralOptRoot, true);
addDependencies(imageioOptRoot, true);
addDependencies(imageReaderOptRoot, true);
}
public Object initTest(TestEnvironment env, Result result) {
Context ctx = new Context(env, result, TEST_IMAGEREADER);
// override units since this test doesn't read "pixels"
result.setUnits(1);
result.setUnitName("image");
return ctx;
}
public void runTest(Object ctx, int numReps) {
final Context ictx = (Context)ctx;
final ImageReader reader = ictx.reader;
final boolean seekForwardOnly = ictx.seekForwardOnly;
final boolean ignoreMetadata = ictx.ignoreMetadata;
do {
try {
ImageInputStream iis = ictx.createImageInputStream();
reader.setInput(iis, seekForwardOnly, ignoreMetadata);
reader.getImageMetadata(0);
reader.reset();
iis.close();
ictx.closeOriginalStream();
} catch (IOException e) {
e.printStackTrace();
}
} while (--numReps >= 0);
}
}
private static class ReadProgressListener
implements IIOReadProgressListener
{
public void sequenceStarted(ImageReader source, int minIndex) {}
public void sequenceComplete(ImageReader source) {}
public void imageStarted(ImageReader source, int imageIndex) {}
public void imageProgress(ImageReader source, float percentageDone) {}
public void imageComplete(ImageReader source) {}
public void thumbnailStarted(ImageReader source,
int imageIndex, int thumbnailIndex) {}
public void thumbnailProgress(ImageReader source,
float percentageDone) {}
public void thumbnailComplete(ImageReader source) {}
public void readAborted(ImageReader source) {}
}
}