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/08 11:36:33 UTC

svn commit: r602442 - in /xmlgraphics/fop/branches/Temp_ImagePackageRedesign: src/java/org/apache/fop/image2/ src/java/org/apache/fop/image2/cache/ src/java/org/apache/fop/image2/impl/ src/java/org/apache/fop/image2/impl/batik/ src/java/org/apache/fop/...

Author: jeremias
Date: Sat Dec  8 02:36:32 2007
New Revision: 602442

URL: http://svn.apache.org/viewvc?rev=602442&view=rev
Log:
Support handling images with no associated URI (from instream-foreign-object). These images are not cached.
Add support for plain image conversion (i.e. with no loading) for instream-foreign-object.
Add convenience writeTo() methods in ImageRawStream to save a few lines of code.

Support for instream-foreign-object in RTF output.
Teach RTF library to handle images without an associated URL.

Added:
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java   (with props)
Modified:
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/ImageManager.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/cache/ImageCache.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/AbstractImage.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/ImageRawStream.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/batik/PreloaderSVG.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/spi/ImagePreloader.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/ps/PSRenderer.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/RTFHandler.java
    xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/ImageManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/ImageManager.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/ImageManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/ImageManager.java Sat Dec  8 02:36:32 2007
@@ -236,18 +236,8 @@
         for (int i = 0; i < count; i++) {
             candidates[i] = getPipelineFactory().newImageConverterPipeline(mime, flavors[i]);
         }
-        ImageProviderPipeline pipeline = null;
-        int minPenalty = Integer.MAX_VALUE;
-        for (int i = count - 1; i >= 0; i--) {
-            if (candidates[i] == null) {
-                continue;
-            }
-            int penalty = candidates[i].getConversionPenalty();
-            if (penalty <= minPenalty) {
-                pipeline = candidates[i];
-                minPenalty = penalty;
-            }
-        }    
+        ImageProviderPipeline pipeline = choosePipeline(candidates);
+        
         if (pipeline != null) {
             img = pipeline.execute(info, hints, session);
         }
@@ -294,6 +284,86 @@
     public Image getImage(ImageInfo info, ImageFlavor[] flavors, ImageSessionContext session)
             throws ImageException, IOException {
         return getImage(info, flavors, ImageUtil.getDefaultHints(session), session);
+    }
+    
+    /**
+     * Converts an image. The caller can indicate what kind of image flavors are requested. When
+     * this method is called the code looks for a suitable combination of ImageConverters so it
+     * can return the image in exactly the form the caller needs.
+     * The array of image flavors is ordered, so the first image flavor is given highest priority.
+     * <p>
+     * Optionally, it is possible to pass in Map of hints. These hints may be used by
+     * ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints
+     * used by the bundled implementations. You can, of course, define your own hints.
+     * @param image the image to convert
+     * @param flavors the requested image flavors (in preferred order).
+     * @param hints a Map of hints to any of the background components or null
+     * @return the fully loaded image
+     * @throws ImageException If no suitable loader/converter combination is available to fulfill
+     *                  the request or if an error occurred while loading the image.
+     * @throws IOException If an I/O error occurs
+     */
+    public Image convertImage(Image image, ImageFlavor[] flavors, Map hints)
+                throws ImageException, IOException {
+        if (hints == null) {
+            hints = Collections.EMPTY_MAP;
+        }
+        ImageInfo info = image.getInfo();
+        
+        Image img = null;
+        int count = flavors.length;
+        ImageProviderPipeline[] candidates = new ImageProviderPipeline[count];
+        for (int i = 0; i < count; i++) {
+            if (image.getFlavor().equals(flavors[i])) {
+                //Shortcut (the image is already in one of the requested formats)
+                return image;
+            }
+            candidates[i] = getPipelineFactory().newImageConverterPipeline(image, flavors[i]);
+        }
+        ImageProviderPipeline pipeline = choosePipeline(candidates);
+        
+        if (pipeline != null) {
+            img = pipeline.execute(info, image, hints, null);
+        }
+        if (img == null) {
+            throw new ImageException(
+                    "Cannot convert image " + image 
+                    + " (no suitable converter combination available)");
+        }
+        return img;
+    }
+
+    /**
+     * Converts an image with no hints. See
+     * {@link #convertImage(Image, ImageFlavor[], Map)} for more
+     * information.
+     * @param image the image to convert
+     * @param flavors the requested image flavors (in preferred order).
+     * @return the fully loaded image
+     * @throws ImageException If no suitable loader/converter combination is available to fulfill
+     *                  the request or if an error occurred while loading the image.
+     * @throws IOException If an I/O error occurs
+     */
+    public Image convertImage(Image image, ImageFlavor[] flavors)
+                throws ImageException, IOException {
+        return convertImage(image, flavors, null);
+    }
+    
+    private ImageProviderPipeline choosePipeline(ImageProviderPipeline[] candidates) {
+        ImageProviderPipeline pipeline = null;
+        int minPenalty = Integer.MAX_VALUE;
+        int count = candidates.length;
+        for (int i = count - 1; i >= 0; i--) {
+            if (candidates[i] == null) {
+                continue;
+            }
+            int penalty = candidates[i].getConversionPenalty();
+            if (penalty <= minPenalty) {
+                pipeline = candidates[i];
+                minPenalty = penalty;
+            }
+        }
+        return pipeline;
     }
     
 }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/cache/ImageCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/cache/ImageCache.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/cache/ImageCache.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/cache/ImageCache.java Sat Dec  8 02:36:32 2007
