You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2007/12/04 11:27:55 UTC
svn commit: r600870 [2/3] - in
/xmlgraphics/fop/branches/Temp_ImagePackageRedesign:
src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/
src/java/org/apache/fop/fo/flow/ src/java/org/apache/fop/image2/
src/java/org/apache/fop/image2/cache/ src/j...
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRawStream.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRawStream.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRawStream.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRawStream.java Tue Dec 4 02:27:51 2007
@@ -21,9 +21,10 @@
import java.io.InputStream;
+import org.apache.commons.io.IOUtils;
+
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
-import org.apache.fop.image2.util.ImageUtil;
/**
* This class is an implementation of the Image interface exposing an InputStream for loading the
@@ -32,27 +33,28 @@
public class ImageRawStream extends AbstractImage {
private ImageFlavor flavor;
- private InputStream in;
+ private InputStreamFactory streamFactory;
/**
- * Constructor for use with ImageLoaders.
+ * Main constructor.
* @param info the image info object
* @param flavor the image flavor for the raw image
+ * @param streamFactory the InputStreamFactory that is used to create InputStream instances
*/
- public ImageRawStream(ImageInfo info, ImageFlavor flavor) {
- this(info, flavor, ImageUtil.needInputStream(info.getSource()));
+ public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStreamFactory streamFactory) {
+ super(info);
+ this.flavor = flavor;
+ setInputStreamFactory(streamFactory);
}
/**
- * Main constructor.
+ * Constructor for a simple InputStream as parameter.
* @param info the image info object
* @param flavor the image flavor for the raw image
* @param in the InputStream with the raw content
*/
public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStream in) {
- super(info);
- this.flavor = flavor;
- this.in = in;
+ this(info, flavor, new SingleStreamFactory(in));
}
/** {@inheritDoc} */
@@ -60,11 +62,88 @@
return this.flavor;
}
+ /** {@inheritDoc} */
+ public boolean isCacheable() {
+ return !this.streamFactory.isUsedOnceOnly();
+ }
+
+ /**
+ * Sets the InputStreamFactory to be used by this image. This method allows to replace the
+ * original factory.
+ * @param factory the new InputStreamFactory
+ */
+ public void setInputStreamFactory(InputStreamFactory factory) {
+ if (this.streamFactory != null) {
+ this.streamFactory.close();
+ }
+ this.streamFactory = factory;
+ }
+
/**
- * Returns an InputStream to access the raw image.
+ * Returns a new InputStream to access the raw image.
* @return the InputStream
*/
- public InputStream getInputStream() {
- return this.in;
+ public InputStream createInputStream() {
+ return this.streamFactory.createInputStream();
+ }
+
+ /**
+ * Represents a factory for InputStream objects. Make sure the class is thread-safe!
+ */
+ public interface InputStreamFactory {
+
+ /**
+ * Indicates whether this factory is only usable once or many times.
+ * @return true if the factory can only be used once
+ */
+ boolean isUsedOnceOnly();
+
+ /**
+ * Creates and returns a new InputStream.
+ * @return the new InputStream
+ */
+ InputStream createInputStream();
+
+ /**
+ * Closes the factory and releases any resources held open during the lifetime of this
+ * object.
+ */
+ void close();
+
}
+
+ private static class SingleStreamFactory implements InputStreamFactory {
+
+ private InputStream in;
+
+ public SingleStreamFactory(InputStream in) {
+ this.in = in;
+ }
+
+ public synchronized InputStream createInputStream() {
+ if (this.in != null) {
+ InputStream tempin = this.in;
+ this.in = null; //Don't close, just remove the reference
+ return tempin;
+ } else {
+ throw new IllegalStateException("Can only create an InputStream once!");
+ }
+ }
+
+ public synchronized void close() {
+ IOUtils.closeQuietly(this.in);
+ this.in = null;
+ }
+
+ public boolean isUsedOnceOnly() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ protected void finalize() {
+ close();
+ }
+
+ }
+
}
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRendered.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRendered.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRendered.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRendered.java Tue Dec 4 02:27:51 2007
@@ -46,6 +46,11 @@
return ImageFlavor.RENDERED_IMAGE;
}
+ /** {@inheritDoc} */
+ public boolean isCacheable() {
+ return true;
+ }
+
/**
* Returns the contained RenderedImage instance.
* @return the RenderedImage instance
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageXMLDOM.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageXMLDOM.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageXMLDOM.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageXMLDOM.java Tue Dec 4 02:27:51 2007
@@ -19,9 +19,10 @@
package org.apache.fop.image2.impl;
+import org.w3c.dom.Document;
+
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
-import org.w3c.dom.Document;
/**
* This class is an implementation of the Image interface exposing an XML DOM (W3C).
@@ -48,6 +49,11 @@
return ImageFlavor.XML_DOM;
}
+ /** {@inheritDoc} */
+ public boolean isCacheable() {
+ return true;
+ }
+
/**
* Returns the contained W3C DOM document.
* @return the DOM
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderBMP.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderBMP.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderBMP.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderBMP.java Tue Dec 4 02:27:51 2007
@@ -25,7 +25,7 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
@@ -44,7 +44,7 @@
private static final int WIDTH_OFFSET = 18;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -55,8 +55,8 @@
&& (header[1] == (byte) 0x4d));
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(in, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(in, context));
return info;
} else {
return null;
@@ -68,8 +68,8 @@
return "image/bmp";
}
- private ImageSize determineSize(ImageInputStream in, FOUserAgent userAgent) throws IOException,
- ImageException {
+ private ImageSize determineSize(ImageInputStream in, ImageContext context)
+ throws IOException, ImageException {
in.mark();
ByteOrder oldByteOrder = in.getByteOrder();
try {
@@ -87,13 +87,13 @@
int xRes = in.readInt();
double xResDPI = UnitConv.in2mm(xRes / 1000d);
if (xResDPI == 0) {
- xResDPI = userAgent.getSourceResolution();
+ xResDPI = context.getSourceResolution();
}
int yRes = in.readInt();
double yResDPI = UnitConv.in2mm(yRes / 1000d);
if (yResDPI == 0) {
- yResDPI = userAgent.getSourceResolution();
+ yResDPI = context.getSourceResolution();
}
size.setResolution(xResDPI, yResDPI);
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEMF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEMF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEMF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEMF.java Tue Dec 4 02:27:51 2007
@@ -25,7 +25,7 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
@@ -56,7 +56,7 @@
private static final int VRES_MM_OFFSET = 84;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -70,8 +70,8 @@
&& (header[SIGNATURE_OFFSET + 3] == (byte) 0x46) );
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(in, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(in, context));
return info;
} else {
return null;
@@ -83,8 +83,8 @@
return "image/emf";
}
- private ImageSize determineSize(ImageInputStream in, FOUserAgent userAgent) throws IOException,
- ImageException {
+ private ImageSize determineSize(ImageInputStream in, ImageContext context)
+ throws IOException, ImageException {
in.mark();
ByteOrder oldByteOrder = in.getByteOrder();
try {
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEPS.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEPS.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEPS.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderEPS.java Tue Dec 4 02:27:51 2007
@@ -34,8 +34,8 @@
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox;
import org.apache.xmlgraphics.ps.dsc.events.DSCEvent;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
import org.apache.fop.image2.util.ImageInputStreamAdapter;
@@ -52,7 +52,7 @@
public static final Object EPS_BOUNDING_BOX = Rectangle2D.class;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -83,8 +83,8 @@
}
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- boolean success = determineSize(in, userAgent, info);
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ boolean success = determineSize(in, context, info);
in.reset(); //Need to go back to start of file
if (!success) {
//No BoundingBox found, so probably no EPS
@@ -121,7 +121,7 @@
return offsets;
}
- private boolean determineSize(ImageInputStream in, FOUserAgent userAgent, ImageInfo info)
+ private boolean determineSize(ImageInputStream in, ImageContext context, ImageInfo info)
throws IOException {
in.mark();
@@ -168,7 +168,7 @@
size.setSizeInMillipoints(
(int)Math.round(bbox.getWidth() * 1000),
(int)Math.round(bbox.getHeight() * 1000));
- size.setResolution(userAgent.getSourceResolution());
+ size.setResolution(context.getSourceResolution());
size.calcPixelsFromSize();
info.setSize(size);
info.getCustomObjects().put(EPS_BOUNDING_BOX, bbox);
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderGIF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderGIF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderGIF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderGIF.java Tue Dec 4 02:27:51 2007
@@ -24,8 +24,8 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
import org.apache.fop.image2.util.ImageUtil;
@@ -38,7 +38,7 @@
private static final int GIF_SIG_LENGTH = 10;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -53,8 +53,8 @@
&& (header[5] == 'a'));
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(header, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(header, context));
return info;
} else {
return null;
@@ -66,7 +66,7 @@
return MimeConstants.MIME_GIF;
}
- private ImageSize determineSize(byte[] header, FOUserAgent userAgent) {
+ private ImageSize determineSize(byte[] header, ImageContext context) {
// little endian notation
int byte1 = header[6] & 0xff;
int byte2 = header[7] & 0xff;
@@ -75,7 +75,7 @@
byte1 = header[8] & 0xff;
byte2 = header[9] & 0xff;
int height = ((byte2 << 8) | byte1) & 0xffff;
- ImageSize size = new ImageSize(width, height, userAgent.getSourceResolution());
+ ImageSize size = new ImageSize(width, height, context.getSourceResolution());
size.calcSizeFromPixels();
return size;
}
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderJPEG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderJPEG.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderJPEG.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderJPEG.java Tue Dec 4 02:27:51 2007
@@ -24,8 +24,8 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
@@ -34,13 +34,13 @@
/**
* Image preloader for JPEG images.
*/
-public class PreloaderJPEG extends AbstractImagePreloader implements JPEGConstants {
+public class PreloaderJPEG extends AbstractImagePreloader implements JPEGConstants {
private static final int JPG_SIG_LENGTH = 3;
/** {@inheritDoc}
* @throws ImageException */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -52,8 +52,8 @@
&& (header[2] == (byte)MARK));
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(in, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(in, context));
return info;
} else {
return null;
@@ -65,14 +65,17 @@
return MimeConstants.MIME_JPEG;
}
- private ImageSize determineSize(ImageInputStream in, FOUserAgent userAgent) throws IOException,
- ImageException {
+ private ImageSize determineSize(ImageInputStream in, ImageContext context)
+ throws IOException, ImageException {
in.mark();
try {
ImageSize size = new ImageSize();
+ //TODO Read resolution from EXIF if there's no APP0
+ //(for example with JPEGs from digicams)
while (true) {
int segID = readMarkerSegment(in);
+ //System.out.println("Segment: " + Integer.toHexString(segID));
switch (segID) {
case SOI:
case NULL:
@@ -93,7 +96,11 @@
size.setResolution(xdensity, ydensity);
} else {
//resolution not specified
- size.setResolution(userAgent.getSourceResolution());
+ size.setResolution(context.getSourceResolution());
+ }
+ if (size.getWidthPx() != 0) {
+ size.calcSizeFromPixels();
+ return size;
}
in.skipBytes(reclen - 14);
break;
@@ -106,7 +113,17 @@
int height = in.readUnsignedShort();
int width = in.readUnsignedShort();
size.setSizeInPixels(width, height);
- size.calcSizeFromPixels();
+ if (size.getDpiHorizontal() != 0) {
+ size.calcSizeFromPixels();
+ return size;
+ }
+ break;
+ case SOS:
+ case EOI:
+ if (size.getDpiHorizontal() == 0) {
+ size.setResolution(context.getSourceResolution());
+ size.calcSizeFromPixels();
+ }
return size;
default:
reclen = in.readUnsignedShort();
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderPNG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderPNG.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderPNG.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderPNG.java Tue Dec 4 02:27:51 2007
@@ -28,8 +28,8 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
@@ -48,7 +48,7 @@
/** {@inheritDoc}
* @throws ImageException */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -65,8 +65,8 @@
&& (header[7] == (byte) 0x0a));
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(in, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(in, context));
return info;
} else {
return null;
@@ -78,7 +78,7 @@
return MimeConstants.MIME_PNG;
}
- private ImageSize determineSize(ImageInputStream in, FOUserAgent userAgent)
+ private ImageSize determineSize(ImageInputStream in, ImageContext context)
throws IOException, ImageException {
in.mark();
@@ -95,7 +95,7 @@
size.setSizeInPixels(reader.getWidth(imageIndex), reader.getHeight(imageIndex));
//Resolution (first a default, then try to read the metadata)
- size.setResolution(userAgent.getSourceResolution());
+ size.setResolution(context.getSourceResolution());
ImageIOUtil.extractResolution(iiometa, size);
reader.dispose();
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderTIFF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderTIFF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderTIFF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/PreloaderTIFF.java Tue Dec 4 02:27:51 2007
@@ -24,18 +24,19 @@
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFField;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
+import org.apache.xmlgraphics.image.codec.util.SeekableStream;
+
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
import org.apache.fop.image2.util.ImageUtil;
import org.apache.fop.image2.util.SeekableStreamAdapter;
import org.apache.fop.util.UnitConv;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFField;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
-import org.apache.xmlgraphics.image.codec.util.SeekableStream;
/**
* Image preloader for TIFF images.
@@ -49,7 +50,7 @@
/** {@inheritDoc}
* @throws ImageException */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
@@ -77,8 +78,8 @@
}
if (supported) {
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
- info.setSize(determineSize(in, userAgent));
+ ImageInfo info = new ImageInfo(uri, getMimeType());
+ info.setSize(determineSize(in, context));
return info;
} else {
return null;
@@ -90,7 +91,7 @@
return MimeConstants.MIME_TIFF;
}
- private ImageSize determineSize(ImageInputStream in, FOUserAgent userAgent)
+ private ImageSize determineSize(ImageInputStream in, ImageContext context)
throws IOException, ImageException {
in.mark();
@@ -110,7 +111,7 @@
TIFFField fldy = dir.getField(TIFFImageDecoder.TIFF_Y_RESOLUTION);
if (fldx == null || fldy == null) {
unit = 2;
- xRes = userAgent.getSourceResolution();
+ xRes = context.getSourceResolution();
yRes = xRes;
} else {
xRes = fldx.getAsFloat(0);
@@ -124,7 +125,7 @@
UnitConv.in2mm(yRes) / 10); //Centimeters
}
} else {
- size.setResolution(userAgent.getSourceResolution());
+ size.setResolution(context.getSourceResolution());
}
size.calcSizeFromPixels();
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderSVG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderSVG.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderSVG.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderSVG.java Tue Dec 4 02:27:51 2007
@@ -23,11 +23,13 @@
import java.util.Map;
import org.apache.batik.dom.svg.SVGDOMImplementation;
+
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.image2.Image;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
+import org.apache.fop.image2.ImageSessionContext;
import org.apache.fop.image2.impl.AbstractImageLoader;
import org.apache.fop.image2.impl.ImageXMLDOM;
@@ -55,7 +57,8 @@
}
/** {@inheritDoc} */
- public Image loadImage(ImageInfo info, Map hints) throws ImageException, IOException {
+ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
+ throws ImageException, IOException {
if (!MimeConstants.MIME_SVG.equals(info.getMimeType())) {
throw new IllegalArgumentException("ImageInfo must be from an SVG image");
}
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderWMF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderWMF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderWMF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageLoaderWMF.java Tue Dec 4 02:27:51 2007
@@ -26,6 +26,7 @@
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
+import org.apache.fop.image2.ImageSessionContext;
import org.apache.fop.image2.impl.AbstractImageLoader;
/**
@@ -52,7 +53,8 @@
}
/** {@inheritDoc} */
- public Image loadImage(ImageInfo info, Map hints) throws ImageException, IOException {
+ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
+ throws ImageException, IOException {
if (!ImageWMF.MIME_WMF.equals(info.getMimeType())) {
throw new IllegalArgumentException("ImageInfo must be from a WMF image");
}
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageWMF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageWMF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageWMF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/ImageWMF.java Tue Dec 4 02:27:51 2007
@@ -20,6 +20,7 @@
package org.apache.fop.image2.impl.batik;
import org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore;
+
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.impl.AbstractImage;
@@ -52,6 +53,11 @@
return WMF_IMAGE;
}
+ /** {@inheritDoc} */
+ public boolean isCacheable() {
+ return true;
+ }
+
/**
* Returns the contained WMF record store.
* @return the WMFRecordStore
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderSVG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderSVG.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderSVG.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderSVG.java Tue Dec 4 02:27:51 2007
@@ -25,6 +25,9 @@
import javax.xml.transform.Source;
+import org.w3c.dom.Element;
+import org.w3c.dom.svg.SVGDocument;
+
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
@@ -32,9 +35,10 @@
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.apps.FOUserAgent;
+
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.image.XMLImage;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
import org.apache.fop.image2.impl.AbstractImagePreloader;
@@ -43,8 +47,6 @@
import org.apache.fop.svg.SVGUserAgent;
import org.apache.fop.util.UnclosableInputStream;
import org.apache.fop.util.UnitConv;
-import org.w3c.dom.Element;
-import org.w3c.dom.svg.SVGDocument;
/**
* Image preloader for SVG images.
@@ -57,7 +59,7 @@
private boolean batikAvailable = true;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException {
if (!ImageUtil.hasInputStream(src)) {
//TODO Remove this and support DOMSource and possibly SAXSource
@@ -67,7 +69,7 @@
if (batikAvailable) {
try {
Loader loader = new Loader();
- return loader.getImage(uri, src, userAgent);
+ info = loader.getImage(uri, src, context);
} catch (NoClassDefFoundError e) {
batikAvailable = false;
log.warn("Batik not in class path", e);
@@ -92,7 +94,7 @@
*/
class Loader {
private ImageInfo getImage(String uri, Source src,
- FOUserAgent userAgent) {
+ ImageContext context) {
// parse document and get the size attributes of the svg element
InputStream in = new UnclosableInputStream(ImageUtil.needInputStream(src));
@@ -127,11 +129,11 @@
int height = Math.round(UnitProcessor.svgVerticalLengthToUserSpace(
s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx));
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
+ ImageInfo info = new ImageInfo(uri, getMimeType());
ImageSize size = new ImageSize();
size.setSizeInMillipoints(width, height);
//Set the resolution to that of the FOUserAgent
- size.setResolution(userAgent.getSourceResolution());
+ size.setResolution(context.getSourceResolution());
size.calcPixelsFromSize();
info.setSize(size);
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderWMF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderWMF.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderWMF.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderWMF.java Tue Dec 4 02:27:51 2007
@@ -31,7 +31,8 @@
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.apps.FOUserAgent;
+
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageInfo;
import org.apache.fop.image2.ImageSize;
import org.apache.fop.image2.impl.AbstractImagePreloader;
@@ -49,7 +50,7 @@
private boolean batikAvailable = true;
/** {@inheritDoc} */
- public ImageInfo preloadImage(String uri, Source src, FOUserAgent userAgent)
+ public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException {
if (!ImageUtil.hasInputStream(src)) {
return null;
@@ -58,7 +59,7 @@
if (batikAvailable) {
try {
Loader loader = new Loader();
- return loader.getImage(uri, src, userAgent);
+ info = loader.getImage(uri, src, context);
} catch (NoClassDefFoundError e) {
batikAvailable = false;
log.warn("Batik not in class path", e);
@@ -83,7 +84,7 @@
*/
class Loader {
private ImageInfo getImage(String uri, Source src,
- FOUserAgent userAgent) {
+ ImageContext context) {
// parse document and get the size attributes of the svg element
InputStream in = new UnclosableInputStream(ImageUtil.needInputStream(src));
@@ -105,7 +106,7 @@
int height = wmfStore.getHeightUnits();
int dpi = wmfStore.getMetaFileUnitsPerInch();
- ImageInfo info = new ImageInfo(uri, src, getMimeType());
+ ImageInfo info = new ImageInfo(uri, getMimeType());
ImageSize size = new ImageSize();
size.setSizeInPixels(width, height);
size.setResolution(dpi);
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/imageio/ImageLoaderImageIO.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/imageio/ImageLoaderImageIO.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/imageio/ImageLoaderImageIO.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/imageio/ImageLoaderImageIO.java Tue Dec 4 02:27:51 2007
@@ -28,11 +28,13 @@
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
+import javax.xml.transform.Source;
import org.apache.fop.image2.Image;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
+import org.apache.fop.image2.ImageSessionContext;
import org.apache.fop.image2.impl.AbstractImageLoader;
import org.apache.fop.image2.impl.ImageBuffered;
import org.apache.fop.image2.impl.ImageRendered;
@@ -63,8 +65,10 @@
}
/** {@inheritDoc} */
- public Image loadImage(ImageInfo info, Map hints) throws ImageException, IOException {
- ImageInputStream imgStream = ImageUtil.needImageInputStream(info.getSource());
+ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
+ throws ImageException, IOException {
+ Source src = session.needSource(info.getOriginalURI());
+ ImageInputStream imgStream = ImageUtil.needImageInputStream(src);
Iterator iter = ImageIO.getImageReaders(imgStream);
if (!iter.hasNext()) {
throw new ImageException("No ImageIO ImageReader found .");
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.pipeline;
+
+import org.apache.fop.image2.spi.ImageConverter;
+import org.apache.fop.util.dijkstra.Edge;
+import org.apache.fop.util.dijkstra.Vertex;
+
+/**
+ * Represents an image conversion. The class basically wraps an ImageConverter so it can be
+ * used with Dijkstra's shortest route algorithm to build image conversion pipelines.
+ */
+public class ImageConversionEdge implements Edge {
+
+ private ImageRepresentation source;
+ private ImageRepresentation target;
+ private ImageConverter converter;
+
+ /**
+ * Main constructor.
+ * @param converter the image converter
+ */
+ public ImageConversionEdge(
+ ImageConverter converter) {
+ this.converter = converter;
+ this.source = new ImageRepresentation(converter.getSourceFlavor());
+ this.target = new ImageRepresentation(converter.getTargetFlavor());
+ }
+
+ /**
+ * Returns the wrapped ImageConverter.
+ * @return the ImageConverter
+ */
+ public ImageConverter getImageConverter() {
+ return this.converter;
+ }
+
+ /** {@inheritDoc} */
+ public int getPenalty() {
+ return getImageConverter().getConversionPenalty();
+ }
+
+ /** {@inheritDoc} */
+ public Vertex getStart() {
+ return this.source;
+ }
+
+ /** {@inheritDoc} */
+ public Vertex getEnd() {
+ return this.target;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageConversionEdge.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.pipeline;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.image2.Image;
+import org.apache.fop.image2.ImageException;
+import org.apache.fop.image2.ImageFlavor;
+import org.apache.fop.image2.ImageInfo;
+import org.apache.fop.image2.ImageSessionContext;
+import org.apache.fop.image2.cache.ImageCache;
+import org.apache.fop.image2.impl.ImageRawStream;
+import org.apache.fop.image2.spi.ImageConverter;
+import org.apache.fop.image2.spi.ImageLoader;
+
+/**
+ * Represents a pipeline of ImageConverters with an ImageLoader at the beginning of the
+ * pipeline.
+ */
+public class ImageProviderPipeline {
+
+ /** logger */
+ protected static Log log = LogFactory.getLog(ImageProviderPipeline.class);
+
+ private ImageCache cache;
+ private ImageLoader loader;
+ private List converters = new java.util.ArrayList();
+
+ /**
+ * Main constructor.
+ * @param cache the image cache (may be null if no caching is desired)
+ * @param loader the image loader to drive the pipeline with
+ */
+ public ImageProviderPipeline(ImageCache cache, ImageLoader loader) {
+ this.cache = cache;
+ this.loader = loader;
+ }
+
+ /**
+ * Constructor for operation without caching.
+ * @param loader the image loader to drive the pipeline with
+ */
+ public ImageProviderPipeline(ImageLoader loader) {
+ this(null, loader);
+ }
+
+ /**
+ * Executes the image converter pipeline. First, the image indicated by the ImageInfo instance
+ * is loaded through an ImageLoader and then optionally converted by a series of
+ * ImageConverters. At the end of the pipeline, the fully loaded and converted image is
+ * returned.
+ * @param info the image info object indicating the image to load
+ * @param hints a Map of image conversion hints
+ * @param context the session context
+ * @return the requested image
+ * @throws ImageException if an error occurs while loader or converting the image
+ * @throws IOException if an I/O error occurs
+ */
+ public Image execute(ImageInfo info, Map hints, ImageSessionContext context)
+ throws ImageException, IOException {
+ long start, duration;
+ start = System.currentTimeMillis();
+ Image img = null;
+
+ //Remember the last image in the pipeline that is cacheable and cache that.
+ Image lastCacheableImage = null;
+
+ int converterCount = converters.size();
+ int startingPoint = 0;
+ if (cache != null) {
+ for (int i = converterCount - 1; i >= 0; i--) {
+ ImageConverter converter = (ImageConverter)converters.get(i);
+ ImageFlavor flavor = converter.getTargetFlavor();
+ img = cache.getImage(info, flavor);
+ if (img != null) {
+ startingPoint = i + 1;
+ break;
+ }
+ }
+
+ if (img == null) {
+ //try target flavor of loader from cache
+ ImageFlavor flavor = loader.getTargetFlavor();
+ img = cache.getImage(info, flavor);
+ }
+ }
+
+ boolean entirelyInCache = true;
+ if (img == null) {
+ //Load image
+ img = loader.loadImage(info, hints, context);
+ if (log.isTraceEnabled()) {
+ duration = System.currentTimeMillis() - start;
+ log.trace("Image loading using " + loader + " took " + duration + " ms.");
+ }
+
+ //Caching
+ entirelyInCache = false;
+ if (img.isCacheable()) {
+ lastCacheableImage = img;
+ }
+ }
+
+ if (converterCount > 0) {
+ for (int i = startingPoint; i < converterCount; i++) {
+ ImageConverter converter = (ImageConverter)converters.get(i);
+ start = System.currentTimeMillis();
+ img = converter.convert(img, hints);
+ if (log.isTraceEnabled()) {
+ duration = System.currentTimeMillis() - start;
+ log.trace("Image conversion using " + converter + " took " + duration + " ms.");
+ }
+
+ //Caching
+ entirelyInCache = false;
+ if (img.isCacheable()) {
+ lastCacheableImage = img;
+ }
+ }
+ }
+
+ //Note: Currently we just cache the end result of the pipeline, not all intermediate
+ //results as it is expected that the cache hit ration would be rather small.
+ if (cache != null && !entirelyInCache) {
+ if (lastCacheableImage == null) {
+ //Try to make the Image cacheable
+ lastCacheableImage = forceCaching(img);
+ }
+ if (lastCacheableImage != null) {
+ if (log.isTraceEnabled()) {
+ log.trace("Caching image: " + lastCacheableImage);
+ }
+ cache.putImage(lastCacheableImage);
+ }
+ }
+ return img;
+ }
+
+ /**
+ * In some cases the provided Image is not cacheable, nor is any of the intermediate Image
+ * instances (for example, when loading a raw JPEG file). If the image is loaded over a
+ * potentially slow network, it is preferrable to download the whole file and cache it
+ * in memory or in a temporary file. It's not always possible to convert an Image into a
+ * cacheable variant.
+ * @param img the Image to investigate
+ * @return the converted, cacheable Image or null if the Image cannot be converted
+ * @throws IOException if an I/O error occurs
+ */
+ protected Image forceCaching(Image img) throws IOException {
+ if (img instanceof ImageRawStream) {
+ ImageRawStream raw = (ImageRawStream)img;
+ if (log.isDebugEnabled()) {
+ log.debug("Image is made cacheable: " + img.getInfo());
+ }
+
+ //Read the whole stream and hold it in memory so the image can be cached
+ ByteArrayOutputStream baout = new ByteArrayOutputStream();
+ InputStream in = raw.createInputStream();
+ try {
+ IOUtils.copy(in, baout);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ final byte[] data = baout.toByteArray();
+
+ raw.setInputStreamFactory(new ImageRawStream.InputStreamFactory() {
+
+ public void close() {
+ //nop
+ }
+
+ public InputStream createInputStream() {
+ return new ByteArrayInputStream(data);
+ }
+
+ public boolean isUsedOnceOnly() {
+ return false;
+ }
+
+ });
+ return raw;
+ }
+ return null;
+ }
+
+ /**
+ * Adds an additional ImageConverter to the end of the pipeline.
+ * @param converter the ImageConverter instance
+ */
+ public void addConverter(ImageConverter converter) {
+ //TODO check for compatibility
+ this.converters.add(converter);
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Loader: ").append(loader);
+ if (converters.size() > 0) {
+ sb.append(" Converters: ");
+ sb.append(converters);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns the overall conversion penalty for the pipeline. This can be used to choose among
+ * different possible pipelines.
+ * @return the overall penalty (a non-negative integer)
+ */
+ public int getConversionPenalty() {
+ int penalty = 0;
+ penalty += loader.getUsagePenalty();
+ Iterator iter = converters.iterator();
+ while (iter.hasNext()) {
+ ImageConverter converter = (ImageConverter)iter.next();
+ penalty += converter.getConversionPenalty();
+ }
+ return penalty;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.pipeline;
+
+import org.apache.fop.image2.ImageFlavor;
+import org.apache.fop.util.dijkstra.Vertex;
+
+/**
+ * This class represents a combination of MIME type and an image flavor.
+ * It is used in conjunction with Dijkstra's algorithm to find and construct a
+ * conversion pipeline for images.
+ */
+public class ImageRepresentation implements Vertex {
+
+ private ImageFlavor flavor;
+
+ /**
+ * Main constructor
+ * @param flavor the image flavor
+ */
+ public ImageRepresentation(ImageFlavor flavor) {
+ this.flavor = flavor;
+ }
+
+ /**
+ * Returns the image flavor.
+ * @return the image flavor
+ */
+ public ImageFlavor getFlavor() {
+ return flavor;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals(Object obj) {
+ return toString().equals(((ImageRepresentation)obj).toString());
+ }
+
+ /** {@inheritDoc} */
+ public int hashCode() {
+ return getFlavor().hashCode();
+ }
+
+ /** {@inheritDoc} */
+ public int compareTo(Object obj) {
+ return toString().compareTo(((ImageRepresentation)obj).toString());
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return getFlavor().toString();
+ }
+
+}
\ No newline at end of file
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageRepresentation.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.pipeline;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.image2.ImageFlavor;
+import org.apache.fop.image2.ImageManager;
+import org.apache.fop.image2.spi.ImageConverter;
+import org.apache.fop.image2.spi.ImageImplRegistry;
+import org.apache.fop.image2.spi.ImageLoader;
+import org.apache.fop.image2.spi.ImageLoaderFactory;
+import org.apache.fop.util.dijkstra.DefaultEdgeDirectory;
+import org.apache.fop.util.dijkstra.DijkstraAlgorithm;
+import org.apache.fop.util.dijkstra.Vertex;
+
+/**
+ * Factory class for image processing pipelines.
+ */
+public class PipelineFactory {
+
+ /** logger */
+ protected static Log log = LogFactory.getLog(PipelineFactory.class);
+
+ private ImageManager manager;
+
+ private int converterEdgeDirectoryVersion = -1;
+
+ /** Holds the EdgeDirectory for all image conversions */
+ private DefaultEdgeDirectory converterEdgeDirectory;
+
+ /**
+ * Main constructor.
+ * @param manager the ImageManager instance
+ */
+ public PipelineFactory(ImageManager manager) {
+ this.manager = manager;
+ }
+
+ private DefaultEdgeDirectory getEdgeDirectory() {
+ ImageImplRegistry registry = manager.getRegistry();
+ if (registry.getImageConverterModifications() != converterEdgeDirectoryVersion) {
+ Collection converters = registry.getImageConverters();
+
+ //Rebuild edge directory
+ DefaultEdgeDirectory dir = new DefaultEdgeDirectory();
+ Iterator iter = converters.iterator();
+ while (iter.hasNext()) {
+ ImageConverter converter = (ImageConverter)iter.next();
+ dir.addEdge(new ImageConversionEdge(converter));
+ }
+
+ converterEdgeDirectoryVersion = registry.getImageConverterModifications();
+ this.converterEdgeDirectory = dir; //Replace (thread-safe)
+ }
+ return this.converterEdgeDirectory;
+ }
+
+ /**
+ * Creates and returns an ImageConverterPipeline that allows to load an image of the given
+ * MIME type and present it in the requested image flavor.
+ * @param originalMime the MIME type of the original image
+ * @param targetFlavor the requested image flavor
+ * @return an ImageConverterPipeline or null if no suitable pipeline could be assembled
+ */
+ public ImageProviderPipeline newImageConverterPipeline(
+ String originalMime, ImageFlavor targetFlavor) {
+ ImageImplRegistry registry = manager.getRegistry();
+ ImageProviderPipeline pipeline = null;
+
+ //Get snapshot to avoid concurrent modification problems (thread-safety)
+ DefaultEdgeDirectory dir = getEdgeDirectory();
+
+ ImageLoaderFactory loaderFactory = registry.getImageLoaderFactory(
+ originalMime, targetFlavor);
+ if (loaderFactory != null) {
+ //Directly load image and return it
+ ImageLoader loader = loaderFactory.newImageLoader(targetFlavor);
+ pipeline = new ImageProviderPipeline(manager.getCache(), loader);
+ } else {
+ //Need to use ImageConverters
+ if (log.isDebugEnabled()) {
+ log.debug("No ImageLoaderFactory found that can load this format directly."
+ + " Trying ImageConverters instead...");
+ }
+
+ ImageRepresentation destination = new ImageRepresentation(targetFlavor);
+ //Get Loader for originalMIME
+ // --> List of resulting flavors, possibly multiple loaders
+ ImageLoaderFactory[] loaderFactories = registry.getImageLoaderFactories(originalMime);
+ if (loaderFactories != null) {
+ //Find best pipeline -> best loader
+ for (int i = 0, ci = loaderFactories.length; i < ci; i++) {
+ loaderFactory = loaderFactories[i];
+ ImageFlavor[] flavors = loaderFactory.getSupportedFlavors(originalMime);
+ for (int j = 0, cj = flavors.length; j < cj; j++) {
+ DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(
+ dir);
+ ImageRepresentation origin = new ImageRepresentation(flavors[j]);
+ dijkstra.execute(origin, destination);
+ if (log.isDebugEnabled()) {
+ log.debug("Lowest penalty: " + dijkstra.getLowestPenalty(destination));
+ }
+
+ Vertex prev = destination;
+ Vertex pred = dijkstra.getPredecessor(destination);
+ if (pred == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("No route found!");
+ }
+ } else {
+ LinkedList stops = new LinkedList();
+ //stops.addLast(destination);
+ while ((pred = dijkstra.getPredecessor(prev)) != null) {
+ ImageConversionEdge edge = (ImageConversionEdge)
+ dir.getBestEdge(pred, prev);
+ stops.addFirst(edge);
+ prev = pred;
+ }
+ ImageLoader loader = loaderFactory.newImageLoader(flavors[i]);
+ pipeline = new ImageProviderPipeline(manager.getCache(), loader);
+ Iterator iter = stops.iterator();
+ while (iter.hasNext()) {
+ ImageConversionEdge edge = (ImageConversionEdge)iter.next();
+ pipeline.addConverter(edge.getImageConverter());
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Pipeline: " + pipeline);
+ }
+ return pipeline;
+ }
+ }
+ }
+
+ //Build final pipeline
+
+ }
+
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Pipeline: " + pipeline);
+ }
+ return pipeline;
+ }
+
+}
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageImplRegistry.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageImplRegistry.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageImplRegistry.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageImplRegistry.java Tue Dec 4 02:27:51 2007
@@ -19,8 +19,9 @@
package org.apache.fop.image2.spi;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,9 +31,6 @@
import org.apache.xmlgraphics.util.Service;
import org.apache.fop.image2.ImageFlavor;
-import org.apache.fop.util.dijkstra.DefaultEdgeDirectory;
-import org.apache.fop.util.dijkstra.DijkstraAlgorithm;
-import org.apache.fop.util.dijkstra.Vertex;
/**
* This class is the registry for all implementations of the various service provider interfaces
@@ -55,8 +53,7 @@
private List converters = new java.util.ArrayList();
//Content: List<ImageConverter>
- /** Holds the EdgeDirectory for all image conversions */
- private DefaultEdgeDirectory converterEdgeDirectory = new DefaultEdgeDirectory();
+ private int converterModifications;
/** Singleton instance */
private static ImageImplRegistry defaultInstance;
@@ -159,12 +156,29 @@
}
/**
+ * Returns the Collection of registered ImageConverter instances.
+ * @return a Collection<ImageConverter>
+ */
+ public Collection getImageConverters() {
+ return Collections.unmodifiableList(this.converters);
+ }
+
+ /**
+ * Returns the number of modifications to the collection of registered ImageConverter instances.
+ * This is used to detect changes in the registry concerning ImageConverters.
+ * @return the number of modifications
+ */
+ public int getImageConverterModifications() {
+ return this.converterModifications;
+ }
+
+ /**
* Registers a new ImageConverter.
* @param converter An ImageConverter instance
*/
public void registerConverter(ImageConverter converter) {
converters.add(converter);
- converterEdgeDirectory.addEdge(new ImageConversionEdge(converter));
+ converterModifications++;
if (log.isDebugEnabled()) {
log.debug("Registered: " + converter.getClass().getName());
}
@@ -207,7 +221,13 @@
return null;
}
- private ImageLoaderFactory[] getImageLoaderFactories(String mime) {
+ /**
+ * Returns an array of ImageLoaderFactory instances which support the given MIME type. The
+ * instances are returned in no particular order.
+ * @param mime the MIME type to find ImageLoaderFactories for
+ * @return the array of ImageLoaderFactory instances
+ */
+ public ImageLoaderFactory[] getImageLoaderFactories(String mime) {
Map flavorMap = (Map)loaders.get(mime);
if (flavorMap != null) {
Set factories = new java.util.HashSet();
@@ -223,87 +243,6 @@
}
}
return null;
- }
-
- /**
- * Creates and returns an ImageConverterPipeline that allows to load an image of the given
- * MIME type and present it in the requested image flavor.
- * @param originalMime the MIME type of the original image
- * @param targetFlavor the requested image flavor
- * @return an ImageConverterPipeline or null if no suitable pipeline could be assembled
- */
- public ImageConverterPipeline newImageConverterPipeline(
- String originalMime, ImageFlavor targetFlavor) {
- ImageConverterPipeline pipeline = null;
- ImageLoaderFactory loaderFactory = getImageLoaderFactory(originalMime, targetFlavor);
- if (loaderFactory != null) {
- //Directly load image and return it
- ImageLoader loader = loaderFactory.newImageLoader(targetFlavor);
- pipeline = new ImageConverterPipeline(loader);
- } else {
- //Need to use ImageConverters
- if (log.isDebugEnabled()) {
- log.debug("No ImageLoaderFactory found that can load this format directly."
- + " Trying ImageConverters instead...");
- }
-
- ImageRepresentation destination = new ImageRepresentation(targetFlavor);
- //Get Loader for originalMIME
- // --> List of resulting flavors, possibly multiple loaders
- ImageLoaderFactory[] loaderFactories = getImageLoaderFactories(originalMime);
- if (loaderFactories != null) {
- //Find best pipeline -> best loader
- for (int i = 0, ci = loaderFactories.length; i < ci; i++) {
- loaderFactory = loaderFactories[i];
- ImageFlavor[] flavors = loaderFactory.getSupportedFlavors(originalMime);
- for (int j = 0, cj = flavors.length; j < cj; j++) {
- DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(
- this.converterEdgeDirectory);
- ImageRepresentation origin = new ImageRepresentation(flavors[j]);
- dijkstra.execute(origin, destination);
- if (log.isDebugEnabled()) {
- log.debug("Lowest penalty: " + dijkstra.getLowestPenalty(destination));
- }
-
- Vertex prev = destination;
- Vertex pred = dijkstra.getPredecessor(destination);
- if (pred == null) {
- if (log.isDebugEnabled()) {
- log.debug("No route found!");
- }
- } else {
- LinkedList stops = new LinkedList();
- //stops.addLast(destination);
- while ((pred = dijkstra.getPredecessor(prev)) != null) {
- ImageConversionEdge edge = (ImageConversionEdge)
- this.converterEdgeDirectory.getBestEdge(pred, prev);
- stops.addFirst(edge);
- prev = pred;
- }
- ImageLoader loader = loaderFactory.newImageLoader(flavors[i]);
- pipeline = new ImageConverterPipeline(loader);
- Iterator iter = stops.iterator();
- while (iter.hasNext()) {
- ImageConversionEdge edge = (ImageConversionEdge)iter.next();
- pipeline.addConverter(edge.getImageConverter());
- }
- if (log.isDebugEnabled()) {
- log.debug("Pipeline: " + pipeline);
- }
- return pipeline;
- }
- }
- }
-
- //Build final pipeline
-
- }
-
- }
- if (log.isDebugEnabled()) {
- log.debug("Pipeline: " + pipeline);
- }
- return pipeline;
}
}
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageLoader.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageLoader.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImageLoader.java Tue Dec 4 02:27:51 2007
@@ -26,6 +26,7 @@
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageFlavor;
import org.apache.fop.image2.ImageInfo;
+import org.apache.fop.image2.ImageSessionContext;
/**
* This interface is implemented by classes which load images from a source. Normally, such a
@@ -38,20 +39,24 @@
* @param info the image info object indicating the image
* @param hints a Map of hints that can be used by implementations to customize the loading
* process.
+ * @param session the session context
* @return the fully loaded image
* @throws ImageException if an error occurs while loading the image
* @throws IOException if an I/O error occurs while loading the image
*/
- Image loadImage(ImageInfo info, Map hints) throws ImageException, IOException;
+ Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
+ throws ImageException, IOException;
/**
* Loads and returns an image.
* @param info the image info object indicating the image
+ * @param session the session context
* @return the fully loaded image
* @throws ImageException if an error occurs while loading the image
* @throws IOException if an I/O error occurs while loading the image
*/
- Image loadImage(ImageInfo info) throws ImageException, IOException;
+ Image loadImage(ImageInfo info, ImageSessionContext session)
+ throws ImageException, IOException;
/**
* Returns the image flavor that is returned by this ImageLoader implementation.
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImagePreloader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImagePreloader.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImagePreloader.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImagePreloader.java Tue Dec 4 02:27:51 2007
@@ -23,7 +23,7 @@
import javax.xml.transform.Source;
-import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.image2.ImageContext;
import org.apache.fop.image2.ImageException;
import org.apache.fop.image2.ImageInfo;
@@ -40,13 +40,13 @@
* information. The image is usually not fully loaded at this time to conserve memory.
* @param originalURI the original (unresolved) URI of the image
* @param src a image source the image is loaded from
- * @param userAgent the user agent providing context and configuration information
+ * @param context the context object that provides configuration information
* @return an image info object with the basic information about an image
* @throws ImageException if an error occurs while preloading the image
* @throws IOException if an I/O error occurs while preloading the image
*/
ImageInfo preloadImage(String originalURI,
- Source src, FOUserAgent userAgent) throws ImageException, IOException;
+ Source src, ImageContext context) throws ImageException, IOException;
/**
* Returns the MIME type supported by the image preloader.
Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/ImageUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/ImageUtil.java?rev=600870&r1=600869&r2=600870&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/ImageUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/ImageUtil.java Tue Dec 4 02:27:51 2007
@@ -33,8 +33,8 @@
import org.apache.commons.io.IOUtils;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.image2.ImageProcessingHints;
+import org.apache.fop.image2.ImageSessionContext;
import org.apache.fop.image2.ImageSource;
/**
@@ -94,9 +94,13 @@
* @return the ImageInputStream
*/
public static ImageInputStream needImageInputStream(Source src) {
- ImageInputStream in = getImageInputStream(src);
- if (in != null) {
- return in;
+ if (src instanceof ImageSource) {
+ ImageSource isrc = (ImageSource)src;
+ if (isrc.getImageInputStream() == null) {
+ throw new IllegalArgumentException(
+ "ImageInputStream is null/cleared on ImageSource");
+ }
+ return isrc.getImageInputStream();
} else {
throw new IllegalArgumentException("Source must be an ImageSource");
}
@@ -134,12 +138,42 @@
}
/**
+ * Removes any references to InputStreams or Readers from the given ImageInfo's Source
+ * to prohibit accidental/unwanted use by a component further downstream.
+ * @param info the ImageInfo object
+ *//*
+ public static void removeStreams(ImageInfo info) {
+ //Synchronize to avoid concurrent tampering with the Source
+ synchronized (info) {
+ removeStreams(info.getSource());
+ }
+ }*/
+
+ /**
+ * Removes any references to InputStreams or Readers from the given Source to prohibit
+ * accidental/unwanted use by a component further downstream.
+ * @param src the Source object
+ */
+ public static void removeStreams(Source src) {
+ if (src instanceof ImageSource) {
+ ImageSource isrc = (ImageSource)src;
+ isrc.setImageInputStream(null);
+ } else if (src instanceof StreamSource) {
+ StreamSource ssrc = (StreamSource)src;
+ ssrc.setInputStream(null);
+ ssrc.setReader(null);
+ }
+ }
+
+ /**
* Closes the InputStreams or ImageInputStreams of Source objects. Any exception occurring
* while closing the stream is ignored.
* @param src the Source object
*/
public static void closeQuietly(Source src) {
- if (src instanceof StreamSource) {
+ if (src == null) {
+ return;
+ } else if (src instanceof StreamSource) {
StreamSource streamSource = (StreamSource)src;
IOUtils.closeQuietly(streamSource.getInputStream());
streamSource.setInputStream(null);
@@ -156,7 +190,7 @@
imageSource.setImageInputStream(null);
}
} else {
- throw new IllegalArgumentException("Source not supported!");
+ throw new IllegalArgumentException("Source not supported: " + src.getClass().getName());
}
}
@@ -237,17 +271,15 @@
/**
* Creates a new hint Map with values from the FOUserAgent.
- * @param userAgent the user agent
+ * @param session the session context
* @return a Map of hints
*/
- public static Map getDefaultHints(FOUserAgent userAgent) {
- //TODO Maybe remove the reference to FOUserAgent from the image package completely.
- //This could improve the usefulness of the package for external projects.
+ public static Map getDefaultHints(ImageSessionContext session) {
java.util.Map hints = new java.util.HashMap();
hints.put(ImageProcessingHints.SOURCE_RESOLUTION,
- new Float(userAgent.getSourceResolution()));
+ new Float(session.getParentContext().getSourceResolution()));
hints.put(ImageProcessingHints.TARGET_RESOLUTION,
- new Float(userAgent.getTargetResolution()));
+ new Float(session.getTargetResolution()));
return hints;
}
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.util;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Provides a simple cache using soft references and storing the values in a Map. The keys into
+ * the Map are hard references, the values are referenced through soft references. The collected
+ * values are cleaned up through a ReferenceQueue.
+ */
+public class SoftMapCache {
+
+ /** logger */
+ private static Log log = LogFactory.getLog(SoftMapCache.class);
+
+ private Map map;
+ private ReferenceQueue refQueue = new ReferenceQueue();
+
+ /**
+ * Creates a new soft cache.
+ * @param synched true if the Map containing the values should by synchronized
+ */
+ public SoftMapCache(boolean synched) {
+ this.map = new java.util.HashMap();
+ if (synched) {
+ this.map = Collections.synchronizedMap(this.map);
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key. If the value is not found or the value
+ * has been collected, null is returned.
+ * @param key the key
+ * @return the requested value or null
+ */
+ public Object get(Object key) {
+ Reference ref = (Reference)map.get(key);
+ return getReference(key, ref);
+ }
+
+ /**
+ * Removed the value associated with the given key. The value that is removed is returned
+ * as the methods result. If the value is not found or the value has been collected,
+ * null is returned.
+ * @param key the key
+ * @return the requested value or null
+ */
+ public Object remove(Object key) {
+ Reference ref = (Reference)map.remove(key);
+ return getReference(key, ref);
+ }
+
+ private Object getReference(Object key, Reference ref) {
+ Object value = null;
+ if (ref != null) {
+ value = ref.get();
+ if (value == null) {
+ //Remove key if its value has been garbage collected
+ if (log.isTraceEnabled()) {
+ log.trace("Image has been collected: " + key);
+ }
+ checkReferenceQueue();
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Put a new value in the cache overwriting any existing value with the same key.
+ * @param key The key
+ * @param value the value
+ */
+ public void put(Object key, Object value) {
+ map.put(key, wrapInReference(value, key));
+ }
+
+ /**
+ * Clears the cache.
+ */
+ public void clear() {
+ map.clear();
+ }
+
+ /**
+ * Triggers some house-keeping, i.e. processes any pending objects in the reference queue.
+ */
+ public void doHouseKeeping() {
+ checkReferenceQueue();
+ }
+
+ private Reference wrapInReference(Object obj, Object key) {
+ return new SoftReferenceWithKey(obj, key, refQueue);
+ }
+
+ /**
+ * Checks the reference queue if any references have been cleared and removes them from the
+ * cache.
+ */
+ private void checkReferenceQueue() {
+ SoftReferenceWithKey ref;
+ while ((ref = (SoftReferenceWithKey)refQueue.poll()) != null) {
+ if (log.isTraceEnabled()) {
+ log.trace("Removing ImageInfo from ref queue: " + ref.getKey());
+ }
+ map.remove(ref.getKey());
+ }
+ }
+}
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftMapCache.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java?rev=600870&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java Tue Dec 4 02:27:51 2007
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image2.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+
+/**
+ * Special SoftReference subclass that holds an additional key object that can be used to remove
+ * a reference from a Map once the referenced object is collected, for example.
+ */
+public class SoftReferenceWithKey extends SoftReference {
+
+ private Object key;
+
+ /**
+ * Creates a new SoftReference with a key.
+ * @param referent object the new soft reference will refer to
+ * @param key the key object
+ * @param q queue the soft reference is registered with
+ */
+ public SoftReferenceWithKey(Object referent, Object key, ReferenceQueue q) {
+ super(referent, q);
+ this.key = key;
+ }
+
+ /**
+ * Returns the key associated with this reference.
+ * @return the key
+ */
+ public Object getKey() {
+ return this.key;
+ }
+
+}
\ No newline at end of file
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/util/SoftReferenceWithKey.java
------------------------------------------------------------------------------
svn:keywords = Id
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org