git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195164 13f79535-47bb-0310-9956-ffa450edef68tags/Alt-Design-integration-base
@@ -1,32 +1,36 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for BMP image type. | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula | |||
* @version $Id$ | |||
*/ | |||
public class BMPReader implements ImageReader { | |||
static protected final int BMP_SIG_LENGTH = 26; | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(fis); | |||
boolean supported = ((header[0] == (byte) 0x42) && | |||
(header[1] == (byte) 0x4d)); | |||
/** Length of the BMP header */ | |||
protected static final int BMP_SIG_LENGTH = 26; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(bis); | |||
boolean supported = ((header[0] == (byte) 0x42) | |||
&& (header[1] == (byte) 0x4d)); | |||
if (supported) { | |||
return getDimension(header); | |||
} else { | |||
@@ -34,11 +38,16 @@ public class BMPReader implements ImageReader { | |||
} | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/bmp"; | |||
} | |||
protected FopImage.ImageInfo getDimension(byte[] header) { | |||
private FopImage.ImageInfo getDimension(byte[] header) { | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
info.mimeType = getMimeType(); | |||
@@ -47,20 +56,21 @@ public class BMPReader implements ImageReader { | |||
int byte2 = header[19] & 0xff; | |||
int byte3 = header[20] & 0xff; | |||
int byte4 = header[21] & 0xff; | |||
long l = (long)((byte4 << 24) | (byte3 << 16) | | |||
(byte2 << 8) | byte1); | |||
info.width = (int)(l & 0xffffffff); | |||
long l = (long) ((byte4 << 24) | (byte3 << 16) | |||
| (byte2 << 8) | byte1); | |||
info.width = (int) (l & 0xffffffff); | |||
byte1 = header[22] & 0xff; | |||
byte2 = header[23] & 0xff; | |||
byte3 = header[24] & 0xff; | |||
byte4 = header[25] & 0xff; | |||
l = (long)((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); | |||
info.height = (int)(l & 0xffffffff); | |||
l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); | |||
info.height = (int) (l & 0xffffffff); | |||
return info; | |||
} | |||
protected byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
private byte[] getDefaultHeader(BufferedInputStream imageStream) | |||
throws IOException { | |||
byte[] header = new byte[BMP_SIG_LENGTH]; | |||
try { | |||
imageStream.mark(BMP_SIG_LENGTH + 1); | |||
@@ -69,11 +79,12 @@ public class BMPReader implements ImageReader { | |||
} catch (IOException ex) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ex; | |||
} | |||
return header; | |||
} | |||
} | |||
} |
@@ -1,47 +1,41 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.URL; | |||
import org.xml.sax.InputSource; | |||
import org.xml.sax.XMLReader; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.image.EPSImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for EPS document image type. | |||
* | |||
* @version $Id$ | |||
*/ | |||
public class EPSReader implements ImageReader { | |||
private long getLong(byte[] buf, int idx) { | |||
int b1 = buf[idx] & 0xff; | |||
int b2 = buf[idx + 1] & 0xff; | |||
int b3 = buf[idx + 2] & 0xff; | |||
int b4 = buf[idx + 3] & 0xff; | |||
private static final byte[] EPS_HEADER_ASCII = "%!PS".getBytes(); | |||
private static final byte[] BOUNDINGBOX = "%%BoundingBox: ".getBytes(); | |||
return (long)((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); | |||
} | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException { | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
boolean isEPS = false; | |||
fis.mark(32); | |||
bis.mark(32); | |||
byte[] header = new byte[30]; | |||
fis.read(header, 0, 30); | |||
fis.reset(); | |||
bis.read(header, 0, 30); | |||
bis.reset(); | |||
EPSImage.EPSData data = new EPSImage.EPSData(); | |||
@@ -60,8 +54,10 @@ public class EPSReader implements ImageReader { | |||
} else { | |||
// Check if plain ascii | |||
byte[] epsh = "%!PS".getBytes(); | |||
if (epsh[0] == header[0] && epsh[1] == header[1] && | |||
epsh[2] == header[2] && epsh[3] == header[3]) { | |||
if (EPS_HEADER_ASCII[0] == header[0] | |||
&& EPS_HEADER_ASCII[1] == header[1] | |||
&& EPS_HEADER_ASCII[2] == header[2] | |||
&& EPS_HEADER_ASCII[3] == header[3]) { | |||
data.isAscii = true; | |||
isEPS = true; | |||
} | |||
@@ -71,12 +67,12 @@ public class EPSReader implements ImageReader { | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
info.mimeType = getMimeType(); | |||
info.data = data; | |||
readEPSImage(fis, data); | |||
readEPSImage(bis, data); | |||
data.bbox = readBBox(data); | |||
if (data.bbox != null) { | |||
info.width = (int)(data.bbox[2] - data.bbox[0]); | |||
info.height = (int)(data.bbox[3] - data.bbox[1]); | |||
info.width = (int) (data.bbox[2] - data.bbox[0]); | |||
info.height = (int) (data.bbox[3] - data.bbox[1]); | |||
return info; | |||
} else { | |||
// Ain't eps if no BoundingBox | |||
@@ -87,23 +83,47 @@ public class EPSReader implements ImageReader { | |||
return null; | |||
} | |||
/** read the eps file and extract eps part */ | |||
private void readEPSImage(BufferedInputStream fis, EPSImage.EPSData data) throws IOException { | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/eps"; | |||
} | |||
private long getLong(byte[] buf, int idx) { | |||
int b1 = buf[idx] & 0xff; | |||
int b2 = buf[idx + 1] & 0xff; | |||
int b3 = buf[idx + 2] & 0xff; | |||
int b4 = buf[idx + 3] & 0xff; | |||
return (long) ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); | |||
} | |||
/** | |||
* Read the eps file and extract eps part. | |||
* | |||
* @param bis The InputStream | |||
* @param data EPSData object to write the results to | |||
* @exception IOException If an I/O error occurs | |||
*/ | |||
private void readEPSImage(BufferedInputStream bis, EPSImage.EPSData data) | |||
throws IOException { | |||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||
byte[] file; | |||
byte[] readBuf = new byte[20480]; | |||
int bytes_read; | |||
int bytesRead; | |||
int index = 0; | |||
boolean cont = true; | |||
try { | |||
while ((bytes_read = fis.read(readBuf)) != -1) { | |||
baos.write(readBuf, 0, bytes_read); | |||
while ((bytesRead = bis.read(readBuf)) != -1) { | |||
baos.write(readBuf, 0, bytesRead); | |||
} | |||
} catch (java.io.IOException ex) { | |||
throw new IOException("Error while loading EPS image " + | |||
ex.getMessage()); | |||
throw new IOException("Error while loading EPS image: " | |||
+ ex.getMessage()); | |||
} | |||
file = baos.toByteArray(); | |||
@@ -117,36 +137,45 @@ public class EPSReader implements ImageReader { | |||
data.epsFile = new byte[(int) data.psLength]; | |||
System.arraycopy(file, 0, data.rawEps, 0, data.rawEps.length); | |||
System.arraycopy(data.rawEps, (int) data.psStart, data.epsFile, 0, | |||
(int) data.psLength); | |||
(int) data.psLength); | |||
} | |||
} | |||
/* Get embedded preview or null */ | |||
/** | |||
* Get embedded TIFF preview or null. | |||
* | |||
* @param data The EPS payload | |||
* @return The embedded preview | |||
*/ | |||
public byte[] getPreview(EPSImage.EPSData data) { | |||
if (data.preview == null) { | |||
if (data.tiffLength > 0) { | |||
data.preview = new byte[(int) data.tiffLength]; | |||
System.arraycopy(data.rawEps, (int) data.tiffStart, data.preview, 0, | |||
(int) data.tiffLength); | |||
(int) data.tiffLength); | |||
} | |||
} | |||
return data.preview; | |||
} | |||
/** Extract bounding box from eps part | |||
/** | |||
* Extract bounding box from eps part. | |||
* | |||
* @param data The EPS payload | |||
* @return An Array of four coordinates making up the bounding box | |||
*/ | |||
private long[] readBBox(EPSImage.EPSData data) { | |||
long[] mbbox = null; | |||
int idx = 0; | |||
byte[] bbxName = "%%BoundingBox: ".getBytes(); | |||
boolean found = false; | |||
while (!found && (data.epsFile.length > (idx + bbxName.length))) { | |||
while (!found && (data.epsFile.length > (idx + BOUNDINGBOX.length))) { | |||
boolean sfound = true; | |||
int i = idx; | |||
for (i = idx; sfound && (i - idx) < bbxName.length; i++) { | |||
if (bbxName[i - idx] != data.epsFile[i]) | |||
for (i = idx; sfound && (i - idx) < BOUNDINGBOX.length; i++) { | |||
if (BOUNDINGBOX[i - idx] != data.epsFile[i]) { | |||
sfound = false; | |||
} | |||
} | |||
if (sfound) { | |||
found = true; | |||
@@ -156,9 +185,9 @@ public class EPSReader implements ImageReader { | |||
} | |||
} | |||
if (!found) | |||
if (!found) { | |||
return mbbox; | |||
} | |||
mbbox = new long[4]; | |||
idx += readLongString(data, mbbox, 0, idx); | |||
@@ -171,15 +200,16 @@ public class EPSReader implements ImageReader { | |||
private int readLongString(EPSImage.EPSData data, long[] mbbox, int i, int idx) { | |||
while (idx < data.epsFile.length && (data.epsFile[idx] == 32)) { | |||
idx++; | |||
idx++; | |||
} | |||
int nidx = idx; | |||
// check also for ANSI46(".") to identify floating point values | |||
while (nidx < data.epsFile.length && | |||
((data.epsFile[nidx] >= 48 && data.epsFile[nidx] <= 57) || | |||
(data.epsFile[nidx] == 45) || (data.epsFile[nidx] == 46) )) { | |||
while (nidx < data.epsFile.length | |||
&& ((data.epsFile[nidx] >= 48 && data.epsFile[nidx] <= 57) | |||
|| (data.epsFile[nidx] == 45) | |||
|| (data.epsFile[nidx] == 46))) { | |||
nidx++; | |||
} | |||
@@ -188,17 +218,14 @@ public class EPSReader implements ImageReader { | |||
String ns = new String(num); | |||
//if( ns.indexOf(".") != -1 ) { | |||
// do something like logging a warning | |||
// do something like logging a warning | |||
//} | |||
// then parse the double and round off to the next math. Integer | |||
mbbox[i] = (long) Math.ceil( Double.parseDouble( ns ) ); | |||
mbbox[i] = (long) Math.ceil(Double.parseDouble(ns)); | |||
return (1 + nidx - idx); | |||
} | |||
public String getMimeType() { | |||
return "image/eps"; | |||
} | |||
} | |||
@@ -1,47 +1,58 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for GIF image type. | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula | |||
* @version $Id$ | |||
*/ | |||
public class GIFReader implements ImageReader { | |||
static protected final int GIF_SIG_LENGTH = 10; | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(fis); | |||
boolean supported = ((header[0] == 'G') && (header[1] == 'I') && | |||
(header[2] == 'F') && (header[3] == '8') && | |||
(header[4] == '7' || header[4] == '9') && | |||
(header[5] == 'a')); | |||
private static final int GIF_SIG_LENGTH = 10; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(bis); | |||
boolean supported = ((header[0] == 'G') | |||
&& (header[1] == 'I') | |||
&& (header[2] == 'F') | |||
&& (header[3] == '8') | |||
&& (header[4] == '7' || header[4] == '9') | |||
&& (header[5] == 'a')); | |||
if (supported) { | |||
FopImage.ImageInfo info = getDimension(header); | |||
info.mimeType = getMimeType(); | |||
return info; | |||
} else | |||
} else { | |||
return null; | |||
} | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/gif"; | |||
} | |||
protected FopImage.ImageInfo getDimension(byte[] header) { | |||
private FopImage.ImageInfo getDimension(byte[] header) { | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
// little endian notation | |||
int byte1 = header[6] & 0xff; | |||
@@ -54,7 +65,8 @@ public class GIFReader implements ImageReader { | |||
return info; | |||
} | |||
protected byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
private byte[] getDefaultHeader(BufferedInputStream imageStream) | |||
throws IOException { | |||
byte[] header = new byte[GIF_SIG_LENGTH]; | |||
try { | |||
imageStream.mark(GIF_SIG_LENGTH + 1); | |||
@@ -63,11 +75,12 @@ public class GIFReader implements ImageReader { | |||
} catch (IOException ex) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ex; | |||
} | |||
return header; | |||
} | |||
} | |||
} |
@@ -1,40 +1,43 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader objects read image headers to determine the image size. | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula | |||
* @version $Id$ | |||
*/ | |||
public interface ImageReader { | |||
/** | |||
* Verify image type. | |||
* If the stream does not contain image data expected by | |||
* the reader it must reset the stream to the start. This | |||
* is so that the next reader can start reading from the start. | |||
* The reader must not close the stream unless it can handle | |||
* the image and it has read the information. | |||
* Verify image type. If the stream does not contain image data expected by | |||
* the reader it must reset the stream to the start. This is so that the | |||
* next reader can start reading from the start. The reader must not close | |||
* the stream unless it can handle the image and it has read the | |||
* information. | |||
* | |||
* @param bis Image buffered input stream | |||
* @return true if image type is the handled one | |||
* @exception IOException io error | |||
* @param bis Image buffered input stream | |||
* @param uri URI to the image | |||
* @param ua The user agent | |||
* @return <code>true</code> if image type is the handled one | |||
* @exception IOException if an I/O error occurs | |||
*/ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException; | |||
FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) | |||
throws IOException; | |||
} | |||
@@ -1,10 +1,9 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
@@ -13,39 +12,52 @@ import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* Factory for ImageReader objects. | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula | |||
* @version $Id$ | |||
*/ | |||
public class ImageReaderFactory { | |||
static protected ArrayList formats = new ArrayList(); | |||
private static ArrayList formats = new ArrayList(); | |||
static { | |||
formats.add(new JPEGReader()); | |||
formats.add(new BMPReader()); | |||
formats.add(new GIFReader()); | |||
formats.add(new PNGReader()); | |||
formats.add(new TIFFReader()); | |||
formats.add(new EPSReader()); | |||
registerFormat(new JPEGReader()); | |||
registerFormat(new BMPReader()); | |||
registerFormat(new GIFReader()); | |||
registerFormat(new PNGReader()); | |||
registerFormat(new TIFFReader()); | |||
registerFormat(new EPSReader()); | |||
// the xml parser through batik closes the stream when finished | |||
// so there is a workaround in the SVGReader | |||
formats.add(new SVGReader()); | |||
formats.add(new XMLReader()); | |||
}; | |||
registerFormat(new SVGReader()); | |||
registerFormat(new XMLReader()); | |||
} | |||
// TODO - a way to add other readers | |||
/** | |||
* Registers a new ImageReader. | |||
* | |||
* @param reader An ImageReader instance | |||
*/ | |||
public static void registerFormat(ImageReader reader) { | |||
formats.add(reader); | |||
} | |||
/** | |||
* ImageReader maker. | |||
* @param in image input stream | |||
* @return ImageReader object | |||
* image type is not supported | |||
* | |||
* @param uri URI to the image | |||
* @param in image input stream | |||
* @param ua user agent | |||
* @return An ImageInfo object describing the image | |||
*/ | |||
static public FopImage.ImageInfo make(String uri, InputStream in, | |||
FOUserAgent ua) { | |||
public static FopImage.ImageInfo make(String uri, InputStream in, | |||
FOUserAgent ua) { | |||
ImageReader reader; | |||
BufferedInputStream bis = new BufferedInputStream(in); | |||
@@ -53,14 +65,14 @@ public class ImageReaderFactory { | |||
for (int count = 0; count < formats.size(); count++) { | |||
reader = (ImageReader) formats.get(count); | |||
FopImage.ImageInfo info = reader.verifySignature(uri, bis, ua); | |||
if(info != null) { | |||
if (info != null) { | |||
return info; | |||
} | |||
} | |||
} catch (IOException ex) { | |||
ua.getLogger().error( | |||
"Error while recovering Image Informations (" + | |||
uri + ") : " + ex.getMessage()); | |||
"Error while recovering Image Informations (" | |||
+ uri + ")", ex); | |||
} | |||
return null; | |||
} |
@@ -1,23 +1,24 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for JPEG image type. | |||
* | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* @version $Id$ | |||
*/ | |||
public class JPEGReader implements ImageReader { | |||
@@ -28,23 +29,24 @@ public class JPEGReader implements ImageReader { | |||
* inside the APPn marker. And we don't want to confuse those dimensions with | |||
* the image dimensions. | |||
*/ | |||
static protected final int MARK = 0xff; // Beginneing of a Marker | |||
static protected final int NULL = 0x00; // Special case for 0xff00 | |||
static protected final int SOF1 = 0xc0; // Baseline DCT | |||
static protected final int SOF2 = 0xc1; // Extended Sequential DCT | |||
static protected final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 | |||
static protected final int SOFA = 0xca; // Progressice DCT only PDF 1.3 | |||
static protected final int APP0 = 0xe0; // Application marker, JFIF | |||
static protected final int APPF = 0xef; // Application marker | |||
static protected final int SOS = 0xda; // Start of Scan | |||
static protected final int SOI = 0xd8; // start of Image | |||
static protected final int JPG_SIG_LENGTH = 2; | |||
private static final int MARK = 0xff; // Beginning of a Marker | |||
private static final int NULL = 0x00; // Special case for 0xff00 | |||
private static final int SOF1 = 0xc0; // Baseline DCT | |||
private static final int SOF2 = 0xc1; // Extended Sequential DCT | |||
private static final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 | |||
private static final int SOFA = 0xca; // Progressice DCT only PDF 1.3 | |||
private static final int APP0 = 0xe0; // Application marker, JFIF | |||
private static final int APPF = 0xef; // Application marker | |||
private static final int SOS = 0xda; // Start of Scan | |||
private static final int SOI = 0xd8; // start of Image | |||
private static final int JPG_SIG_LENGTH = 2; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(fis); | |||
boolean supported = ((header[0] == (byte) 0xff) && | |||
(header[1] == (byte) 0xd8)); | |||
boolean supported = ((header[0] == (byte) 0xff) | |||
&& (header[1] == (byte) 0xd8)); | |||
if (supported) { | |||
FopImage.ImageInfo info = getDimension(fis); | |||
info.mimeType = getMimeType(); | |||
@@ -54,11 +56,16 @@ public class JPEGReader implements ImageReader { | |||
} | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/jpeg"; | |||
} | |||
protected byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
private byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
byte[] header = new byte[JPG_SIG_LENGTH]; | |||
try { | |||
imageStream.mark(JPG_SIG_LENGTH + 1); | |||
@@ -67,13 +74,15 @@ public class JPEGReader implements ImageReader { | |||
} catch (IOException ex) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ex; | |||
} | |||
return header; | |||
} | |||
protected FopImage.ImageInfo getDimension(BufferedInputStream imageStream) throws IOException { | |||
private FopImage.ImageInfo getDimension(BufferedInputStream imageStream) throws IOException { | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
try { | |||
int marker = NULL; | |||
@@ -81,12 +90,13 @@ public class JPEGReader implements ImageReader { | |||
outer: | |||
while (imageStream.available() > 0) { | |||
while ((marker = imageStream.read()) != MARK) { | |||
; | |||
//nop, simply skip | |||
} | |||
do { | |||
marker = imageStream.read(); | |||
} while (marker == MARK) | |||
; | |||
} while (marker == MARK); | |||
switch (marker) { | |||
case SOI: | |||
break; | |||
@@ -103,26 +113,29 @@ public class JPEGReader implements ImageReader { | |||
default: | |||
length = this.read2bytes(imageStream); | |||
skipped = this.skip(imageStream, length - 2); | |||
if (skipped != length - 2) | |||
if (skipped != length - 2) { | |||
throw new IOException("Skipping Error"); | |||
} | |||
} | |||
} | |||
} catch (IOException ioe) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ioe; | |||
} | |||
return info; | |||
} | |||
protected int read2bytes(BufferedInputStream imageStream) throws IOException { | |||
private int read2bytes(BufferedInputStream imageStream) throws IOException { | |||
int byte1 = imageStream.read(); | |||
int byte2 = imageStream.read(); | |||
return (int)((byte1 << 8) | byte2); | |||
return (int) ((byte1 << 8) | byte2); | |||
} | |||
protected long skip(BufferedInputStream imageStream, long n) throws IOException { | |||
private long skip(BufferedInputStream imageStream, long n) throws IOException { | |||
long discarded = 0; | |||
while (discarded != n) { | |||
imageStream.read(); | |||
@@ -131,5 +144,4 @@ public class JPEGReader implements ImageReader { | |||
return discarded; // scope for exception | |||
} | |||
} | |||
} |
@@ -1,35 +1,42 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for PNG image type. | |||
* @author Pankaj Narula | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula | |||
* @version $Id$ | |||
*/ | |||
public class PNGReader implements ImageReader { | |||
static protected final int PNG_SIG_LENGTH = 24; | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(fis); | |||
boolean supported = ((header[0] == (byte) 0x89) && | |||
(header[1] == (byte) 0x50) && (header[2] == (byte) 0x4e) && | |||
(header[3] == (byte) 0x47) && (header[4] == (byte) 0x0d) && | |||
(header[5] == (byte) 0x0a) && | |||
(header[6] == (byte) 0x1a) && (header[7] == (byte) 0x0a)); | |||
private static final int PNG_SIG_LENGTH = 24; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(bis); | |||
boolean supported = ((header[0] == (byte) 0x89) | |||
&& (header[1] == (byte) 0x50) | |||
&& (header[2] == (byte) 0x4e) | |||
&& (header[3] == (byte) 0x47) | |||
&& (header[4] == (byte) 0x0d) | |||
&& (header[5] == (byte) 0x0a) | |||
&& (header[6] == (byte) 0x1a) | |||
&& (header[7] == (byte) 0x0a)); | |||
if (supported) { | |||
FopImage.ImageInfo info = getDimension(header); | |||
info.mimeType = getMimeType(); | |||
@@ -39,11 +46,16 @@ public class PNGReader implements ImageReader { | |||
} | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/png"; | |||
} | |||
protected FopImage.ImageInfo getDimension(byte[] header) { | |||
private FopImage.ImageInfo getDimension(byte[] header) { | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
// png is always big endian | |||
@@ -51,20 +63,23 @@ public class PNGReader implements ImageReader { | |||
int byte2 = header[17] & 0xff; | |||
int byte3 = header[18] & 0xff; | |||
int byte4 = header[19] & 0xff; | |||
long l = (long)((byte1 << 24) | (byte2 << 16) | | |||
(byte3 << 8) | byte4); | |||
info.width = (int)(l); | |||
long l = (long) ((byte1 << 24) | |||
| (byte2 << 16) | |||
| (byte3 << 8) | |||
| (byte4)); | |||
info.width = (int) l; | |||
byte1 = header[20] & 0xff; | |||
byte2 = header[21] & 0xff; | |||
byte3 = header[22] & 0xff; | |||
byte4 = header[23] & 0xff; | |||
l = (long)((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); | |||
info.height = (int)(l); | |||
l = (long) ((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); | |||
info.height = (int) l; | |||
return info; | |||
} | |||
protected byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
private byte[] getDefaultHeader(BufferedInputStream imageStream) | |||
throws IOException { | |||
byte[] header = new byte[PNG_SIG_LENGTH]; | |||
try { | |||
imageStream.mark(PNG_SIG_LENGTH + 1); | |||
@@ -73,11 +88,12 @@ public class PNGReader implements ImageReader { | |||
} catch (IOException ex) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ex; | |||
} | |||
return header; | |||
} | |||
} | |||
} |
@@ -1,85 +1,72 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.awt.geom.AffineTransform; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.svg.SVGDocument; | |||
import org.w3c.dom.svg.SVGSVGElement; | |||
// FOP | |||
import org.apache.fop.image.XMLImage; | |||
import org.xml.sax.InputSource; | |||
import org.xml.sax.XMLReader; | |||
// Batik | |||
import org.apache.batik.dom.svg.SAXSVGDocumentFactory; | |||
import org.apache.batik.dom.svg.*; | |||
import org.w3c.dom.*; | |||
import org.w3c.dom.svg.*; | |||
import org.w3c.dom.svg.SVGLength; | |||
import org.apache.batik.bridge.*; | |||
import org.apache.batik.swing.svg.*; | |||
import org.apache.batik.swing.gvt.*; | |||
import org.apache.batik.gvt.*; | |||
import org.apache.batik.gvt.renderer.*; | |||
import org.apache.batik.gvt.filter.*; | |||
import org.apache.batik.gvt.event.*; | |||
import org.w3c.dom.DOMImplementation; | |||
import org.apache.batik.dom.svg.SVGOMDocument; | |||
import org.apache.batik.bridge.BridgeContext; | |||
import org.apache.batik.bridge.UnitProcessor; | |||
import org.apache.batik.dom.svg.SVGDOMImplementation; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.net.URL; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.Point; | |||
import java.awt.geom.Dimension2D; | |||
import java.awt.Dimension; | |||
// FOP | |||
import org.apache.fop.image.XMLImage; | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
import org.apache.fop.svg.SVGUserAgent; | |||
/** | |||
* ImageReader object for SVG document image type. | |||
*/ | |||
/** ImageReader object for SVG document image type. */ | |||
public class SVGReader implements ImageReader { | |||
/** SVG's MIME type */ | |||
public static final String SVG_MIME_TYPE = "image/svg+xml"; | |||
boolean batik = true; | |||
public SVGReader() { | |||
} | |||
private boolean batik = true; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
FOUserAgent ua) | |||
throws IOException { | |||
return loadImage(uri, fis, ua); | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return SVG_MIME_TYPE; | |||
} | |||
/** | |||
* This means the external svg document will be loaded twice. | |||
* Possibly need a slightly different design for the image stuff. | |||
* This means the external svg document will be loaded twice. Possibly need | |||
* a slightly different design for the image stuff. | |||
* | |||
* @param uri @todo Description of the Parameter | |||
* @param fis @todo Description of the Parameter | |||
* @param ua @todo Description of the Parameter | |||
* @return @todo Description of the Return Value | |||
*/ | |||
protected FopImage.ImageInfo loadImage(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) { | |||
if(batik) { | |||
private FopImage.ImageInfo loadImage(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) { | |||
if (batik) { | |||
try { | |||
Loader loader = new Loader(); | |||
return loader.getImage(uri, fis, ua); | |||
return loader.getImage(uri, bis, ua); | |||
} catch (NoClassDefFoundError e) { | |||
batik = false; | |||
//ua.getLogger().error("Batik not in class path", e); | |||
@@ -90,13 +77,13 @@ public class SVGReader implements ImageReader { | |||
} | |||
/** | |||
* This method is put in another class so that the classloader | |||
* does not attempt to load batik related classes when constructing | |||
* the SVGReader class. | |||
* This method is put in another class so that the classloader does not | |||
* attempt to load batik related classes when constructing the SVGReader | |||
* class. | |||
*/ | |||
class Loader { | |||
private FopImage.ImageInfo getImage(String uri, InputStream fis, | |||
FOUserAgent ua) { | |||
FOUserAgent ua) { | |||
// parse document and get the size attributes of the svg element | |||
try { | |||
@@ -107,46 +94,49 @@ public class SVGReader implements ImageReader { | |||
String start = new String(b); | |||
fis.reset(); | |||
if(start.equals("<?xml")) { | |||
if (start.equals("<?xml")) { | |||
// we have xml, might be another doc | |||
// so stop batik from closing the stream | |||
final InputStream input = fis; | |||
fis = new InputStream() { | |||
public int read() throws IOException { | |||
return input.read(); | |||
} | |||
public int read(byte[] b) throws IOException { | |||
return input.read(b); | |||
} | |||
public int read(byte[] b, int off, int len) throws IOException { | |||
return input.read(b, off, len); | |||
} | |||
public long skip(long n) throws IOException { | |||
return input.skip(n); | |||
} | |||
public int available() throws IOException { | |||
return input.available(); | |||
} | |||
public void mark(int rl) { | |||
input.mark(rl); | |||
} | |||
public boolean markSupported() { | |||
return input.markSupported(); | |||
} | |||
public void reset() throws IOException { | |||
input.reset(); | |||
} | |||
public void close() throws IOException { | |||
} | |||
}; | |||
fis = | |||
new InputStream() { | |||
public int read() throws IOException { | |||
return input.read(); | |||
} | |||
public int read(byte[] b) throws IOException { | |||
return input.read(b); | |||
} | |||
public int read(byte[] b, int off, int len) | |||
throws IOException { | |||
return input.read(b, off, len); | |||
} | |||
public long skip(long n) throws IOException { | |||
return input.skip(n); | |||
} | |||
public int available() throws IOException { | |||
return input.available(); | |||
} | |||
public void mark(int rl) { | |||
input.mark(rl); | |||
} | |||
public boolean markSupported() { | |||
return input.markSupported(); | |||
} | |||
public void reset() throws IOException { | |||
input.reset(); | |||
} | |||
public void close() throws IOException { | |||
//ignore | |||
} | |||
}; | |||
} | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
@@ -157,46 +147,47 @@ public class SVGReader implements ImageReader { | |||
length = fis.available(); | |||
fis.mark(length + 1); | |||
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory( | |||
XMLImage.getParserName()); | |||
SVGDocument doc = (SVGDocument)factory.createDocument(uri, fis); | |||
XMLImage.getParserName()); | |||
SVGDocument doc = (SVGDocument) factory.createDocument(uri, fis); | |||
info.data = doc; | |||
Element e = doc.getRootElement(); | |||
String s; | |||
SVGUserAgent userAg = | |||
new SVGUserAgent(ua, new AffineTransform()); | |||
new SVGUserAgent(ua, new AffineTransform()); | |||
BridgeContext ctx = new BridgeContext(userAg); | |||
UnitProcessor.Context uctx = | |||
UnitProcessor.createContext(ctx, e); | |||
UnitProcessor.createContext(ctx, e); | |||
// 'width' attribute - default is 100% | |||
s = e.getAttributeNS(null, | |||
SVGOMDocument.SVG_WIDTH_ATTRIBUTE); | |||
SVGOMDocument.SVG_WIDTH_ATTRIBUTE); | |||
if (s.length() == 0) { | |||
s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE; | |||
} | |||
info.width = (int) UnitProcessor.svgHorizontalLengthToUserSpace ( | |||
s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx); | |||
info.width = (int) UnitProcessor.svgHorizontalLengthToUserSpace( | |||
s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx); | |||
// 'height' attribute - default is 100% | |||
s = e.getAttributeNS(null, | |||
SVGOMDocument.SVG_HEIGHT_ATTRIBUTE); | |||
SVGOMDocument.SVG_HEIGHT_ATTRIBUTE); | |||
if (s.length() == 0) { | |||
s = SVGOMDocument.SVG_SVG_HEIGHT_DEFAULT_VALUE; | |||
} | |||
info.height = (int) UnitProcessor.svgVerticalLengthToUserSpace ( | |||
s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx); | |||
info.height = (int) UnitProcessor.svgVerticalLengthToUserSpace( | |||
s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx); | |||
return info; | |||
} catch (NoClassDefFoundError ncdfe) { | |||
try { | |||
fis.reset(); | |||
} catch (IOException ioe) { } | |||
} catch (IOException ioe) { | |||
// we're more interested in the original exception | |||
} | |||
batik = false; | |||
//ua.getLogger().error("Batik not in class path", ncdfe); | |||
return null; | |||
} | |||
catch (Exception e) { | |||
} catch (Exception e) { | |||
// If the svg is invalid then it throws an IOException | |||
// so there is no way of knowing if it is an svg document | |||
@@ -206,11 +197,12 @@ public class SVGReader implements ImageReader { | |||
// or could not be loaded for some reason | |||
try { | |||
fis.reset(); | |||
} catch (IOException ioe) { } | |||
} catch (IOException ioe) { | |||
// we're more interested in the original exception | |||
} | |||
return null; | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,44 +1,51 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
/** | |||
* ImageReader object for TIFF image type. | |||
* @author Pankaj Narula, Michael Lee | |||
* @version 1.0 | |||
* | |||
* @author Pankaj Narula, Michael Lee | |||
* @version $Id$ | |||
*/ | |||
public class TIFFReader implements ImageReader { | |||
static protected final int TIFF_SIG_LENGTH = 8; | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(fis); | |||
private static final int TIFF_SIG_LENGTH = 8; | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) throws IOException { | |||
byte[] header = getDefaultHeader(bis); | |||
boolean supported = false; | |||
if (header[0] == (byte) 0x49 && header[1] == (byte) 0x49)// first 2 bytes = II (little endian encoding) | |||
{ | |||
// first 2 bytes = II (little endian encoding) | |||
if (header[0] == (byte) 0x49 && header[1] == (byte) 0x49) { | |||
// look for '42' in byte 3 and '0' in byte 4 | |||
if (header[2] == 42 && header[3] == 0) | |||
if (header[2] == 42 && header[3] == 0) { | |||
supported = true; | |||
} | |||
} | |||
if (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D)// first 2 bytes == MM (big endian encoding) | |||
{ | |||
// first 2 bytes == MM (big endian encoding) | |||
if (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D) { | |||
// look for '42' in byte 4 and '0' in byte 3 | |||
if (header[2] == 0 && header[3] == 42) | |||
if (header[2] == 0 && header[3] == 42) { | |||
supported = true; | |||
} | |||
} | |||
if (supported) { | |||
@@ -50,11 +57,16 @@ public class TIFFReader implements ImageReader { | |||
} | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "image/tiff"; | |||
} | |||
protected FopImage.ImageInfo getDimension(byte[] header) { | |||
private FopImage.ImageInfo getDimension(byte[] header) { | |||
// currently not setting the width and height | |||
// these are set again by the Jimi image reader. | |||
// I suppose I'll do it one day to be complete. Or | |||
@@ -77,13 +89,14 @@ public class TIFFReader implements ImageReader { | |||
* byte4 ); | |||
* this.height = ( int ) ( l ); | |||
*/ | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
info.width = -1; | |||
info.height = -1; | |||
return info; | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
info.width = -1; | |||
info.height = -1; | |||
return info; | |||
} | |||
protected byte[] getDefaultHeader(BufferedInputStream imageStream) throws IOException { | |||
private byte[] getDefaultHeader(BufferedInputStream imageStream) | |||
throws IOException { | |||
byte[] header = new byte[TIFF_SIG_LENGTH]; | |||
try { | |||
imageStream.mark(TIFF_SIG_LENGTH + 1); | |||
@@ -92,7 +105,9 @@ public class TIFFReader implements ImageReader { | |||
} catch (IOException ex) { | |||
try { | |||
imageStream.reset(); | |||
} catch (IOException exbis) {} | |||
} catch (IOException exbis) { | |||
// throw the original exception, not this one | |||
} | |||
throw ex; | |||
} | |||
return header; |
@@ -1,61 +1,78 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.image.analyser; | |||
// Java | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
import java.util.Map; | |||
import org.xml.sax.InputSource; | |||
// XML | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.*; | |||
import org.w3c.dom.DOMImplementation; | |||
import java.io.File; | |||
import java.net.URL; | |||
import java.util.HashMap; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.fo.FOUserAgent; | |||
import org.apache.fop.image.XMLImage; | |||
/** | |||
* ImageReader object for XML document image type. | |||
*/ | |||
/** ImageReader object for XML document image type. */ | |||
public class XMLReader implements ImageReader { | |||
private static HashMap converters = new HashMap(); | |||
private static Map converters = new java.util.HashMap(); | |||
/** | |||
* Registers a Converter implementation with XMLReader. | |||
* | |||
* @param ns The namespace to associate with this converter | |||
* @param conv The actual Converter implementation | |||
*/ | |||
public static void setConverter(String ns, Converter conv) { | |||
converters.put(ns, conv); | |||
} | |||
public XMLReader() { | |||
} | |||
/** @see org.apache.fop.image.analyser.ImageReader */ | |||
public FopImage.ImageInfo verifySignature(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) throws IOException { | |||
FOUserAgent ua) | |||
throws IOException { | |||
return loadImage(uri, fis, ua); | |||
} | |||
/** | |||
* Returns the MIME type supported by this implementation. | |||
* | |||
* @return The MIME type | |||
*/ | |||
public String getMimeType() { | |||
return "text/xml"; | |||
} | |||
/** | |||
* This means the external svg document will be loaded twice. | |||
* Possibly need a slightly different design for the image stuff. | |||
* Creates an ImageInfo object from an XML image read from a stream. | |||
* | |||
* @todo This means the external svg document will be loaded twice. Possibly need | |||
* a slightly different design for the image stuff. | |||
* | |||
* @param uri The URI to the image | |||
* @param bis The InputStream | |||
* @param ua The user agent | |||
* @return An ImageInfo object describing the image | |||
*/ | |||
protected FopImage.ImageInfo loadImage(String uri, BufferedInputStream fis, | |||
FOUserAgent ua) { | |||
return createDocument(fis, ua); | |||
protected FopImage.ImageInfo loadImage(String uri, BufferedInputStream bis, | |||
FOUserAgent ua) { | |||
return createDocument(bis, ua); | |||
} | |||
/** | |||
* Creates an ImageInfo object from an XML image read from a stream. | |||
* | |||
* @param is The InputStream | |||
* @param ua The user agent | |||
* @return An ImageInfo object describing the image | |||
*/ | |||
public FopImage.ImageInfo createDocument(BufferedInputStream is, FOUserAgent ua) { | |||
Document doc = null; | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
@@ -70,29 +87,43 @@ public class XMLReader implements ImageReader { | |||
info.data = doc; | |||
Element root = doc.getDocumentElement(); | |||
ua.getLogger().debug("ns:" + root.getAttribute("xmlns")); | |||
ua.getLogger().debug("XML image namespace: " + root.getAttribute("xmlns")); | |||
String ns = root.getAttribute("xmlns"); | |||
info.str = ns; | |||
Converter conv = (Converter)converters.get(ns); | |||
if(conv != null) { | |||
Converter conv = (Converter) converters.get(ns); | |||
if (conv != null) { | |||
FopImage.ImageInfo i = conv.convert(doc); | |||
if(i != null) { | |||
if (i != null) { | |||
info = i; | |||
} | |||
} | |||
} catch (Exception e) { | |||
//e.printStackTrace(); | |||
ua.getLogger().warn("Error while constructing image from XML", e); | |||
try { | |||
is.reset(); | |||
} catch (IOException ioe) { } | |||
} catch (IOException ioe) { | |||
// throw the original exception, not this one | |||
} | |||
return null; | |||
} | |||
return info; | |||
} | |||
/** | |||
* This interface is to be implemented for XML to image converters. | |||
*/ | |||
public static interface Converter { | |||
public FopImage.ImageInfo convert(Document doc); | |||
/** | |||
* This method is called for a DOM document to be converted into an | |||
* ImageInfo object. | |||
* | |||
* @param doc The DOM document to convert | |||
* @return An ImageInfo object describing the image | |||
*/ | |||
FopImage.ImageInfo convert(Document doc); | |||
} | |||
} | |||