@@ -181,6 +181,9 @@
      * @return the requested image or null if the image is not in the cache
      */
     public Image getImage(String uri, ImageFlavor flavor) {
+        if (uri == null || "".equals(uri)) {
+            return null;
+        }
         ImageKey key = new ImageKey(uri, flavor);
         Image img = (Image)images.get(key);
         if (cacheListener != null) {
@@ -198,12 +201,16 @@
      * @param img the image
      */
     public void putImage(Image img) {
+        String originalURI = img.getInfo().getOriginalURI();
+        if (originalURI == null || "".equals(originalURI)) {
+            return; //Don't cache if there's no URI
+        }
         //An already existing Image is replaced.
         if (!img.isCacheable()) {
             throw new IllegalArgumentException(
                     "Image is not cacheable! (Flavor: " + img.getFlavor() + ")");
         }
-        ImageKey key = new ImageKey(img.getInfo().getOriginalURI(), img.getFlavor());
+        ImageKey key = new ImageKey(originalURI, img.getFlavor());
         images.put(key, img);
     }
 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/AbstractImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/AbstractImage.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/AbstractImage.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/impl/AbstractImage.java Sat Dec  8 02:36:32 2007
@@ -61,4 +61,9 @@
         return null;
     }
 
+    /** {@inheritDoc} */
+    public String toString() {
+        return getClass().getName() + ": " + getInfo();
+    }
+
 }

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=602442&r1=602441&r2=602442&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 Sat Dec  8 02:36:32 2007
@@ -19,7 +19,10 @@
 
 package org.apache.fop.image2.impl;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 
 import org.apache.commons.io.IOUtils;
 
