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