TMI-125: Clean up after merge + fix Spi issue.

This commit is contained in:
Harald Kuhr 2015-04-07 11:05:14 +02:00
parent 4219ca437c
commit 2c8f0f5add
3 changed files with 93 additions and 88 deletions

View File

@ -74,18 +74,19 @@ import java.util.Map;
* @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 rasterizer = null;
private Rasterizer rasterizer;
/**
* Creates an {@code SVGImageReader}.
*
* @param pProvider the provider
*/
public SVGImageReader(ImageReaderSpi pProvider) {
public SVGImageReader(final ImageReaderSpi pProvider) {
super(pProvider);
}
protected void resetMembers() {
rasterizer = new Rasterizer();
}
@Override
@ -100,7 +101,6 @@ public class SVGImageReader extends ImageReaderBase {
if (imageInput != null) {
TranscoderInput input = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput));
rasterizer = new Rasterizer();
rasterizer.setInput(input);
}
}
@ -135,7 +135,7 @@ public class SVGImageReader extends ImageReaderBase {
try {
processImageStarted(pIndex);
rasterizer.mTranscoderInput.setURI(baseURI);
rasterizer.transcoderInput.setURI(baseURI);
BufferedImage image = rasterizer.getImage();
Graphics2D g = destination.createGraphics();
@ -253,31 +253,29 @@ public class SVGImageReader extends ImageReaderBase {
*/
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;
BufferedImage image = null;
private TranscoderInput transcoderInput;
private float defaultWidth;
private float defaultHeight;
private boolean initialized = false;
private SVGOMDocument document;
private String uri;
private GraphicsNode gvtRoot;
private TranscoderException exception;
private BridgeContext context;
public BufferedImage createImage(int w, int h) {
return ImageUtil.createTransparent(w, h);//, BufferedImage.TYPE_INT_ARGB);
public BufferedImage createImage(final int width, final int height) {
return ImageUtil.createTransparent(width, height);//, 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 {
protected void transcode(Document document, final String uri, final 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();
if ((document != null) && !(document.getImplementation() instanceof SVGDOMImplementation)) {
DOMImplementation impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION);
document = DOMUtilities.deepCloneDocument(document, impl);
if (uri != null) {
try {
URL url = new URL(uri);
@ -290,7 +288,6 @@ public class SVGImageReader extends ImageReaderBase {
ctx = createBridgeContext();
SVGOMDocument svgDoc = (SVGOMDocument) document;
//SVGSVGElement root = svgDoc.getRootElement();
// build the GVT tree
builder = new GVTBuilder();
@ -298,7 +295,7 @@ public class SVGImageReader extends ImageReaderBase {
boolean isDynamic =
(hints.containsKey(KEY_EXECUTE_ONLOAD) &&
(Boolean) hints.get(KEY_EXECUTE_ONLOAD) &&
BaseScriptingEnvironment.isDynamicDocument(ctx, svgDoc));
BaseScriptingEnvironment.isDynamicDocument(ctx, svgDoc));
if (isDynamic) {
ctx.setDynamicState(BridgeContext.DYNAMIC);
@ -312,8 +309,7 @@ public class SVGImageReader extends ImageReaderBase {
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);
exception = new TranscoderException(ex);
}
// ----
@ -321,24 +317,23 @@ public class SVGImageReader extends ImageReaderBase {
// 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();
defaultWidth = (float) docSize.getWidth();
defaultHeight = (float) docSize.getHeight();
}
else {
mDefaultWidth = 200;
mDefaultHeight = 200;
defaultWidth = 200;
defaultHeight = 200;
}
// Hack to work around exception above
if (root != null) {
mGVTRoot = root;
gvtRoot = root;
}
mDocument = svgDoc;
mURI = uri;
this.document = svgDoc;
this.uri = uri;
//ctx.dispose();
// Hack to avoid the transcode method wacking my context...
mContext = ctx;
context = ctx;
ctx = null;
}
@ -353,24 +348,24 @@ public class SVGImageReader extends ImageReaderBase {
// Hacky workaround below...
if (mGVTRoot == null) {
if (gvtRoot == null) {
// Try to reparse, if we had no URI last time...
if (mURI != mTranscoderInput.getURI()) {
if (uri != transcoderInput.getURI()) {
try {
mContext.dispose();
mDocument.setURLObject(new URL(mTranscoderInput.getURI()));
transcode(mDocument, mTranscoderInput.getURI(), null);
context.dispose();
document.setURLObject(new URL(transcoderInput.getURI()));
transcode(document, transcoderInput.getURI(), null);
}
catch (MalformedURLException ignore) {
// Ignored
}
}
if (mGVTRoot == null) {
throw mException;
if (gvtRoot == null) {
throw exception;
}
}
ctx = mContext;
ctx = context;
// /Hacky
if (abortRequested()) {
processReadAborted();
@ -378,13 +373,13 @@ public class SVGImageReader extends ImageReaderBase {
}
processImageProgress(20f);
// -- --
SVGSVGElement root = mDocument.getRootElement();
// ----
SVGSVGElement root = document.getRootElement();
// ----
// ----
setImageSize(mDefaultWidth, mDefaultHeight);
setImageSize(defaultWidth, defaultHeight);
if (abortRequested()) {
processReadAborted();
@ -394,7 +389,7 @@ public class SVGImageReader extends ImageReaderBase {
// compute the preserveAspectRatio matrix
AffineTransform Px;
String ref = new ParsedURL(mURI).getRef();
String ref = new ParsedURL(uri).getRef();
try {
Px = ViewBox.getViewTransform(ref, root, width, height);
@ -404,12 +399,12 @@ public class SVGImageReader extends ImageReaderBase {
throw new TranscoderException(ex);
}
if (Px.isIdentity() && (width != mDefaultWidth || height != mDefaultHeight)) {
if (Px.isIdentity() && (width != defaultWidth || height != defaultHeight)) {
// 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;
xscale = width / defaultWidth;
yscale = height / defaultHeight;
float scale = Math.min(xscale, yscale);
Px = AffineTransform.getScaleInstance(scale, scale);
}
@ -440,7 +435,7 @@ public class SVGImageReader extends ImageReaderBase {
}
processImageProgress(50f);
CanvasGraphicsNode cgn = getCanvasGraphicsNode(mGVTRoot);
CanvasGraphicsNode cgn = getCanvasGraphicsNode(gvtRoot);
if (cgn != null) {
cgn.setViewingTransform(Px);
curTxf = new AffineTransform();
@ -462,7 +457,7 @@ public class SVGImageReader extends ImageReaderBase {
throw new TranscoderException(ex);
}
this.root = mGVTRoot;
this.root = gvtRoot;
// ----
// NOTE: The code below is copied and pasted from the Batik
@ -510,6 +505,7 @@ public class SVGImageReader extends ImageReaderBase {
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());
}
@ -534,43 +530,44 @@ public class SVGImageReader extends ImageReaderBase {
throw exception;
}
finally {
if (mContext != null) {
mContext.dispose();
if (context != null) {
context.dispose();
}
}
}
private synchronized void init() throws TranscoderException {
if (!mInit) {
if (mTranscoderInput == null) {
if (!initialized) {
if (transcoderInput == null) {
throw new IllegalStateException("input == null");
}
mInit = true;
initialized = true;
super.transcode(mTranscoderInput, null);
super.transcode(transcoderInput, null);
}
}
private BufferedImage getImage() throws TranscoderException {
if (mImage == null) {
mImage = readImage();
if (image == null) {
image = readImage();
}
return mImage;
return image;
}
protected int getDefaultWidth() throws TranscoderException {
init();
return (int) (mDefaultWidth + 0.5);
return (int) (defaultWidth + 0.5);
}
protected int getDefaultHeight() throws TranscoderException {
init();
return (int) (mDefaultHeight + 0.5);
return (int) (defaultHeight + 0.5);
}
public void setInput(TranscoderInput pInput) {
mTranscoderInput = pInput;
public void setInput(final TranscoderInput pInput) {
transcoderInput = pInput;
}
}
}

View File

@ -29,8 +29,8 @@
package com.twelvemonkeys.imageio.plugins.svg;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.lang.SystemUtil;
import com.twelvemonkeys.imageio.util.IIOUtil;
import com.twelvemonkeys.lang.SystemUtil;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
@ -80,18 +80,18 @@ public class SVGImageReaderSpi extends ImageReaderSpi {
);
}
public boolean canDecodeInput(Object pSource) throws IOException {
public boolean canDecodeInput(final Object pSource) throws IOException {
return pSource instanceof ImageInputStream && SVG_READER_AVAILABLE && canDecode((ImageInputStream) pSource);
}
private static boolean canDecode(ImageInputStream pInput) throws IOException {
private static boolean canDecode(final 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: This is not ok for UTF-16 and other wide encodings
// TODO: Use an XML (encoding) aware Reader instance instead
// Need to figure out pretty fast if this is XML or not
int b;
@ -111,9 +111,14 @@ public class SVGImageReaderSpi extends ImageReaderSpi {
// 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() != '!') {
if ((b = pInput.read()) != '!') {
if (b == 's' && pInput.read() == 'v' && pInput.read() == 'g'
&& (Character.isWhitespace((char) (b = pInput.read())) || b == ':')) {
// TODO: Support svg with prefix + recognize namespace (http://www.w3.org/2000/svg)!
return true;
}
// If this is not a comment, or the DOCTYPE declaration, the doc has no DOCTYPE and it can't be svg
return false;
}
@ -126,19 +131,19 @@ public class SVGImageReaderSpi extends ImageReaderSpi {
}
// 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') {
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 {
@ -147,17 +152,17 @@ public class SVGImageReaderSpi extends ImageReaderSpi {
}
public ImageReader createReaderInstance(Object extension) throws IOException {
public ImageReader createReaderInstance(final Object extension) throws IOException {
return new SVGImageReader(this);
}
public String getDescription(Locale locale) {
public String getDescription(final Locale locale) {
return "Scaleable Vector Graphics (SVG) format image reader";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
public void onRegistration(final ServiceRegistry registry, final Class<?> category) {
if (!SVG_READER_AVAILABLE) {
try {
// NOTE: This will break, but it gives us some useful debug info

View File

@ -31,7 +31,6 @@ package com.twelvemonkeys.imageio.plugins.svg;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
@ -43,6 +42,8 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* SVGImageReaderTestCase
*
@ -55,7 +56,9 @@ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase<SVGImage
protected List<TestData> getTestData() {
return Arrays.asList(
new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500))
new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500)),
new TestData(getClassLoaderResource("/svg/red-square.svg"), new Dimension(100, 100)),
new TestData(getClassLoaderResource("/svg/blue-square.svg"), new Dimension(100, 100))
);
}
@ -114,19 +117,19 @@ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase<SVGImage
public void testReadWithSourceRegionParamEqualImage() throws IOException {
super.testReadWithSourceRegionParamEqualImage();
}
@Test
public void testRepeatedRead() throws IOException {
Dimension dim = new Dimension(100, 100);
ImageReader reader = createReader();
ImageReadParam param = reader.getDefaultReadParam();
Dimension dim = new Dimension(100, 100);
ImageReader reader = createReader();
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRenderSize(dim);
TestData redSquare = new TestData(getClassLoaderResource("/svg/red-square.svg"), dim);
TestData redSquare = new TestData(getClassLoaderResource("/svg/red-square.svg"), dim);
reader.setInput(redSquare.getInputStream());
BufferedImage imageRed = reader.read(0, param);
assertEquals(0xFF0000, imageRed.getRGB(50, 50) & 0xFFFFFF);
TestData blueSquare = new TestData(getClassLoaderResource("/svg/blue-square.svg"), dim);
reader.setInput(blueSquare.getInputStream());
BufferedImage imageBlue = reader.read(0, param);