@@ -85,6 +88,35 @@
      */
     public InputStream createInputStream() {
         return this.streamFactory.createInputStream();
+    }
+    
+    /**
+     * Writes the content of the image to an OutputStream. The OutputStream in NOT closed at the
+     * end.
+     * @param out the OutputStream
+     * @throws IOException if an I/O error occurs
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        InputStream in = createInputStream();
+        try {
+            IOUtils.copy(in, out);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+    
+    /**
+     * Writes the content of the image to a File.
+     * @param target the file to be written
+     * @throws IOException if an I/O error occurs
+     */
+    public void writeTo(File target) throws IOException {
+        OutputStream out = new java.io.FileOutputStream(target);
+        try {
+            writeTo(out);
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
     }
     
     /**

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=602442&r1=602441&r2=602442&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 Sat Dec  8 02:36:32 2007
@@ -23,6 +23,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.Source;
 
 import org.w3c.dom.Element;
@@ -37,7 +38,6 @@
 import org.apache.commons.logging.LogFactory;
 
 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;
@@ -82,6 +82,20 @@
     }
 
     /**
+     * Returns the fully qualified classname of an XML parser for
+     * Batik classes that apparently need it (error messages, perhaps)
+     * @return an XML parser classname
+     */
+    public static String getParserName() {
+        try {
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            return factory.newSAXParser().getXMLReader().getClass().getName();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
      * This method is put in another class so that the class loader does not
      * attempt to load Batik related classes when constructing the SVGPreloader
      * class.
@@ -96,7 +110,7 @@
                 int length = in.available();
                 in.mark(length + 1);
                 SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
-                        XMLImage.getParserName());
+                        getParserName());
                 SVGDocument doc = (SVGDocument) factory.createSVGDocument(src.getSystemId(), in);
 
                 Element e = doc.getRootElement();

Modified: 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=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/ImageProviderPipeline.java Sat Dec  8 02:36:32 2007
@@ -23,6 +23,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -61,7 +62,7 @@
      */
     public ImageProviderPipeline(ImageCache cache, ImageLoader loader) {
         this.cache = cache;
-        this.loader = loader;
+        setImageLoader(loader);
     }
     
     /**
@@ -73,6 +74,14 @@
     }
     
     /**
+     * Default constructor without caching and without an ImageLoader (or the ImageLoader may
+     * be set later).
+     */
+    public ImageProviderPipeline() {
+        this(null, null);
+    }
+    
+    /**
      * 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
@@ -86,6 +95,28 @@
      */
     public Image execute(ImageInfo info, Map hints, ImageSessionContext context)
                 throws ImageException, IOException {
+        return execute(info, null, hints, context);
+    }
+    
+    /**
+     * 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 originalImage the original image to start the pipeline off or null if an ImageLoader
+     *          is used
+     * @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, Image originalImage,
+            Map hints, ImageSessionContext context) throws ImageException, IOException {
+        if (hints == null) {
+            hints = Collections.EMPTY_MAP;
+        }
         long start, duration;
         start = System.currentTimeMillis();
         Image img = null;
@@ -106,15 +137,18 @@
                 }
             }
         
-            if (img == null) {
+            if (img == null && loader != null) {
                 //try target flavor of loader from cache
                 ImageFlavor flavor = loader.getTargetFlavor();
                 img = cache.getImage(info, flavor);
             }
         }
+        if (img == null && originalImage != null) {
+            img = originalImage;
+        }
         
         boolean entirelyInCache = true;
-        if (img == null) {
+        if (img == null && loader != null) {
             //Load image
             img = loader.loadImage(info, hints, context);
             if (log.isTraceEnabled()) {
@@ -128,6 +162,10 @@
                 lastCacheableImage = img;
             }
         }
+        if (img == null) {
+            throw new ImageException(
+                    "Pipeline fails. No ImageLoader and no original Image available.");
+        }
         
         if (converterCount > 0) {
             for (int i = startingPoint; i < converterCount; i++) {
@@ -212,6 +250,15 @@
     }
     
     /**
+     * Sets the ImageLoader that is used at the beginning of the pipeline if the image is not
+     * loaded, yet.
+     * @param imageLoader the image loader implementation
+     */
+    public void setImageLoader(ImageLoader imageLoader) {
+        this.loader = imageLoader;
+    }
+    
+    /**
      * Adds an additional ImageConverter to the end of the pipeline.
      * @param converter the ImageConverter instance
      */
@@ -238,7 +285,9 @@
      */
     public int getConversionPenalty() {
         int penalty = 0;
-        penalty += loader.getUsagePenalty();
+        if (loader != null) {
+            penalty += loader.getUsagePenalty();
+        }
         Iterator iter = converters.iterator();
         while (iter.hasNext()) {
             ImageConverter converter = (ImageConverter)iter.next();

Modified: 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=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/image2/pipeline/PipelineFactory.java Sat Dec  8 02:36:32 2007
@@ -26,6 +26,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.fop.image2.Image;
 import org.apache.fop.image2.ImageFlavor;
 import org.apache.fop.image2.ImageManager;
 import org.apache.fop.image2.spi.ImageConverter;
@@ -79,11 +80,27 @@
     }
     
     /**
-     * Creates and returns an ImageConverterPipeline that allows to load an image of the given
-     * MIME type and present it in the requested image flavor.
+     * Creates and returns an {@link ImageProviderPipeline} that allows to load an image of the
+     * given MIME type and present it in the requested image flavor.
+     * @param originalImage the original image that serves as the origin point of the conversion
+     * @param targetFlavor the requested image flavor
+     * @return an {@link ImageProviderPipeline} or null if no suitable pipeline could be assembled
+     */
+    public ImageProviderPipeline newImageConverterPipeline(
+                Image originalImage, ImageFlavor targetFlavor) {
+        //Get snapshot to avoid concurrent modification problems (thread-safety)
+        DefaultEdgeDirectory dir = getEdgeDirectory();
+        ImageRepresentation destination = new ImageRepresentation(targetFlavor);
+        ImageProviderPipeline pipeline = findPipeline(dir, originalImage.getFlavor(), destination);
+        return pipeline;
+    }
+    
+    /**
+     * Creates and returns an {@link ImageProviderPipeline} 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
+     * @return an {@link ImageProviderPipeline} or null if no suitable pipeline could be assembled
      */
     public ImageProviderPipeline newImageConverterPipeline(
                 String originalMime, ImageFlavor targetFlavor) {
@@ -116,36 +133,10 @@
                     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.isTraceEnabled()) {
-                            log.trace("Lowest penalty: " + dijkstra.getLowestPenalty(destination));
-                        }
-                        
-                        Vertex prev = destination;
-                        Vertex pred = dijkstra.getPredecessor(destination);
-                        if (pred == null) {
-                            if (log.isTraceEnabled()) {
-                                log.trace("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());
-                            }
+                        pipeline = findPipeline(dir, flavors[j], destination);
+                        if (pipeline != null) {
+                            ImageLoader loader = loaderFactory.newImageLoader(flavors[j]);
+                            pipeline.setImageLoader(loader);
                             if (pipeline != null && log.isDebugEnabled()) {
                                 log.debug("Pipeline: " + pipeline);
                             }
@@ -163,6 +154,42 @@
             log.debug("Pipeline: " + pipeline);
         }
         return pipeline;
+    }
+    
+    private ImageProviderPipeline findPipeline(DefaultEdgeDirectory dir,
+            ImageFlavor originFlavor, ImageRepresentation destination) {
+        DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(
+                dir);
+        ImageRepresentation origin = new ImageRepresentation(originFlavor); 
+        dijkstra.execute(origin, destination);
+        if (log.isTraceEnabled()) {
+            log.trace("Lowest penalty: " + dijkstra.getLowestPenalty(destination));
+        }
+        
+        Vertex prev = destination;
+        Vertex pred = dijkstra.getPredecessor(destination);
+        if (pred == null) {
+            if (log.isTraceEnabled()) {
+                log.trace("No route found!");
+            }
+            return null;
+        } 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;
+            }
+            ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), null);
+            Iterator iter = stops.iterator();
+            while (iter.hasNext()) {
+                ImageConversionEdge edge = (ImageConversionEdge)iter.next(); 
+                pipeline.addConverter(edge.getImageConverter());
+            }
+            return pipeline;
+        }
     }
     
 }

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=602442&r1=602441&r2=602442&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 Sat Dec  8 02:36:32 2007
@@ -35,7 +35,7 @@
 public interface ImagePreloader {
 
     /** Default priority for preloaders */
-    public static final int DEFAULT_PRIORITY = 1000;
+    int DEFAULT_PRIORITY = 1000;
     
     /**
      * "Preloads" an image, i.e. indentifies whether the source image is supported by this

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/pdf/ImageRawJPEGAdapter.java Sat Dec  8 02:36:32 2007
@@ -19,11 +19,8 @@
 
 package org.apache.fop.render.pdf;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 
-import org.apache.commons.io.IOUtils;
-
 import org.apache.fop.image2.impl.ImageRawJPEG;
 import org.apache.fop.pdf.DCTFilter;
 import org.apache.fop.pdf.PDFDeviceColorSpace;
@@ -86,13 +83,7 @@
     
     /** {@inheritDoc} */
     public void outputContents(OutputStream out) throws IOException {
-        InputStream in = getImage().createInputStream();
-        try {
-            IOUtils.copy(in, out);
-        } finally {
-            IOUtils.closeQuietly(in);
-        }
-        //TODO IMPLEMENT ME
+        getImage().writeTo(out);
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/ps/PSRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/ps/PSRenderer.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/ps/PSRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/ps/PSRenderer.java Sat Dec  8 02:36:32 2007
@@ -456,12 +456,7 @@
                     ImageRawJPEG jpeg = (ImageRawJPEG)raw;
                     ImageEncoder encoder = new ImageEncoder() {
                         public void writeTo(OutputStream out) throws IOException {
-                            InputStream in = raw.createInputStream();
-                            try {
-                                IOUtils.copy(in, out);
-                            } finally {
-                                IOUtils.closeQuietly(in);
-                            }
+                            raw.writeTo(out);
                         }
                         public String getImplicitFilter() {
                             return "<< >> /DCTDecode";

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/RTFHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/RTFHandler.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/RTFHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/RTFHandler.java Sat Dec  8 02:36:32 2007
@@ -22,6 +22,7 @@
 // Java
 import java.awt.geom.Point2D;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.util.Iterator;
@@ -31,7 +32,6 @@
 
 import org.xml.sax.SAXException;
 
-import org.apache.batik.dom.svg.SVGDOMImplementation;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -75,15 +75,15 @@
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fonts.FontSetup;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.XMLImage;
 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.ImageManager;
 import org.apache.fop.image2.ImageSessionContext;
+import org.apache.fop.image2.ImageSize;
 import org.apache.fop.image2.impl.ImageRawStream;
+import org.apache.fop.image2.impl.ImageXMLDOM;
 import org.apache.fop.image2.util.ImageUtil;
 import org.apache.fop.render.DefaultFontResolver;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
@@ -1132,71 +1132,83 @@
             Document doc = child.getDOMDocument();
             String ns = child.getNamespaceURI();
             
-            if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
-                // Build the image info.
-                FopImage.ImageInfo info = new FopImage.ImageInfo();
-                info.mimeType = "image/svg+xml";
-                info.str = SVGDOMImplementation.SVG_NAMESPACE_URI;
-                info.originalURI = "";
-                info.data = doc;
-
-                // Set the resolution to that of the FOUserAgent
-                FOUserAgent ua = ifo.getUserAgent();
-                info.dpiHorizontal = 25.4f / ua.getSourcePixelUnitToMillimeter();
-                info.dpiVertical = info.dpiHorizontal;
-                
-                // Set the image size to the size of the svg.
-                Point2D csize = new Point2D.Float(-1, -1);
-                Point2D intrinsicDimensions = child.getDimension(csize);
-                info.width = (int) intrinsicDimensions.getX();
-                info.height = (int) intrinsicDimensions.getY();
-                
-                FopImage fopImage = new XMLImage(info);
-                fopImage.load(FopImage.ORIGINAL_DATA);
+            ImageInfo info = new ImageInfo(null, null);
+            // Set the resolution to that of the FOUserAgent
+            FOUserAgent ua = ifo.getUserAgent();
+            ImageSize size = new ImageSize();
+            size.setResolution(ua.getSourceResolution());
+            
+            // Set the image size to the size of the svg.
+            Point2D csize = new Point2D.Float(-1, -1);
+            Point2D intrinsicDimensions = child.getDimension(csize);
+            size.setSizeInMillipoints(
+                    (int)Math.round(intrinsicDimensions.getX() * 1000),
+                    (int)Math.round(intrinsicDimensions.getY() * 1000));
+            size.calcPixelsFromSize();
+            info.setSize(size);
 
-                //putGraphic(ifo, fopImage);
-            } else {
-                log.warn("The namespace " + ns
-                        + " for instream-foreign-objects is not supported.");
-            }
+            ImageXMLDOM image = new ImageXMLDOM(info, doc, ns);
             
+            FOUserAgent userAgent = ifo.getUserAgent();
+            ImageManager manager = userAgent.getFactory().getImageManager();
+            Image converted = manager.convertImage(image, FLAVORS);
+            putGraphic(ifo, converted);
             
         } catch (Exception e) {
             log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e);
         }
     }
 
