mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-04 11:26:44 -04:00
It all works
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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,
|
||||
};
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,3 @@
|
||||
com.twelvemonkeys.imageio.plugins.svg.SVGImageReaderSpi
|
||||
com.twelvemonkeys.imageio.plugins.wmf.WMFImageReaderSpi
|
||||
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi
|
@@ -0,0 +1 @@
|
||||
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi
|
@@ -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");
|
||||
}
|
||||
}
|
@@ -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");
|
||||
}
|
||||
}
|
218
imageio/imageio-batik/src/test/resources/svg/batikLogo.svg
Executable file
218
imageio/imageio-batik/src/test/resources/svg/batikLogo.svg
Executable 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>
|
BIN
imageio/imageio-batik/src/test/resources/wmf/test.wmf
Executable file
BIN
imageio/imageio-batik/src/test/resources/wmf/test.wmf
Executable file
Binary file not shown.
Reference in New Issue
Block a user