Merge commit 'hamnis/master'

Conflicts:
	imageio/imageio-batik/pom.xml
	imageio/imageio-core/pom.xml
	imageio/imageio-ico/pom.xml
	imageio/imageio-iff/pom.xml
	imageio/imageio-metadata/pom.xml
	imageio/imageio-pict/pom.xml
	imageio/imageio-psd/pom.xml
	imageio/imageio-reference/pom.xml
	imageio/imageio-thumbsdb/pom.xml
	twelvemonkeys-core/pom.xml
	twelvemonkeys-imageio/pom.xml
	twelvemonkeys-servlet/pom.xml
This commit is contained in:
Harald Kuhr
2010-02-07 20:43:44 +01:00
576 changed files with 440 additions and 439 deletions

View File

@@ -0,0 +1,25 @@
Copyright (c) 2009, Harald Kuhr
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 "TwelveMonkeys" 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.

View File

@@ -0,0 +1,65 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.0-SNAPSHOT</version>
</parent>
<artifactId>imageio-batik</artifactId>
<name>TwelveMonkeys ImageIO Batik Plugin</name>
<description>
<![CDATA[
ImageIO wrapper for the Batik SVG Toolkit, enabling Scalable Vector Graphics (SVG) support.
See the <a href="http://xmlgraphics.apache.org/batik/">Batik Home page</a>
for more information.]]>
</description>
<dependencies>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>batik</groupId>
<artifactId>batik-rasterizer-ext</artifactId>
<version>1.6-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>batik</groupId>
<artifactId>batik-svggen</artifactId>
<version>1.6-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>batik</groupId>
<artifactId>batik-transcoder</artifactId>
<version>1.6-1</version>
<scope>provided</scope>
<!--
There seems to be some weirdness in the
Batik/FOP poms (Batik depends on FOP 0.20-5) that screws things up,
making everything end up depending on Batik 1.5, not 1.6
-->
<exclusions>
<exclusion>
<groupId>fop</groupId>
<artifactId>fop</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,574 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.svg;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageReaderBase;
import com.twelvemonkeys.imageio.util.IIOUtil;
import org.apache.batik.bridge.*;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.gvt.CanvasGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.renderer.ConcreteImageRendererFactory;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.gvt.renderer.ImageRendererFactory;
import org.apache.batik.transcoder.*;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.util.ParsedURL;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGSVGElement;
import javax.imageio.IIOException;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
/**
* Image reader for SVG document fragments.
* <p/>
*
* @author Harald Kuhr
* @author Inpspired by code from the Batik Team
* @version $Id: $
* @see <A href="http://www.mail-archive.com/batik-dev@xml.apache.org/msg00992.html">batik-dev</A>
*/
public class SVGImageReader extends ImageReaderBase {
private Rasterizer mRasterizer = new Rasterizer();
/**
* Creates an {@code SVGImageReader}.
*
* @param pProvider the provider
*/
public SVGImageReader(ImageReaderSpi pProvider) {
super(pProvider);
}
protected void resetMembers() {
}
@Override
public void dispose() {
super.dispose();
mRasterizer = null;
}
@Override
public void setInput(Object pInput, boolean pSeekForwardOnly, boolean pIgnoreMetadata) {
super.setInput(pInput, pSeekForwardOnly, pIgnoreMetadata);
if (mImageInput != null) {
TranscoderInput input = new TranscoderInput(IIOUtil.createStreamAdapter(mImageInput));
mRasterizer.setInput(input);
}
}
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
checkBounds(pIndex);
String baseURI = null;
if (pParam instanceof SVGReadParam) {
SVGReadParam svgParam = (SVGReadParam) pParam;
// Set IIOParams as hints
// Note: The cast to Map invokes a different method that preserves
// unset defaults, DO NOT REMOVE!
mRasterizer.setTranscodingHints((Map) paramsToHints(svgParam));
// Get the base URI (not a hint)
baseURI = svgParam.getBaseURI();
}
Dimension size;
if (pParam != null && (size = pParam.getSourceRenderSize()) != null) {
// Use size...
}
else {
size = new Dimension(getWidth(pIndex), getHeight(pIndex));
}
BufferedImage destination = getDestination(pParam, getImageTypes(pIndex), size.width, size.height);
// Read in the image, using the Batik Transcoder
try {
processImageStarted(pIndex);
mRasterizer.mTranscoderInput.setURI(baseURI);
BufferedImage image = mRasterizer.getImage();
Graphics2D g = destination.createGraphics();
try {
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
g.drawImage(image, 0, 0, null); // TODO: Dest offset?
}
finally {
g.dispose();
}
processImageComplete();
return destination;
}
catch (TranscoderException e) {
throw new IIOException(e.getMessage(), e);
}
}
private TranscodingHints paramsToHints(SVGReadParam pParam) throws IOException {
TranscodingHints hints = new TranscodingHints();
// Note: We must allow generic ImageReadParams, so converting to
// TanscodingHints should be done outside the SVGReadParam class.
// Set dimensions
Dimension size = pParam.getSourceRenderSize();
Dimension origSize = new Dimension(getWidth(0), getHeight(0));
if (size == null) {
// SVG is not a pixel based format, but we'll scale it, according to
// the subsampling for compatibility
size = getSourceRenderSizeFromSubsamping(pParam, origSize);
}
if (size != null) {
hints.put(ImageTranscoder.KEY_WIDTH, new Float(size.getWidth()));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(size.getHeight()));
}
// Set area of interest
Rectangle region = pParam.getSourceRegion();
if (region != null) {
hints.put(ImageTranscoder.KEY_AOI, region);
// Avoid that the batik transcoder scales the AOI up to original image size
if (size == null) {
hints.put(ImageTranscoder.KEY_WIDTH, new Float(region.getWidth()));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(region.getHeight()));
}
else {
// Need to resize here...
double xScale = size.getWidth() / origSize.getWidth();
double yScale = size.getHeight() / origSize.getHeight();
hints.put(ImageTranscoder.KEY_WIDTH, new Float(region.getWidth() * xScale));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(region.getHeight() * yScale));
}
}
else if (size != null) {
// Allow non-uniform scaling
hints.put(ImageTranscoder.KEY_AOI, new Rectangle(origSize));
}
// Background color
Paint bg = pParam.getBackgroundColor();
if (bg != null) {
hints.put(ImageTranscoder.KEY_BACKGROUND_COLOR, bg);
}
return hints;
}
private Dimension getSourceRenderSizeFromSubsamping(ImageReadParam pParam, Dimension pOrigSize) {
if (pParam.getSourceXSubsampling() > 1 || pParam.getSourceYSubsampling() > 1) {
return new Dimension((int) (pOrigSize.width / (float) pParam.getSourceXSubsampling()),
(int) (pOrigSize.height / (float) pParam.getSourceYSubsampling()));
}
return null;
}
public ImageReadParam getDefaultReadParam() {
return new SVGReadParam();
}
public int getWidth(int pIndex) throws IOException {
checkBounds(pIndex);
try {
return mRasterizer.getDefaultWidth();
}
catch (TranscoderException e) {
throw new IIOException(e.getMessage(), e);
}
}
public int getHeight(int pIndex) throws IOException {
checkBounds(pIndex);
try {
return mRasterizer.getDefaultHeight();
}
catch (TranscoderException e) {
throw new IIOException(e.getMessage(), e);
}
}
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
return Collections.singleton(ImageTypeSpecifier.createFromRenderedImage(mRasterizer.createImage(1, 1))).iterator();
}
/**
* An image transcoder that stores the resulting image.
* <p/>
* NOTE: This class includes a lot of copy and paste code from the Batik classes
* and needs major refactoring!
*/
private class Rasterizer extends SVGAbstractTranscoder /*ImageTranscoder*/ {
BufferedImage mImage = null;
private TranscoderInput mTranscoderInput;
private float mDefaultWidth;
private float mDefaultHeight;
private boolean mInit = false;
private SVGOMDocument mDocument;
private String mURI;
private GraphicsNode mGVTRoot;
private TranscoderException mException;
private BridgeContext mContext;
public BufferedImage createImage(int w, int h) {
return ImageUtil.createTransparent(w, h);//, BufferedImage.TYPE_INT_ARGB);
}
// This is cheating... We don't fully transcode after all
protected void transcode(Document document, String uri, TranscoderOutput output) throws TranscoderException {
// Sets up root, curTxf & curAoi
// ----
if ((document != null) &&
!(document.getImplementation() instanceof SVGDOMImplementation)) {
DOMImplementation impl;
impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION);
// impl = ExtensibleSVGDOMImplementation.getDOMImplementation();
document = DOMUtilities.deepCloneDocument(document, impl);
if (uri != null) {
try {
URL url = new URL(uri);
((SVGOMDocument) document).setURLObject(url);
}
catch (MalformedURLException ignore) {
}
}
}
ctx = createBridgeContext();
SVGOMDocument svgDoc = (SVGOMDocument) document;
//SVGSVGElement root = svgDoc.getRootElement();
// build the GVT tree
builder = new GVTBuilder();
// flag that indicates if the document is dynamic
boolean isDynamic =
(hints.containsKey(KEY_EXECUTE_ONLOAD) &&
(Boolean) hints.get(KEY_EXECUTE_ONLOAD) &&
BaseScriptingEnvironment.isDynamicDocument(ctx, svgDoc));
if (isDynamic) {
ctx.setDynamicState(BridgeContext.DYNAMIC);
}
// Modified code below:
GraphicsNode root = null;
try {
root = builder.build(ctx, svgDoc);
}
catch (BridgeException ex) {
// Note: This might fail, but we STILL have the dimensions we need
// However, we need to reparse later...
//throw new TranscoderException(ex);
mException = new TranscoderException(ex);
}
// ----
// get the 'width' and 'height' attributes of the SVG document
Dimension2D docSize = ctx.getDocumentSize();
if (docSize != null) {
mDefaultWidth = (float) docSize.getWidth();
mDefaultHeight = (float) docSize.getHeight();
}
else {
mDefaultWidth = 200;
mDefaultHeight = 200;
}
// Hack to work around exception above
if (root != null) {
mGVTRoot = root;
}
mDocument = svgDoc;
mURI = uri;
//ctx.dispose();
// Hack to avoid the transcode method wacking my context...
mContext = ctx;
ctx = null;
}
private BufferedImage readImage() throws TranscoderException {
init();
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(10f);
// Hacky workaround below...
if (mGVTRoot == null) {
// Try to reparse, if we had no URI last time...
if (mURI != mTranscoderInput.getURI()) {
try {
mContext.dispose();
mDocument.setURLObject(new URL(mTranscoderInput.getURI()));
transcode(mDocument, mTranscoderInput.getURI(), null);
}
catch (MalformedURLException ignore) {
// Ignored
}
}
if (mGVTRoot == null) {
throw mException;
}
}
ctx = mContext;
// /Hacky
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(20f);
// -- --
SVGSVGElement root = mDocument.getRootElement();
// ----
// ----
setImageSize(mDefaultWidth, mDefaultHeight);
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(40f);
// compute the preserveAspectRatio matrix
AffineTransform Px;
String ref = new ParsedURL(mURI).getRef();
try {
Px = ViewBox.getViewTransform(ref, root, width, height);
}
catch (BridgeException ex) {
throw new TranscoderException(ex);
}
if (Px.isIdentity() && (width != mDefaultWidth || height != mDefaultHeight)) {
// The document has no viewBox, we need to resize it by hand.
// we want to keep the document size ratio
float xscale, yscale;
xscale = width / mDefaultWidth;
yscale = height / mDefaultHeight;
float scale = Math.min(xscale, yscale);
Px = AffineTransform.getScaleInstance(scale, scale);
}
// take the AOI into account if any
if (hints.containsKey(KEY_AOI)) {
Rectangle2D aoi = (Rectangle2D) hints.get(KEY_AOI);
// transform the AOI into the image's coordinate system
aoi = Px.createTransformedShape(aoi).getBounds2D();
AffineTransform Mx = new AffineTransform();
double sx = width / aoi.getWidth();
double sy = height / aoi.getHeight();
Mx.scale(sx, sy);
double tx = -aoi.getX();
double ty = -aoi.getY();
Mx.translate(tx, ty);
// take the AOI transformation matrix into account
// we apply first the preserveAspectRatio matrix
Px.preConcatenate(Mx);
curAOI = aoi;
}
else {
curAOI = new Rectangle2D.Float(0, 0, width, height);
}
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(50f);
CanvasGraphicsNode cgn = getCanvasGraphicsNode(mGVTRoot);
if (cgn != null) {
cgn.setViewingTransform(Px);
curTxf = new AffineTransform();
}
else {
curTxf = Px;
}
try {
// dispatch an 'onload' event if needed
if (ctx.isDynamic()) {
BaseScriptingEnvironment se;
se = new BaseScriptingEnvironment(ctx);
se.loadScripts();
se.dispatchSVGLoadEvent();
}
}
catch (BridgeException ex) {
throw new TranscoderException(ex);
}
this.root = mGVTRoot;
// ----
// NOTE: The code below is copied and pasted from the Batik
// ImageTranscoder class' transcode() method:
// prepare the image to be painted
int w = (int) (width + 0.5);
int h = (int) (height + 0.5);
// paint the SVG document using the bridge package
// create the appropriate renderer
ImageRendererFactory rendFactory = new ConcreteImageRendererFactory();
// ImageRenderer renderer = rendFactory.createDynamicImageRenderer();
ImageRenderer renderer = rendFactory.createStaticImageRenderer();
renderer.updateOffScreen(w, h);
renderer.setTransform(curTxf);
renderer.setTree(this.root);
this.root = null; // We're done with it...
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(75f);
try {
// now we are sure that the aoi is the image size
Shape raoi = new Rectangle2D.Float(0, 0, width, height);
// Warning: the renderer's AOI must be in user space
renderer.repaint(curTxf.createInverse().
createTransformedShape(raoi));
// NOTE: repaint above cause nullpointer exception with fonts..???
BufferedImage rend = renderer.getOffScreen();
renderer = null; // We're done with it...
BufferedImage dest = createImage(w, h);
Graphics2D g2d = GraphicsUtil.createGraphics(dest);
try {
if (hints.containsKey(ImageTranscoder.KEY_BACKGROUND_COLOR)) {
Paint bgcolor = (Paint) hints.get(ImageTranscoder.KEY_BACKGROUND_COLOR);
g2d.setComposite(AlphaComposite.SrcOver);
g2d.setPaint(bgcolor);
g2d.fillRect(0, 0, w, h);
}
if (rend != null) { // might be null if the svg document is empty
g2d.drawRenderedImage(rend, new AffineTransform());
}
}
finally {
if (g2d != null) {
g2d.dispose();
}
}
if (abortRequested()) {
processReadAborted();
return null;
}
processImageProgress(99f);
return dest;
//writeImage(dest, output);
}
catch (Exception ex) {
throw new TranscoderException(ex.getMessage(), ex);
}
finally {
if (mContext != null) {
mContext.dispose();
}
}
}
private synchronized void init() throws TranscoderException {
if (!mInit) {
if (mTranscoderInput == null) {
throw new IllegalStateException("input == null");
}
mInit = true;
super.transcode(mTranscoderInput, null);
}
}
private BufferedImage getImage() throws TranscoderException {
if (mImage == null) {
mImage = readImage();
}
return mImage;
}
protected int getDefaultWidth() throws TranscoderException {
init();
return (int) (mDefaultWidth + 0.5);
}
protected int getDefaultHeight() throws TranscoderException {
init();
return (int) (mDefaultHeight + 0.5);
}
public void setInput(TranscoderInput pInput) {
mTranscoderInput = pInput;
}
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.svg;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.lang.SystemUtil;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
/**
* SVGImageReaderSpi
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: SVGImageReaderSpi.java,v 1.1 2003/12/02 16:45:00 haku Exp $
*/
public class SVGImageReaderSpi extends ImageReaderSpi {
private final static boolean SVG_READER_AVAILABLE = SystemUtil.isClassAvailable("com.twelvemonkeys.imageio.plugins.svg.SVGImageReader");
/**
* Creates an {@code SVGImageReaderSpi}.
*/
public SVGImageReaderSpi() {
this(IIOUtil.getProviderInfo(SVGImageReaderSpi.class));
}
private SVGImageReaderSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
SVG_READER_AVAILABLE ? new String[]{"svg", "SVG"} : new String[]{""}, // Names
SVG_READER_AVAILABLE ? new String[]{"svg"} : null, // Suffixes
SVG_READER_AVAILABLE ? new String[]{"image/svg", "image/x-svg", "image/svg+xml", "image/svg-xml"} : null, // Mime-types
"com.twelvemonkeys.imageio.plugins.svg.SVGImageReader", // Reader class name
ImageReaderSpi.STANDARD_INPUT_TYPE, // Output types
null, // Writer SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canDecodeInput(Object pSource) throws IOException {
return pSource instanceof ImageInputStream && SVG_READER_AVAILABLE && canDecode((ImageInputStream) pSource);
}
private static boolean canDecode(ImageInputStream pInput) throws IOException {
// NOTE: This test is quite quick as it does not involve any parsing,
// however it requires the doctype to be "svg", which may not be correct
// in all cases...
try {
pInput.mark();
// TODO: This is may not be ok for non-UTF/iso-latin encodings...
// TODO: Use an XML (encoding) aware Reader instance instead
// Need to figure out pretty fast if this is XML or not
int b;
while (Character.isWhitespace((char) (b = pInput.read()))) {
// Skip over leading WS
}
if (!((b == '<') && (pInput.read() == '?') && (pInput.read() == 'x') && (pInput.read() == 'm')
&& (pInput.read() == 'l'))) {
return false;
}
// Okay, we have XML. But, is it really SVG?
boolean docTypeFound = false;
while (!docTypeFound) {
while (pInput.read() != '<') {
// Skip over, until begin tag
}
// If this is not a comment, or the DOCTYPE declaration, the doc
// has no DOCTYPE and it can't be svg
if (pInput.read() != '!') {
return false;
}
// There might be comments before the doctype, unfortunately...
// If next is "--", this is a comment
if ((b = pInput.read()) == '-' && pInput.read() == '-') {
while (!(pInput.read() == '-' && pInput.read() == '-' && pInput.read() == '>')) {
// Skip until end of comment
}
}
// If we are lucky, this is DOCTYPE declaration
if (b == 'D' && pInput.read() == 'O' && pInput.read() == 'C'
&& pInput.read() == 'T' && pInput.read() == 'Y' && pInput.read() == 'P'
&& pInput.read() == 'E') {
docTypeFound = true;
while (Character.isWhitespace((char) (b = pInput.read()))) {
// Skip over WS
}
if (b == 's' && pInput.read() == 'v' && pInput.read() == 'g') {
//System.out.println("It's svg!");
return true;
}
}
}
return false;
}
finally {
pInput.reset();
}
}
public ImageReader createReaderInstance(Object extension) throws IOException {
return new SVGImageReader(this);
}
public String getDescription(Locale locale) {
return "Scaleable Vector Graphics (SVG) format image reader";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!SVG_READER_AVAILABLE) {
try {
// NOTE: This will break, but it gives us some useful debug info
new SVGImageReader(this);
}
catch (Throwable t) {
System.err.println("Could not instantiate SVGImageReader (missing support classes).");
t.printStackTrace();
}
IIOUtil.deregisterProvider(registry, this, category);
}
}}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.svg;
import javax.imageio.ImageReadParam;
import java.awt.*;
/**
* Implementation of {@code IamgeReadParam} for SVG images.
* SVG images allows for different source render sizes.
*
*/
public class SVGReadParam extends ImageReadParam {
private Paint mBackground;
private String mBaseURI;
public Paint getBackgroundColor() {
return mBackground;
}
public void setBackgroundColor(Paint pColor) {
mBackground = pColor;
}
public String getBaseURI() {
return mBaseURI;
}
public void setBaseURI(String pBaseURI) {
mBaseURI = pBaseURI;
}
@Override
public boolean canSetSourceRenderSize() {
return true;
}
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageReaderBase;
import org.apache.batik.ext.awt.image.codec.SeekableStream;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFDecodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* TIFFImageReader class description.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: TIFFImageReader.java,v 1.0 29.jul.2004 12:52:33 haku Exp $
*/
// TODO: Massive clean-up
// TODO: Support raster decoding...
public class TIFFImageReader extends ImageReaderBase {
private TIFFImageDecoder mDecoder = null;
private List<RenderedImage> mImages = new ArrayList<RenderedImage>();
protected TIFFImageReader(final ImageReaderSpi pOriginatingProvider) {
super(pOriginatingProvider);
}
protected void resetMembers() {
mDecoder = null;
}
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
// Decode image, convert and return as BufferedImage
RenderedImage image = readAsRenderedImage(pIndex, pParam);
return ImageUtil.toBuffered(image);
}
public RenderedImage readAsRenderedImage(int pIndex, ImageReadParam pParam) throws IOException {
init(pIndex);
processImageStarted(pIndex);
if (pParam == null) {
// Cache image for use by getWidth and getHeight methods
RenderedImage image;
if (mImages.size() > pIndex && mImages.get(pIndex) != null) {
image = mImages.get(pIndex);
}
else {
// Decode
image = mDecoder.decodeAsRenderedImage(pIndex);
// Make room
for (int i = mImages.size(); i < pIndex; i++) {
mImages.add(pIndex, null);
}
mImages.add(pIndex, image);
}
if (abortRequested()) {
processReadAborted();
return image;
}
processImageComplete();
return image;
}
else {
// TODO: Parameter conversion
mDecoder.setParam(new TIFFDecodeParam());
RenderedImage image = mDecoder.decodeAsRenderedImage(pIndex);
// Subsample and apply AOI
if (pParam.getSourceRegion() != null) {
image = fakeAOI(ImageUtil.toBuffered(image), pParam);
}
if (pParam.getSourceXSubsampling() > 1 || pParam.getSourceYSubsampling() > 1) {
image = ImageUtil.toBuffered(fakeSubsampling(ImageUtil.toBuffered(image), pParam));
}
processImageComplete();
return image;
}
}
private void init(int pIndex) throws IOException {
init();
checkBounds(pIndex);
}
protected void checkBounds(int pIndex) throws IOException {
if (pIndex < getMinIndex()){
throw new IndexOutOfBoundsException("index < minIndex");
}
else if (pIndex >= getNumImages(true)) {
throw new IndexOutOfBoundsException("index > numImages");
}
}
private synchronized void init() {
if (mDecoder == null) {
if (mImageInput == null) {
throw new IllegalStateException("input == null");
}
mDecoder = new TIFFImageDecoder(new SeekableStream() {
public int read() throws IOException {
return mImageInput.read();
}
public int read(final byte[] pBytes, final int pStart, final int pLength) throws IOException {
return mImageInput.read(pBytes, pStart, pLength);
}
public long getFilePointer() throws IOException {
return mImageInput.getStreamPosition();
}
public void seek(final long pPos) throws IOException {
mImageInput.seek(pPos);
}
}, null);
}
}
public int getWidth(int pIndex) throws IOException {
init(pIndex);
// TODO: Use cache...
return mDecoder.decodeAsRenderedImage(pIndex).getWidth();
}
public int getHeight(int pIndex) throws IOException {
init(pIndex);
// TODO: Use cache...
return mDecoder.decodeAsRenderedImage(pIndex).getHeight();
}
public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
throw new UnsupportedOperationException("Method getImageTypes not implemented");// TODO: Implement
}
public int getNumImages(boolean pAllowSearch) throws IOException {
init();
if (pAllowSearch) {
return mDecoder.getNumPages();
}
return -1;
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.lang.SystemUtil;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
/**
* TIFFImageReaderSpi
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: TIFFImageReaderSpi.java,v 1.1 2003/12/02 16:45:00 wmhakur Exp $
*/
public class TIFFImageReaderSpi extends ImageReaderSpi {
final static boolean TIFF_CLASSES_AVAILABLE = SystemUtil.isClassAvailable("com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader");
/**
* Creates a {@code TIFFImageReaderSpi}.
*/
public TIFFImageReaderSpi() {
this(IIOUtil.getProviderInfo(TIFFImageReaderSpi.class));
}
private TIFFImageReaderSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
TIFF_CLASSES_AVAILABLE ? new String[]{"tiff", "TIFF"} : new String[] {""}, // Names
TIFF_CLASSES_AVAILABLE ? new String[]{"tiff", "tif"} : null, // Suffixes
TIFF_CLASSES_AVAILABLE ? new String[]{"image/tiff", "image/x-tiff"} : null, // Mime-types
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader", // Writer class name..?
ImageReaderSpi.STANDARD_INPUT_TYPE, // Output types
new String[]{"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi"}, // Writer SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canDecodeInput(Object source) throws IOException {
return source instanceof ImageInputStream && TIFF_CLASSES_AVAILABLE && canDecode((ImageInputStream) source);
}
static boolean canDecode(ImageInputStream pInput) throws IOException {
try {
pInput.mark();
int byte0 = pInput.read(); // Byte order 1 (M or I)
int byte1 = pInput.read(); // Byte order 2 (always same as 1)
int byte2 = pInput.read(); // Version number 1 (M: 0, I: 42)
int byte3 = pInput.read(); // Version number 2 (M: 42, I: 0)
// Test for Motorola or Intel byte order, and version number == 42
if ((byte0 == 'M' && byte1 == 'M' && byte2 == 0 && byte3 == 42)
|| (byte0 == 'I' && byte1 == 'I' && byte2 == 42 && byte3 == 0)) {
return true;
}
}
finally {
pInput.reset();
}
return false;
}
public ImageReader createReaderInstance(Object extension) throws IOException {
return new TIFFImageReader(this);
}
public String getDescription(Locale locale) {
return "Tagged Image File Format (TIFF) image reader";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!TIFF_CLASSES_AVAILABLE) {
IIOUtil.deregisterProvider(registry, this, category);
}
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageWriterBase;
import com.twelvemonkeys.imageio.util.IIOUtil;
import org.apache.batik.ext.awt.image.codec.ImageEncodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFEncodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageEncoder;
import javax.imageio.IIOImage;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageWriterSpi;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
/**
* TIFFImageWriter class description.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: TIFFImageWriter.java,v 1.0 29.jul.2004 12:52:54 haku Exp $
*/
public class TIFFImageWriter extends ImageWriterBase {
private TIFFImageEncoder mEncoder = null;
protected TIFFImageWriter(final ImageWriterSpi pProvider) {
super(pProvider);
}
@Override
public void setOutput(final Object pOutput) {
mEncoder = null;
super.setOutput(pOutput);
}
public IIOMetadata getDefaultImageMetadata(final ImageTypeSpecifier imageType, final ImageWriteParam param) {
throw new UnsupportedOperationException("Method getDefaultImageMetadata not implemented");// TODO: Implement
}
public IIOMetadata convertImageMetadata(final IIOMetadata inData, final ImageTypeSpecifier imageType, final ImageWriteParam param) {
throw new UnsupportedOperationException("Method convertImageMetadata not implemented");// TODO: Implement
}
public void write(final IIOMetadata pStreamMetadata, final IIOImage pImage, final ImageWriteParam pParam) throws IOException {
RenderedImage renderedImage = pImage.getRenderedImage();
init();
ImageEncodeParam param;
if (pParam != null) {
param = new TIFFEncodeParam();
// TODO: Convert params
mEncoder.setParam(param);
}
BufferedImage image;
// FIX: TIFFEnocder chokes on a any of the TYPE_INT_* types...
// (The TIFFEncoder expects int types to have 1 sample of size 32
// while there actually is 4 samples of size 8, according to the
// SampleModel...)
if (renderedImage instanceof BufferedImage && (
((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_ARGB
|| ((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_ARGB_PRE)) {
image = ImageUtil.toBuffered(renderedImage, BufferedImage.TYPE_4BYTE_ABGR);
}
else if (renderedImage instanceof BufferedImage && (
((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_BGR
|| ((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_RGB)) {
image = ImageUtil.toBuffered(renderedImage, BufferedImage.TYPE_3BYTE_BGR);
}
else {
image = ImageUtil.toBuffered(renderedImage);
}
image = fakeAOI(image, pParam);
image = ImageUtil.toBuffered(fakeSubsampling(image, pParam));
/*
System.out.println("Image: " + pImage);
SampleModel sampleModel = pImage.getSampleModel();
System.out.println("SampleModel: " + sampleModel);
int sampleSize[] = sampleModel.getSampleSize();
System.out.println("Samples: " + sampleSize.length);
for (int i = 0; i < sampleSize.length; i++) {
System.out.println("SampleSize[" + i + "]: " + sampleSize[i]);
}
int dataType = sampleModel.getDataType();
System.out.println("DataType: " + dataType);
*/
processImageStarted(0);
mEncoder.encode(image);
mImageOutput.flush();
processImageComplete();
}
public void dispose() {
super.dispose();
mEncoder = null;
}
private synchronized void init() {
if (mEncoder == null) {
if (mImageOutput == null) {
throw new IllegalStateException("output == null");
}
mEncoder = new TIFFImageEncoder(IIOUtil.createStreamAdapter(mImageOutput), null);
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.spi.ServiceRegistry;
import java.io.IOException;
import java.util.Locale;
/**
* TIFFmageWriterSpi
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: TIFFImageWriterSpi.java,v 1.2 2004/01/14 15:21:44 wmhakur Exp $
*/
public class TIFFImageWriterSpi extends ImageWriterSpi {
/**
* Creates a {@code TIFFImageWriterSpi}.
*/
public TIFFImageWriterSpi() {
this(IIOUtil.getProviderInfo(TIFFImageWriterSpi.class));
}
private TIFFImageWriterSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
new String[]{"tiff", "TIFF"}, // Names
new String[]{"tif", "tiff"}, // Suffixes
new String[]{"image/tiff", "image/x-tiff"}, // Mime-types
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter", // Writer class name..?
STANDARD_OUTPUT_TYPE, // Output types
new String[]{"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi"}, // Reader SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canEncodeImage(ImageTypeSpecifier type) {
return true;
}
public ImageWriter createWriterInstance(Object extension) throws IOException {
try {
return new TIFFImageWriter(this);
}
catch (Throwable t) {
// Wrap in IOException if the writer can't be instantiated.
// This makes the IIORegistry deregister this service provider
IOException exception = new IOException(t.getMessage());
exception.initCause(t);
throw exception;
}
}
public String getDescription(Locale locale) {
return "Tagged Image File Format (TIFF) image writer";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!TIFFImageReaderSpi.TIFF_CLASSES_AVAILABLE) {
IIOUtil.deregisterProvider(registry, this, category);
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.wmf;
/**
* WMF
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: WMF.java,v 1.0 Feb 17, 2008 5:46:59 PM haraldk Exp$
*/
interface WMF {
static byte[] HEADER = new byte[] {
(byte) 0xd7, (byte) 0xcd, (byte) 0xc6, (byte) 0x9a, (byte) 0x00,
(byte) 0x00, //(byte) 0x7a, (byte) 0xf3, (byte) 0xa6, (byte) 0xfe,
//(byte) 0xf5, (byte) 0x06, (byte) 0x1c, (byte) 0x01, (byte) 0xe8,
//(byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
//(byte) 0xcc,
};
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.wmf;
import com.twelvemonkeys.imageio.ImageReaderBase;
import com.twelvemonkeys.imageio.plugins.svg.SVGImageReader;
import com.twelvemonkeys.imageio.plugins.svg.SVGReadParam;
import com.twelvemonkeys.imageio.util.IIOUtil;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
/**
* WMFImageReader class description.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: WMFImageReader.java,v 1.0 29.jul.2004 13:00:59 haku Exp $
*/
// TODO: Probably possible to do less wrapping/unwrapping of data...
// TODO: Consider using temp file instead of in-memory stream
public class WMFImageReader extends ImageReaderBase {
private SVGImageReader mReader = null;
public WMFImageReader(final ImageReaderSpi pProvider) {
super(pProvider);
}
protected void resetMembers() {
if (mReader != null) {
mReader.dispose();
}
mReader = null;
}
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
init();
processImageStarted(pIndex);
BufferedImage image = mReader.read(pIndex, pParam);
if (abortRequested()) {
processReadAborted();
return image;
}
processImageComplete();
return image;
}
private synchronized void init() throws IOException {
// Need the extra test, to avoid throwing an IOException from the Transcoder
if (mImageInput == null) {
throw new IllegalStateException("input == null");
}
if (mReader == null) {
WMFTranscoder transcoder = new WMFTranscoder();
ByteArrayOutputStream output = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(output, "UTF8");
try {
TranscoderInput in = new TranscoderInput(IIOUtil.createStreamAdapter(mImageInput));
TranscoderOutput out = new TranscoderOutput(writer);
// TODO: Transcodinghints?
transcoder.transcode(in, out);
}
catch (TranscoderException e) {
throw new IIOException(e.getMessage(), e);
}
mReader = new SVGImageReader(getOriginatingProvider());
mReader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(output.toByteArray())));
}
}
@Override
public ImageReadParam getDefaultReadParam() {
return new SVGReadParam();
}
public int getWidth(int pIndex) throws IOException {
init();
return mReader.getWidth(pIndex);
}
public int getHeight(int pIndex) throws IOException {
init();
return mReader.getHeight(pIndex);
}
public Iterator<ImageTypeSpecifier> getImageTypes(final int pImageIndex) throws IOException {
init();
return mReader.getImageTypes(pImageIndex);
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.wmf;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.lang.SystemUtil;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
/**
* WMFImageReaderSpi
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: WMFImageReaderSpi.java,v 1.1 2003/12/02 16:45:00 wmhakur Exp $
*/
public class WMFImageReaderSpi extends ImageReaderSpi {
// This is correct, as we rely on the SVG reader
private final static boolean WMF_READER_AVAILABLE = SystemUtil.isClassAvailable("com.twelvemonkeys.imageio.plugins.svg.SVGImageReader");
/**
* Creates a {@code WMFImageReaderSpi}.
*/
public WMFImageReaderSpi() {
this(IIOUtil.getProviderInfo(WMFImageReaderSpi.class));
}
private WMFImageReaderSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
WMF_READER_AVAILABLE ? new String[]{"wmf", "WMF"} : new String[]{""}, // Names
WMF_READER_AVAILABLE ? new String[]{"wmf", "emf"} : null, // Suffixes
WMF_READER_AVAILABLE ? new String[]{"application/x-msmetafile", "image/x-wmf"} : null, // Mime-types
WMFImageReader.class.getName(), // Reader class name..?
ImageReaderSpi.STANDARD_INPUT_TYPE, // Output types
null, // Writer SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canDecodeInput(Object source) throws IOException {
return source instanceof ImageInputStream && WMF_READER_AVAILABLE && canDecode((ImageInputStream) source);
}
public static boolean canDecode(ImageInputStream pInput) throws IOException {
if (pInput == null) {
throw new IllegalArgumentException("input == null");
}
try {
pInput.mark();
for (byte header : WMF.HEADER) {
int read = (byte) pInput.read();
if (header != read) {
// System.out.println("--> " + i + ": " + read + " (expected " + header + ")");
return false;
}
}
return true;
}
finally {
pInput.reset();
}
}
public ImageReader createReaderInstance(Object extension) throws IOException {
return new WMFImageReader(this);
}
public String getDescription(Locale locale) {
return "Windows Meta File (WMF) image reader";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!WMF_READER_AVAILABLE) {
IIOUtil.deregisterProvider(registry, this, category);
}
}
}

View File

@@ -0,0 +1,3 @@
com.twelvemonkeys.imageio.plugins.svg.SVGImageReaderSpi
com.twelvemonkeys.imageio.plugins.wmf.WMFImageReaderSpi
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi

View File

@@ -0,0 +1 @@
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.svg;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
/**
* SVGImageReaderTestCase
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: SVGImageReaderTestCase.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
*/
public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase<SVGImageReader> {
private SVGImageReaderSpi mSVGImageReaderSpi = new SVGImageReaderSpi();
protected List<TestData> getTestData() {
return Arrays.asList(
new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500))
);
}
protected ImageReaderSpi createProvider() {
return mSVGImageReaderSpi;
}
@Override
protected SVGImageReader createReader() {
return new SVGImageReader(createProvider());
}
protected Class<SVGImageReader> getReaderClass() {
return SVGImageReader.class;
}
protected List<String> getFormatNames() {
return Arrays.asList("svg");
}
protected List<String> getSuffixes() {
return Arrays.asList("svg");
}
protected List<String> getMIMETypes() {
return Arrays.asList("image/svg+xml");
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2008, Harald Kuhr
* 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 "TwelveMonkeys" 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.
*/
package com.twelvemonkeys.imageio.plugins.wmf;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
/**
* SVGImageReaderTestCase
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: SVGImageReaderTestCase.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
*/
public class WMFImageReaderTestCase extends ImageReaderAbstractTestCase<WMFImageReader> {
private WMFImageReaderSpi mSVGImageReaderSpi = new WMFImageReaderSpi();
protected List<TestData> getTestData() {
return Arrays.asList(
// TODO: Dimensions does not look right...
new TestData(getClassLoaderResource("/wmf/test.wmf"), new Dimension(841, 673))
);
}
protected ImageReaderSpi createProvider() {
return mSVGImageReaderSpi;
}
@Override
protected WMFImageReader createReader() {
return new WMFImageReader(createProvider());
}
protected Class<WMFImageReader> getReaderClass() {
return WMFImageReader.class;
}
protected List<String> getFormatNames() {
return Arrays.asList("wmf");
}
protected List<String> getSuffixes() {
return Arrays.asList("wmf", "emf");
}
protected List<String> getMIMETypes() {
return Arrays.asList("image/x-wmf", "application/x-msmetafile");
}
}

View File

@@ -0,0 +1,218 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!--
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. 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.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Batik" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, 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 software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
-->
<!-- ====================================================================== -->
<!-- Defines the Batik Logo using an SVG font. -->
<!-- -->
<!-- @author vhardy@apache.org -->
<!-- @author thomas.deweese@kodak.com -->
<!-- @author bella.robinson@cmis.csiro.au -->
<!-- @version $Id: batikLogo.svg,v 1.13 2003/08/08 11:39:29 vhardy Exp $ -->
<!-- ====================================================================== -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" viewBox="0 0 450 500">
<title>Batik Logo</title>
<g id="content">
<defs>
<symbol id="Batik_Squiggle" stroke="none" viewBox="0 0 540 570">
<path id="Batik_Squiggle_Blue" fill="#6666FF"
d="M172,44C137,60,31,135,11,199c-8,27,22,48,44,33
C14,306-1,332,0,356c0,14,13,42,44,27c8-4,35-25,52-41
c14-1,24-11,42-28c17,14,36,10,52-7c22,2,82-78,44-108
c-3-24-30-37-53-18c-6-2-13-1-18,1c22-35,43-82,49-105
C219,47,188,36,172,44z"/>
<path id="Batik_Squiggle_Red" fill="#FF0000"
d="M400,0c-18,3-49,31-49,31c-29,23-43,58-28,95
c-13,14-29,44-29,67c0,28,20,52,50,29c7,8,21,16,37,5
c-5,29,3,48,26,49c1,10,13,31,36,17c16-10,58-39,79-56
c25-23,25-94-18-89c33-59-3-96-27-84c-10,4-46,25-52,30
c-1-7-5-12-11-14C436,45,436-5,401,0z"/>
<path id="Batik_Squiggle_Green" fill="#33CC33"
d="M275,353c-46,12-88,43-114,91c-9,16,6,37,25,33
c-14,24-40,67-15,81c28,16,52-8,60-15c18,21,50,10,81-17
c41,14,68-2,103-53c8-12,30-43,30-65c0-16-15-30-35-21
c-1-12-9-38-53-19c-10-6-31-5-54,17
C308,375,300,347,275,353z"/>
</symbol>
<!-- ============================= -->
<!-- Batik SVG Font Definition -->
<!-- ============================= -->
<font horiz-adv-x="150" id="Batik">
<font-face
font-family="Batik SVGFont"
units-per-em="240"
ascent="190"
descent="50"
alphabetic="0"/>
<missing-glyph horiz-adv-x="150" d="M20 0 V240 H100 V0 z"/>
<glyph unicode=" " glyph-name=" " horiz-adv-x="100"/>
<glyph id="B" unicode="B" glyph-name="B" horiz-adv-x="130">
<g transform="scale(1,-1)translate(0,-170)">
<path d="M21.244,141.963V40.831c0-6.188-0.57-10.773-1.707-13.754c-1.137-2.977-3.066-5.461-5.793-7.449c-1.137-0.766-2.367-1.395-3.695-1.891s-3.012-0.938-5.055-1.32c-2.125-0.371-3.488-0.781-4.094-1.23s-0.906-1.121-0.906-2.02
c0-1.195,0.32-2.035,0.969-2.52c0.645-0.484,1.953-0.73,3.93-0.73c0.758,0,3.816,0.211,9.176,0.625c5.355,0.418,10.387,0.625,15.098,0.625c2.961,0,7.883-0.207,14.758-0.625c6.875-0.414,12.324-0.625,16.352-0.625c16.711,0,29.762,3.461,39.145,10.379
s14.074,16.574,14.074,28.965c0,7.148-1.793,13.418-5.375,18.816c-3.586,5.398-9,9.996-16.242,13.797v2.18c11.574,2.051,20.445,6.547,26.613,13.492s9.254,15.879,9.254,26.805c0,15.406-5.184,27.645-15.551,36.715s-24.473,13.602-42.316,13.602
c-6.078,0-13.367-0.293-21.871-0.875c-8.508-0.586-13.898-0.875-16.172-0.875c-6.762,0-13.863,0.348-21.301,1.043c-1.824,0.137-2.965,0.207-3.418,0.207c-0.609,0-1.199-0.344-1.77-1.027s-0.852-1.406-0.852-2.172c0-1.598,1.355-2.93,4.074-3.996l0.113-0.055
c1.809-0.836,3.223-1.574,4.242-2.223c1.02-0.645,1.906-1.387,2.66-2.223c2.039-2.047,3.492-4.516,4.359-7.402s1.301-7.254,1.301-13.105z M39.244,73.209c0,3.648,0.453,5.93,1.367,6.84c0.914,0.914,2.816,1.367,5.711,1.367h16.555
c12.023,0,20.758-2.031,26.203-6.098c5.441-4.066,8.164-10.508,8.164-19.324c0-10.945-4.188-20.027-12.559-27.246c-8.375-7.219-18.914-10.832-31.625-10.832c-5.711,0-9.441,0.855-11.191,2.566s-2.625,5.148-2.625,10.316v42.41z M39.244,150.737
c0,6.539,1.789,10.953,5.371,13.242c3.578,2.293,11.16,3.438,22.746,3.438c14.172,0,24.82-3.031,31.945-9.094s10.688-15.156,10.688-27.281c0-13.031-4.234-23.188-12.695-30.461s-20.316-10.914-35.563-10.914H47.463c-3.578,0-5.84,0.477-6.793,1.426
s-1.426,3.285-1.426,7.004v52.641z"/>
<!-- Put the Squiggle in the B -->
<use xlink:href="#Batik_Squiggle" width="54" height="57"
transform="translate(45,103)" />
</g>
</glyph>
<glyph id="a" unicode="a" glyph-name="a" horiz-adv-x="105">
<path transform="scale(1,-1)translate(-125, -170)"
d="M194.825,161.952c-5.238,4.766-10.891,8.285-16.961,10.559c-6.07,2.27-12.863,3.406-20.375,3.406c-7.363,0-12.98-1.922-16.848-5.762c-3.871-3.844-5.805-9.414-5.805-16.719c0-9.359,4.266-16.758,12.805-22.195
c8.535-5.438,23.766-10.215,45.695-14.324v-15.789c0-7.09-2.16-12.523-6.477-16.297s-10.523-5.664-18.625-5.664c-6.891,0-11.758,0.992-14.598,2.977s-4.258,5.336-4.258,10.063c0,1.984,0.281,4.27,0.852,6.863s0.855,4.156,0.855,4.688
c0,1.07-0.516,1.945-1.547,2.633s-2.352,1.027-3.953,1.027c-3.055,0-5.652-0.816-7.793-2.449s-3.207-3.664-3.207-6.098c0-6.605,3.664-12.625,11-18.055c7.332-5.43,15.977-8.148,25.93-8.148c13.906,0,23.727,2.621,29.465,7.855
c5.734,5.238,8.605,14.535,8.605,27.891v42.844c0,6.516,0.621,10.715,1.867,12.594s3.609,2.816,7.086,2.816c0.602,0,1.434-0.035,2.492-0.113c1.055-0.078,1.773-0.117,2.152-0.117c0.527,0,1.02,0.246,1.473,0.73c0.453,0.488,0.68,1.07,0.68,1.742
c0,1.574-1.273,2.887-3.816,3.934s-5.785,1.574-9.73,1.574c-4.176,0-7.668-1.039-10.477-3.117s-4.973-5.191-6.488-9.348z M193.037,122.167c-16.43,3.43-27.789,7.273-34.074,11.535c-6.285,4.266-9.426,9.973-9.426,17.129c0,5.559,1.512,9.879,4.543,12.961
c3.027,3.086,7.27,4.625,12.723,4.625c7.492,0,13.738-1.941,18.738-5.832c4.996-3.887,7.496-8.813,7.496-14.777v-25.641z"/>
</glyph>
<glyph id="ti" unicode="ti" glyph-name="ti" horiz-adv-x="100">
<g style="fill:#FF0000;" transform="scale(1,-1)translate(-215,-170)">
<path d="M311.259,168.69c-0.684-0.531-2.199-0.871-4.551-1.023c-1.441,0-2.711-0.113-3.813-0.34s-2.105-0.57-3.012-1.027c-3.035-1.594-5.102-3.586-6.203-5.98c-1.102-2.391-1.648-6.625-1.648-12.703v-35.543c0-11.688,0.188-23.227,0.566-34.617
c0.078-2.047,0.117-3.227,0.117-3.531c0-1.594-0.191-2.617-0.57-3.074c-0.383-0.453-1.066-0.684-2.059-0.684c-1.066,0-9.44,3.681-11.451,4.196s-6.655,1.804-11.209,1.804h-20.266V55.045c0-1.148-0.117-1.918-0.344-2.301s-0.684-0.578-1.363-0.578
c-1.219,0-3.059,2.172-5.527,6.516s-4.727,7.617-6.777,9.824c-2.887,3.199-5.98,6.246-9.285,9.141s-4.953,4.609-4.953,5.141c0,0.609,0.375,1.203,1.129,1.773s1.434,0.855,2.035,0.855h8.586v59.84c0,11.266,2.051,19.273,6.16,24.027
c4.105,4.754,10.875,7.133,20.305,7.133c5.724,0,11.038-1.066,15.948-3.17c4.26-0.381,8.633-0.58,13.126-0.58c4.328,0,8.957,0.211,13.895,0.625c4.934,0.414,7.668,0.625,8.199,0.625c1.141,0,2.09-0.266,2.848-0.793c0.758-0.531,1.141-1.176,1.141-1.934
c0-1.137-0.344-1.969-1.023-2.5z M251.317,163.288c-2.773-2.922-4.156-7.227-4.156-12.914v-64.957c0,0,12.812,0.543,13.215,0.57c1.194,0.081,2.965,0.184,5.164,0.184c3.867,0,6.23,1.637,7.637,3.914c1.402,2.281,2.105,7.367,2.105,15.266v42.039
c0,4.781-0.285,8.273-0.848,10.477c-0.566,2.203-1.563,4.211-2.992,6.031c-0.758,0.836-1.961,1.863-3.617,3.074c-0.292,0.169-0.532,0.312-0.731,0.434c-1.229,0.172-2.446,0.261-3.651,0.261c-5.313,0-9.355-1.457-12.125-4.379z"/>
<path d="M284.067,48.667c1.969,0,4.207-1.535,6.711-4.605c2.5-3.07,3.754-5.555,3.754-7.453c0-1.969-1.309-4.453-3.926-7.449c-2.617-2.992-4.648-4.492-6.086-4.492c-1.594,0-3.695,1.555-6.313,4.664s-3.926,5.766-3.926,7.961c0,2.352,1.137,4.836,3.41,7.453s4.398,3.922,6.375,3.922z"/>
</g>
</glyph>
<glyph id="k" unicode="k" glyph-name="k" horiz-adv-x="120">
<path transform="scale(1,-1)translate(-310, -170)"
d="M331.507,147.307V35.413c0-8.078-0.68-13.219-2.031-15.43s-3.906-3.316-7.664-3.316h-1.805c-1.387,0-2.465-0.242-3.23-0.734c-0.77-0.492-1.191-1.188-1.27-2.094c0-1.656,1.977-2.941,5.93-3.848l0.23-0.074
c1.824-0.301,3.516-0.68,5.074-1.133s3.098-0.984,4.617-1.594c2.66-1.059,5.586-2.535,8.781-4.43c3.191-1.895,5.246-2.844,6.16-2.844c0.984,0,1.746,0.383,2.277,1.141s0.801,1.859,0.801,3.301c0,0.305-0.039,1.082-0.113,2.332
c-0.078,1.254-0.113,2.375-0.113,3.359c-0.383,5.391-0.668,10.684-0.859,15.883s-0.285,10.531-0.285,15.996v80.641l33.148-30.207c1.434-1.367,2.566-2.715,3.398-4.047c0.832-1.328,1.25-2.527,1.25-3.594c0-1.289-1.324-2.316-3.969-3.078
c-0.305-0.074-0.566-0.148-0.793-0.227c-1.891-0.375-3.215-0.828-3.969-1.359c-0.758-0.527-1.133-1.242-1.133-2.148c0-0.68,0.453-1.262,1.359-1.754s2.004-0.738,3.289-0.738c0.301,0,2.305,0.211,6.008,0.625c3.703,0.418,7.297,0.625,10.773,0.625
c2.871,0,6.141-0.207,9.809-0.625c3.664-0.414,5.875-0.625,6.633-0.625c1.438,0,2.496,0.227,3.176,0.68s1.02,1.133,1.02,2.039c0,1.734-1.285,2.828-3.855,3.281h-0.113c-1.133,0.152-2.27,0.379-3.402,0.684s-2.305,0.723-3.516,1.254
c-7.332,2.891-13.758,7.07-19.273,12.543c-0.605,0.684-1.059,1.141-1.359,1.367l-19.73,17.781c10.66,14.914,19.223,26.215,25.688,33.902s11.59,12.672,15.371,14.953c3.023,1.75,6.879,2.969,11.566,3.652c0.375,0.078,0.641,0.113,0.793,0.113
c2.191,0.152,3.609,0.438,4.254,0.852c0.641,0.414,1,1.113,1.078,2.094c0,1.133-0.512,1.922-1.535,2.375s-3.012,0.68-5.965,0.68h-19.277c-5,0-15.23-10.113-30.684-30.34c-5.609-7.375-10.117-13.227-13.523-17.563l-6.516,6.156v15.617
c0,6.852,0.531,11.344,1.602,13.477c1.066,2.133,3.086,3.883,6.059,5.25c1.219,0.535,3.121,0.992,5.715,1.371c0.078,0.023,0.152,0.031,0.23,0.031c2.133,0.152,3.523,0.492,4.172,1.023s0.973,1.363,0.973,2.5c0,0.836-0.344,1.496-1.027,1.988
s-1.594,0.738-2.734,0.738c-0.305,0-2.758-0.211-7.355-0.625c-4.602-0.414-8.992-0.625-13.172-0.625c-6.309,0-12.313,0.375-18.016,1.125c-0.914,0.082-1.445,0.125-1.594,0.125c-0.836,0-1.523-0.25-2.055-0.746s-0.797-1.09-0.797-1.777
c0-0.766,0.262-1.473,0.789-2.121c0.523-0.648,1.613-1.434,3.27-2.355c0.375-0.227,0.789-0.492,1.242-0.797c1.273-0.758,2.215-1.445,2.816-2.055c1.277-1.367,2.16-3.074,2.648-5.129c0.488-2.051,0.734-5.926,0.734-11.629z"/>
</glyph>
<glyph unicode="*" glyph-name="*" horiz-adv-x="120">
<g transform="scale(1, -1)">
<use xlink:href="#Batik_Squiggle" width="108" height="114"
transform="translate(0,-130)" />
</g>
</glyph>
<hkern g1="B" g2="a" k="5"/>
<hkern g1="a" g2="t" k="14"/>
<hkern g1="a" g2="ti" k="14"/>
<hkern g1="i" g2="k" k="6"/>
<hkern g1="ti" g2="k" k="6"/>
</font>
<g id="Batik_Logo_Underline" transform="scale(.75,.75)" >
<path d="M37.886,60c-0.018,0.1-0.377,1.375-0.439,1.492c-0.15,0.285-1.382,2.046-1.598,2.291c0.206-0.233,0.428-0.452,0.65-0.67c-6.851,6.751-0.262,0.713,0.893-0.499c1.893-1.986-2.124,1.712,0.112-0.08
c0.604-0.484,1.242-0.925,1.886-1.355c-2.574,1.719,0.458-0.228,1.417-0.868c-2.634,1.761-1.231,0.788-0.605,0.423c1.799-1.049,3.686-1.946,5.591-2.783c0.978-0.43,1.97-0.828,2.964-1.217c1.844-0.723-1.918,0.683-0.003,0.012
c0.706-0.264,1.412-0.528,2.117-0.792c-1.224,0.456-1.388,0.521-0.491,0.195c2.531-0.908,5.102-1.708,7.683-2.461c5.73-1.672,11.556-3.013,17.401-4.216c30.689-6.315,61.555-8.765,92.723-10.467c35.225-1.924,70.559-2.313,105.819-1.278
c27.375,0.803,55.137,2.029,82.154,6.813c1.854,0.328,3.702,0.69,5.545,1.079c-2.182-0.459,0.632,0.149,1.102,0.26c0.785,0.185,1.566,0.383,2.347,0.585c2.714,0.705,5.407,1.537,7.987,2.642c0.676-4.98,1.351-9.959,2.026-14.939
c-29.001,20.428-70.184,18.783-104.484,20.881c-37.85,2.314-78.422,7.341-105.371,37.024c-3.142,3.46-5.693,10.35-0.21,12.998c8.018,3.873,16.683,5.137,25.266,7.166c7.149,1.69,13.362,4.381,16.934,11.121c4.934,9.311,2.75,18.519-0.175,28.003
c-3.217,10.428-5.508,20.886-0.692,31.219c4.219,9.05,19.441-3.641,15.823-11.611c-4.234-9.326,1.407-19.828,3.653-28.997c2.667-10.888,1.908-22.401-3.872-32.224c-9.76-16.588-31.066-13.848-46.449-21.271c-0.07,4.333-0.14,8.666-0.21,12.998
c10.537-11.719,25.017-18.668,40.974-22.714c18.159-4.604,37.034-5.719,55.666-6.747c37.146-2.049,77.822-2.405,109.506-24.634c4.136-2.902,8.771-12.048,2.026-14.939c-7.868-3.373-16.687-4.781-25.083-6.132c-12.447-2.004-25.032-3.156-37.6-4.075
c-33.215-2.427-66.599-2.839-99.887-2.247c-34.872,0.621-69.791,2.496-104.432,6.637c-24.317,2.907-50.972,6.112-73.187,17.171c-4.951,2.465-9.505,5.587-13.309,9.623c-1.027,1.089-2.19,2.464-2.986,3.643c0.137-0.203-3.419,6.639-1.518,3.165
c-0.205,0.374-0.38,0.762-0.549,1.151c-1.126,2.59-2.056,5.322-2.196,8.168c-0.222,4.484,4.48,3.091,6.917,1.551c3.856-2.437,7.345-6.516,8.167-11.093z"/>
</g> <!-- End Batik_Logo_Underline -->
<filter id="dropShadow" filterUnits="objectBoundingBox"
filterRes="200" width="1.4" height="1.4">
<feGaussianBlur in="SourceAlpha" stdDeviation="4" />
<feOffset dx="8" dy="8" />
<feComponentTransfer result="shadow">
<feFuncA type="linear" slope=".5" intercept="0" />
</feComponentTransfer>
<feComposite in2="shadow" in="SourceGraphic"/>
</filter>
<g id="Batik_Logo_Shadow" filter="url(#dropShadow)">
<g id="Batik_Logo">
<text id="text" x="0" y="0" font-family="Batik SVGFont"
font-size="180">Batik</text>
<use xlink:href="#Batik_Logo_Underline"/>
</g> <!-- End Batik_Logo -->
</g> <!-- End Batik_Logo_Shadow -->
<g id="Batik_Tag_Box" >
<rect x="1" y="1" width="446" height="496"
style="fill:none; stroke:black" />
<use xlink:href="#Batik_Squiggle" width="27" height="28"
transform="translate(418,467)" />
</g> <!-- End Batik_Tag_Box -->
</defs>
<use x="65" y="233" xlink:href="#Batik_Logo_Shadow" />
</g>
<!-- ============================================================= -->
<!-- Batik sample mark -->
<!-- ============================================================= -->
<use xlink:href="#Batik_Tag_Box" />
</svg>

Binary file not shown.