+    private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+        ImageFlavor.RAW_EMF, ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
+    };
+    
     /**
      * Puts a graphic/image into the generated RTF file.
      * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
-     * @param fopImage the image
+     * @param info the image info object
      * @throws IOException In case of an I/O error
      */
     private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info) 
             throws IOException {
-        byte[] rawData = null;
-        
         try {
             FOUserAgent userAgent = abstractGraphic.getUserAgent();
             ImageManager manager = userAgent.getFactory().getImageManager();
-            ImageFlavor[] flavors = new ImageFlavor[] {
-                    ImageFlavor.RAW_EMF, ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
-            };
             ImageSessionContext sessionContext = userAgent.getImageSessionContext();
             Map hints = ImageUtil.getDefaultHints(sessionContext);
-            Image image = manager.getImage(info, flavors, hints, sessionContext);
+            Image image = manager.getImage(info, FLAVORS, hints, sessionContext);
 
-            if (image instanceof ImageRawStream) {
-                ImageRawStream rawImage = (ImageRawStream)image; 
-                rawData = IOUtils.toByteArray(rawImage.createInputStream());
-            }
+            putGraphic(abstractGraphic, image);
         } catch (ImageException ie) {
             log.error("Error while loading/processing image: " + info.getOriginalURI(), ie);
         }
+    }
+    
+    /**
+     * Puts a graphic/image into the generated RTF file.
+     * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
+     * @param image the image
+     * @throws IOException In case of an I/O error
+     */
+    private void putGraphic(AbstractGraphics abstractGraphic, Image image) 
+            throws IOException {
+        byte[] rawData = null;
+        
+        ImageInfo info = image.getInfo();
+
+        if (image instanceof ImageRawStream) {
+            ImageRawStream rawImage = (ImageRawStream)image;
+            InputStream in = rawImage.createInputStream();
+            try {
+                rawData = IOUtils.toByteArray(in);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+        }
 
         if (rawData == null) {
             log.warn(FONode.decorateWithContextInfo("Image could not be embedded: "
-                    + info.getOriginalURI(), abstractGraphic));
+                    + image, abstractGraphic));
             return;
         }
 
@@ -1207,7 +1219,9 @@
         final RtfExternalGraphic rtfGraphic = c.getTextrun().newImage();
    
         //set URL
-        rtfGraphic.setURL(info.getOriginalURI());
+        if (info.getOriginalURI() != null) {
+            rtfGraphic.setURL(info.getOriginalURI());
+        }
         rtfGraphic.setImageData(rawData);
 
         //set scaling

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java?rev=602442&r1=602441&r2=602442&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java Sat Dec  8 02:36:32 2007
@@ -26,19 +26,17 @@
  * the FOP project.
  */
 
-import org.apache.commons.io.IOUtils;
-import org.apache.fop.render.rtf.rtflib.tools.ImageConstants;
-import org.apache.fop.render.rtf.rtflib.tools.ImageUtil;
-//import org.apache.fop.render.rtf.rtflib.tools.jpeg.Encoder;
-//import org.apache.fop.render.rtf.rtflib.tools.jpeg.JPEGException;
-
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
-
-import java.io.File;
-import java.net.URL;
 import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.render.rtf.rtflib.tools.ImageConstants;
+import org.apache.fop.render.rtf.rtflib.tools.ImageUtil;
 
 /**
  * Creates an RTF image from an external graphic file.
@@ -342,13 +340,13 @@
         }
 
 
-        if (url == null) {
-            throw new ExternalGraphicException("The attribute 'url' of "
-                    + "<fo:external-graphic> is null.");
+        if (url == null && imagedata == null) {
+            throw new ExternalGraphicException(
+                    "No image data is available (neither URL, nor in-memory)");
         }
 
         String linkToRoot = System.getProperty("jfor_link_to_root");
-        if (linkToRoot != null) {
+        if (url != null && linkToRoot != null) {
             writer.write("{\\field {\\* \\fldinst { INCLUDEPICTURE \"");
             writer.write(linkToRoot);
             File urlFile = new File(url.getFile());
@@ -380,7 +378,7 @@
         }
 
         // Determine image file format
-        String file = url.getFile ();
+        String file = (url != null ? url.getFile() : "<unknown>");
         imageformat = FormatBase.determineFormat(imagedata);
         if (imageformat != null) {
             imageformat = imageformat.convert(imageformat, imagedata);

Added: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java?rev=602442&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java (added)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java Sat Dec  8 02:36:32 2007
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.svg.SVGDocument;
+
+import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.image2.impl.ImageConverterBuffered2Rendered;
+import org.apache.fop.image2.impl.ImageConverterG2D2Bitmap;
+import org.apache.fop.image2.impl.ImageConverterRendered2PNG;
+import org.apache.fop.image2.impl.ImageRawStream;
+import org.apache.fop.image2.impl.ImageXMLDOM;
+import org.apache.fop.image2.impl.batik.ImageConverterSVG2G2D;
+import org.apache.fop.image2.impl.batik.PreloaderSVG;
+import org.apache.fop.image2.impl.imageio.ImageLoaderImageIO;
+import org.apache.fop.image2.pipeline.ImageProviderPipeline;
+import org.apache.fop.image2.spi.ImageLoader;
+
+/**
+ * Tests for the image pipeline functionality.
+ */
+public class ImagePipelineTestCase extends TestCase {
+
+    private FopFactory fopFactory;
+    
+    public ImagePipelineTestCase(String name) {
+        super(name);
+        fopFactory = FopFactory.newInstance();
+        fopFactory.setSourceResolution(72);
+        fopFactory.setTargetResolution(300);
+    }
+    
+    public void testPipelineWithLoader() throws Exception {
+        String uri = "test/resources/images/bgimg72dpi.gif";
+
+        FOUserAgent userAgent = fopFactory.newFOUserAgent();
+        ImageManager manager = fopFactory.getImageManager();
+        
+        ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
+        assertNotNull("ImageInfo must not be null", info);
+        
+        ImageLoader loader = new ImageLoaderImageIO(ImageFlavor.RENDERED_IMAGE);
+        ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), loader);
+        pipeline.addConverter(new ImageConverterRendered2PNG());
+        
+        Image img = pipeline.execute(info, null, userAgent.getImageSessionContext());
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.RAW_PNG, img.getFlavor());
+        assertTrue(img instanceof ImageRawStream);
+    }
+    
+    private ImageXMLDOM createSVGImage() throws IOException {
+        File svgFile = new File("test/resources/images/img-w-size.svg");
+        SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
+                PreloaderSVG.getParserName());
+        SVGDocument doc = (SVGDocument)factory.createSVGDocument(
+                svgFile.toURL().toExternalForm());
+        
+        //We simulate an instream-foreign-object where there is no original URI for the image.
+        //We also don't "know" the MIME type.
+        ImageInfo info = new ImageInfo(null /*null is the intention here*/, null);
+        info.setSize(new ImageSize(72, 72, 72));
+        info.getSize().calcSizeFromPixels();
+        
+        ImageXMLDOM svgImage = new ImageXMLDOM(info,
+                doc, doc.getDocumentElement().getNamespaceURI());
+        return svgImage;
+    }
+    
+    public void testPipelineWithoutLoader() throws Exception {
+
+        FOUserAgent userAgent = fopFactory.newFOUserAgent();
+        ImageManager manager = fopFactory.getImageManager();
+
+        ImageXMLDOM svgImage = createSVGImage();
+        
+        ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), null);
+        pipeline.addConverter(new ImageConverterSVG2G2D());
+        pipeline.addConverter(new ImageConverterG2D2Bitmap());
+        pipeline.addConverter(new ImageConverterBuffered2Rendered());
+        pipeline.addConverter(new ImageConverterRendered2PNG());
+        
+        Image img = pipeline.execute(svgImage.getInfo(), svgImage, null,
+                    userAgent.getImageSessionContext());
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.RAW_PNG, img.getFlavor());
+        assertTrue(img instanceof ImageRawStream);
+    }
+    
+    public void testPipelineFromURIThroughManager() throws Exception {
+        String uri = "examples/fo/graphics/asf-logo.png";
+        
+        FOUserAgent userAgent = fopFactory.newFOUserAgent();
+        ImageManager manager = fopFactory.getImageManager();
+        
+        ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
+        assertNotNull("ImageInfo must not be null", info);
+
+        ImageFlavor[] flavors = new ImageFlavor[] {
+                ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
+        };
+        Image img = manager.getImage(info, flavors, userAgent.getImageSessionContext());
+        
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.RAW_PNG, img.getFlavor());
+        assertTrue(img instanceof ImageRawStream);
+    }
+    
+    public void testPipelineWithoutURIThroughManager() throws Exception {
+        
+        ImageManager manager = fopFactory.getImageManager();
+        
+        ImageXMLDOM svgImage = createSVGImage();
+
+        ImageFlavor[] flavors = new ImageFlavor[] {
+                ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
+        };
+        Image img = manager.convertImage(svgImage, flavors);
+        
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.RAW_PNG, img.getFlavor());
+        assertTrue(img instanceof ImageRawStream);
+    }
+    
+}

Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/test/java/org/apache/fop/image2/ImagePipelineTestCase.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