You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2010/03/18 09:26:31 UTC
svn commit: r924666 - in /xmlgraphics/commons/trunk:
src/documentation/content/xdocs/
src/java/org/apache/xmlgraphics/image/loader/
src/java/org/apache/xmlgraphics/image/loader/impl/
src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ src/java/o...
Author: jeremias
Date: Thu Mar 18 08:26:30 2010
New Revision: 924666
URL: http://svn.apache.org/viewvc?rev=924666&view=rev
Log:
Enhancements to the image loading framework:
- Add support for configurable additional penalties for preloader, loader and converter plug-ins in the ImageImplRegistry (in addition to the hard-coded penalties). (See docs for details)
- Add image manager and image session context to hints map so implementations can use these objects.
- Deprecated usage penalty on ImageLoaderFactory due to a redundancy with the usage penalty on ImageLoader.
- Additional logging on raw CCITT loader factory
Added:
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java (with props)
xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java (with props)
xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java (with props)
xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/
xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java (with props)
Modified:
xmlgraphics/commons/trunk/src/documentation/content/xdocs/image-loader.xml
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageManager.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java
xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java
Modified: xmlgraphics/commons/trunk/src/documentation/content/xdocs/image-loader.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/documentation/content/xdocs/image-loader.xml?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/documentation/content/xdocs/image-loader.xml (original)
+++ xmlgraphics/commons/trunk/src/documentation/content/xdocs/image-loader.xml Thu Mar 18 08:26:30 2010
@@ -317,5 +317,44 @@ import org.apache.xmlgraphics.image.load
</p>
</section>
</section>
+ <section id="customization">
+ <title>Customization</title>
+ <section id="source-reuse">
+ <title>Disabling Source Re-use</title>
+ <p>
+ By default, the Source object being used during the pre-loading stage is re-used when
+ the image is fully loaded later (assuming an ImageSessionContext is used that descends
+ from AbstractImageSessionContext). That means that a stream is only opened once and
+ the image loading framework tries to re-wind the stream when it has to re-read portions
+ of the stream when loading the complete image.
+ </p>
+ <p>
+ In some situations, this behavior may be undesired. Therefore, it can be disabled
+ through a system property
+ (<code>org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext.no-source-reuse</code>).
+ Set it to "true" and that feature will be disabled.
+ </p>
+ </section>
+ <section id="plugin-penalties">
+ <title>Adjusting plug-in penalties</title>
+ <p>
+ Every image loader plug-in has a hard-coded usage penalty that influences which solution
+ is chosen if there are multiple possibilities to load an image. Sometimes, though, these
+ penalties need to be tweaked. The <code>ImageImplRegistry</code> (reachable through
+ <code>ImageManager.getRegistry()</code>) supports storing additional penalty values.
+ An example:
+ </p>
+ <source><![CDATA[ImageImplRegistry registry = imageManager.getRegistry();
+registry.setAdditionalPenalty(
+ "org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawCCITTFax",
+ Penalty.toPenalty(10000));]]></source>
+ <p>
+ This increases the penalty for the raw CCITT loader significantly so it will only be
+ used if no other solutions exist. You can also set <code>Penalty.INFINITE_PENALTY</code>
+ to disable the plug-in altogether. Negative penalties are possible to promote a plug-in
+ but a negative penalty sum will be treated as zero penalty in most cases.
+ </p>
+ </section>
+ </section>
</body>
</document>
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageManager.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageManager.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageManager.java Thu Mar 18 08:26:30 2010
@@ -20,7 +20,6 @@
package org.apache.xmlgraphics.image.loader;
import java.io.IOException;
-import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
@@ -35,6 +34,7 @@ import org.apache.xmlgraphics.image.load
import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
import org.apache.xmlgraphics.image.loader.spi.ImagePreloader;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
/**
* ImageManager is the central starting point for image access.
@@ -45,7 +45,7 @@ public class ImageManager {
protected static Log log = LogFactory.getLog(ImageManager.class);
/** Holds all registered interface implementations for the image package */
- private ImageImplRegistry registry = ImageImplRegistry.getDefaultInstance();
+ private ImageImplRegistry registry;
/** Provides session-independent information */
private ImageContext imageContext;
@@ -60,6 +60,16 @@ public class ImageManager {
* @param context the session-independent context information
*/
public ImageManager(ImageContext context) {
+ this(ImageImplRegistry.getDefaultInstance(), context);
+ }
+
+ /**
+ * Constructor for testing purposes.
+ * @param registry the implementation registry with all plug-ins
+ * @param context the session-independent context information
+ */
+ public ImageManager(ImageImplRegistry registry, ImageContext context) {
+ this.registry = registry;
this.imageContext = context;
}
@@ -171,6 +181,22 @@ public class ImageManager {
+ uri);
}
+ private Map prepareHints(Map hints, ImageSessionContext sessionContext) {
+ Map newHints = new java.util.HashMap();
+ if (hints != null) {
+ newHints.putAll(hints); //Copy in case an unmodifiable map is passed in
+ }
+ if (!newHints.containsKey(ImageProcessingHints.IMAGE_SESSION_CONTEXT)
+ && sessionContext != null) {
+ newHints.put(ImageProcessingHints.IMAGE_SESSION_CONTEXT, sessionContext);
+
+ }
+ if (!newHints.containsKey(ImageProcessingHints.IMAGE_MANAGER)) {
+ newHints.put(ImageProcessingHints.IMAGE_MANAGER, this);
+ }
+ return newHints;
+ }
+
/**
* Loads an image. The caller can indicate what kind of image flavor is requested. When this
* method is called the code looks for a suitable ImageLoader and, if necessary, builds
@@ -192,9 +218,7 @@ public class ImageManager {
public Image getImage(ImageInfo info, ImageFlavor flavor, Map hints,
ImageSessionContext session)
throws ImageException, IOException {
- if (hints == null) {
- hints = Collections.EMPTY_MAP;
- }
+ hints = prepareHints(hints, session);
Image img = null;
ImageProviderPipeline pipeline = getPipelineFactory().newImageConverterPipeline(
@@ -233,9 +257,7 @@ public class ImageManager {
public Image getImage(ImageInfo info, ImageFlavor[] flavors, Map hints,
ImageSessionContext session)
throws ImageException, IOException {
- if (hints == null) {
- hints = Collections.EMPTY_MAP;
- }
+ hints = prepareHints(hints, session);
Image img = null;
ImageProviderPipeline[] candidates = getPipelineFactory().determineCandidatePipelines(
@@ -309,9 +331,7 @@ public class ImageManager {
*/
public Image convertImage(Image image, ImageFlavor[] flavors, Map hints)
throws ImageException, IOException {
- if (hints == null) {
- hints = Collections.EMPTY_MAP;
- }
+ hints = prepareHints(hints, null);
ImageInfo info = image.getInfo();
Image img = null;
@@ -362,14 +382,27 @@ public class ImageManager {
ImageProviderPipeline pipeline = null;
int minPenalty = Integer.MAX_VALUE;
int count = candidates.length;
+ if (log.isTraceEnabled()) {
+ log.trace("Candidate Pipelines:");
+ for (int i = 0; i < count; i++) {
+ if (candidates[i] == null) {
+ continue;
+ }
+ log.trace(" " + i + ": "
+ + candidates[i].getConversionPenalty(getRegistry()) + " for " + candidates[i]);
+ }
+ }
for (int i = count - 1; i >= 0; i--) {
if (candidates[i] == null) {
continue;
}
- int penalty = candidates[i].getConversionPenalty();
- if (penalty <= minPenalty) {
+ Penalty penalty = candidates[i].getConversionPenalty(getRegistry());
+ if (penalty.isInfinitePenalty()) {
+ continue; //Exclude candidate on infinite penalty
+ }
+ if (penalty.getValue() <= minPenalty) {
pipeline = candidates[i];
- minPenalty = penalty;
+ minPenalty = penalty.getValue();
}
}
if (log.isDebugEnabled()) {
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/ImageProcessingHints.java Thu Mar 18 08:26:30 2010
@@ -22,6 +22,7 @@ package org.apache.xmlgraphics.image.loa
/**
* This interface defines some standard hints to be used for image processing in this package.
* They are provided for convenience. You can define your own hints as you like.
+ * Generally, consumers should not rely on the presence of any hint!
*/
public interface ImageProcessingHints {
@@ -30,6 +31,22 @@ public interface ImageProcessingHints {
/** Used to send a hint about the target resolution (of the final output format). */
Object TARGET_RESOLUTION = "TARGET_RESOLUTION"; //Value: Number (unit dpi)
+ /**
+ * Used to pass in the {@link ImageSessionContext}. A consumer can use this to load embedded
+ * images over the same mechanism as the main image (ex. JPEG images referenced in an
+ * SVG image).
+ * @since 1.4
+ */
+ Object IMAGE_SESSION_CONTEXT = "IMAGE_SESSION_CONTEXT"; //Value: ImageSessionContext instance
+
+ /**
+ * Used to pass in the {@link ImageManager}. A consumer can use this to load embedded
+ * images over the same mechanism as the main image (ex. JPEG images referenced in an
+ * SVG image).
+ * @since 1.4
+ */
+ Object IMAGE_MANAGER = "IMAGE_MANAGER"; //Value: ImageManager instance
+
/** Used to tell the image loader to ignore any color profile in the image. */
Object IGNORE_COLOR_PROFILE = "IGNORE_COLOR_PROFILE"; //Value: Boolean
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoader.java Thu Mar 18 08:26:30 2010
@@ -42,7 +42,7 @@ public abstract class AbstractImageLoade
/** {@inheritDoc} */
public int getUsagePenalty() {
- return 0;
+ return NO_LOADING_PENALTY;
}
/**
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/AbstractImageLoaderFactory.java Thu Mar 18 08:26:30 2010
@@ -19,7 +19,9 @@
package org.apache.xmlgraphics.image.loader.impl;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory;
/**
@@ -34,4 +36,14 @@ public abstract class AbstractImageLoade
return true;
}
+ /**
+ * {@inheritDoc}
+ * @deprecated Redundancy with {@link ImageLoader#getUsagePenalty()}
+ */
+ public int getUsagePenalty(String mime, ImageFlavor flavor) {
+ //Kept for compatibility
+ ImageLoader loader = newImageLoader(flavor);
+ return loader.getUsagePenalty();
+ }
+
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/CompositeImageLoader.java Thu Mar 18 08:26:30 2010
@@ -66,6 +66,15 @@ public class CompositeImageLoader extend
}
/** {@inheritDoc} */
+ public int getUsagePenalty() {
+ int maxPenalty = NO_LOADING_PENALTY;
+ for (int i = 1, c = loaders.length; i < c; i++) {
+ maxPenalty = Math.max(maxPenalty, loaders[i].getUsagePenalty());
+ }
+ return maxPenalty;
+ }
+
+ /** {@inheritDoc} */
public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
throws ImageException, IOException {
ImageException firstException = null;
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryEPS.java Thu Mar 18 08:26:30 2010
@@ -54,11 +54,6 @@ public class ImageLoaderFactoryEPS exten
}
/** {@inheritDoc} */
- public int getUsagePenalty(String mime, ImageFlavor flavor) {
- return 0;
- }
-
- /** {@inheritDoc} */
public boolean isAvailable() {
return true;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryInternalTIFF.java Thu Mar 18 08:26:30 2010
@@ -54,11 +54,6 @@ public class ImageLoaderFactoryInternalT
}
/** {@inheritDoc} */
- public int getUsagePenalty(String mime, ImageFlavor flavor) {
- return 10000; //Provide this only as a fallback
- }
-
- /** {@inheritDoc} */
public boolean isAvailable() {
return true;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRaw.java Thu Mar 18 08:26:30 2010
@@ -87,11 +87,6 @@ public class ImageLoaderFactoryRaw exten
}
/** {@inheritDoc} */
- public int getUsagePenalty(String mime, ImageFlavor flavor) {
- return 0;
- }
-
- /** {@inheritDoc} */
public boolean isAvailable() {
return true;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderFactoryRawCCITTFax.java Thu Mar 18 08:26:30 2010
@@ -19,6 +19,9 @@
package org.apache.xmlgraphics.image.loader.impl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -30,6 +33,9 @@ import org.apache.xmlgraphics.util.MimeC
*/
public class ImageLoaderFactoryRawCCITTFax extends AbstractImageLoaderFactory {
+ /** logger */
+ private transient Log log = LogFactory.getLog(ImageLoaderFactoryRawCCITTFax.class);
+
private static final String[] MIMES = new String[] {
MimeConstants.MIME_TIFF};
@@ -80,11 +86,6 @@ public class ImageLoaderFactoryRawCCITTF
}
/** {@inheritDoc} */
- public int getUsagePenalty(String mime, ImageFlavor flavor) {
- return 0;
- }
-
- /** {@inheritDoc} */
public boolean isAvailable() {
return true;
}
@@ -94,6 +95,7 @@ public class ImageLoaderFactoryRawCCITTF
Boolean tiled = (Boolean)imageInfo.getCustomObjects().get("TIFF_TILED");
if (Boolean.TRUE.equals(tiled)) {
//We don't support tiled images
+ log.trace("Raw CCITT loading not supported for tiled TIFF image");
return false;
}
Integer compression = (Integer)imageInfo.getCustomObjects().get("TIFF_COMPRESSION");
@@ -105,7 +107,11 @@ public class ImageLoaderFactoryRawCCITTF
case TIFFImage.COMP_FAX_G3_2D:
case TIFFImage.COMP_FAX_G4_2D:
Integer stripCount = (Integer)imageInfo.getCustomObjects().get("TIFF_STRIP_COUNT");
- return (stripCount != null && stripCount.intValue() == 1);
+ boolean supported = (stripCount != null && stripCount.intValue() == 1);
+ if (!supported) {
+ log.trace("Raw CCITT loading not supported for multi-strip TIFF image");
+ }
+ return supported;
default:
return false;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java Thu Mar 18 08:26:30 2010
@@ -35,8 +35,6 @@ import org.apache.xmlgraphics.image.load
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoader;
-import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
/**
@@ -74,4 +72,9 @@ public class ImageLoaderInternalTIFF ext
return new ImageRendered(info, img, null);
}
+ /** {@inheritDoc} */
+ public int getUsagePenalty() {
+ return 1000; //Provide this only as a fallback
+ }
+
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderFactoryImageIO.java Thu Mar 18 08:26:30 2010
@@ -50,11 +50,6 @@ public class ImageLoaderFactoryImageIO e
}
/** {@inheritDoc} */
- public int getUsagePenalty(String mime, ImageFlavor flavor) {
- return 0;
- }
-
- /** {@inheritDoc} */
public boolean isAvailable() {
return (getSupportedMIMETypes().length > 0);
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageConversionEdge.java Thu Mar 18 08:26:30 2010
@@ -20,6 +20,7 @@
package org.apache.xmlgraphics.image.loader.pipeline;
import org.apache.xmlgraphics.image.loader.spi.ImageConverter;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
import org.apache.xmlgraphics.util.dijkstra.Edge;
import org.apache.xmlgraphics.util.dijkstra.Vertex;
@@ -27,21 +28,23 @@ import org.apache.xmlgraphics.util.dijks
* 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 {
+class ImageConversionEdge implements Edge {
private ImageRepresentation source;
private ImageRepresentation target;
private ImageConverter converter;
+ private int penalty;
/**
* Main constructor.
* @param converter the image converter
+ * @param penalty the penalty for this edge
*/
- public ImageConversionEdge(
- ImageConverter converter) {
+ public ImageConversionEdge(ImageConverter converter, Penalty penalty) {
this.converter = converter;
this.source = new ImageRepresentation(converter.getSourceFlavor());
this.target = new ImageRepresentation(converter.getTargetFlavor());
+ this.penalty = Math.max(0, penalty.getValue());
}
/**
@@ -54,7 +57,7 @@ public class ImageConversionEdge impleme
/** {@inheritDoc} */
public int getPenalty() {
- return getImageConverter().getConversionPenalty();
+ return this.penalty;
}
/** {@inheritDoc} */
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/ImageProviderPipeline.java Thu Mar 18 08:26:30 2010
@@ -39,7 +39,9 @@ import org.apache.xmlgraphics.image.load
import org.apache.xmlgraphics.image.loader.cache.ImageCache;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
import org.apache.xmlgraphics.image.loader.spi.ImageConverter;
+import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
/**
* Represents a pipeline of ImageConverters with an ImageLoader at the beginning of the
@@ -272,14 +274,32 @@ public class ImageProviderPipeline {
* @return the overall penalty (a non-negative integer)
*/
public int getConversionPenalty() {
- int penalty = 0;
+ return getConversionPenalty(null).getValue();
+ }
+
+ /**
+ * Returns the overall conversion penalty for the pipeline. This can be used to choose among
+ * different possible pipelines.
+ * @param registry the image implementation registry
+ * @return the overall penalty (a non-negative integer)
+ */
+ public Penalty getConversionPenalty(ImageImplRegistry registry) {
+ Penalty penalty = Penalty.ZERO_PENALTY;
if (loader != null) {
- penalty += loader.getUsagePenalty();
+ penalty = penalty.add(loader.getUsagePenalty());
+ if (registry != null) {
+ penalty = penalty.add(
+ registry.getAdditionalPenalty(loader.getClass().getName()));
+ }
}
Iterator iter = converters.iterator();
while (iter.hasNext()) {
ImageConverter converter = (ImageConverter)iter.next();
- penalty += converter.getConversionPenalty();
+ penalty = penalty.add(converter.getConversionPenalty());
+ if (registry != null) {
+ penalty = penalty.add(
+ registry.getAdditionalPenalty(converter.getClass().getName()));
+ }
}
return penalty;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/pipeline/PipelineFactory.java Thu Mar 18 08:26:30 2010
@@ -19,8 +19,8 @@
package org.apache.xmlgraphics.image.loader.pipeline;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
@@ -38,6 +38,7 @@ import org.apache.xmlgraphics.image.load
import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
import org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
import org.apache.xmlgraphics.util.dijkstra.DefaultEdgeDirectory;
import org.apache.xmlgraphics.util.dijkstra.DijkstraAlgorithm;
import org.apache.xmlgraphics.util.dijkstra.Vertex;
@@ -75,7 +76,10 @@ public class PipelineFactory {
Iterator iter = converters.iterator();
while (iter.hasNext()) {
ImageConverter converter = (ImageConverter)iter.next();
- dir.addEdge(new ImageConversionEdge(converter));
+ Penalty penalty = Penalty.toPenalty(converter.getConversionPenalty());
+ penalty = penalty.add(
+ registry.getAdditionalPenalty(converter.getClass().getName()));
+ dir.addEdge(new ImageConversionEdge(converter, penalty));
}
converterEdgeDirectoryVersion = registry.getImageConverterModifications();
@@ -109,9 +113,34 @@ public class PipelineFactory {
*/
public ImageProviderPipeline newImageConverterPipeline(
ImageInfo imageInfo, ImageFlavor targetFlavor) {
+ ImageProviderPipeline[] candidates = determineCandidatePipelines(imageInfo, targetFlavor);
+
+ //Choose best pipeline
+ if (candidates.length > 0) {
+ Arrays.sort(candidates, new PipelineComparator());
+ ImageProviderPipeline pipeline = (ImageProviderPipeline)candidates[0];
+ if (pipeline != null && log.isDebugEnabled()) {
+ log.debug("Pipeline: " + pipeline
+ + " with penalty " + pipeline.getConversionPenalty());
+ }
+ return pipeline;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Determines all possible pipelines for the given image that can produce the requested
+ * target flavor.
+ * @param imageInfo the image information
+ * @param targetFlavor the target flavor
+ * @return the candidate pipelines
+ */
+ public ImageProviderPipeline[] determineCandidatePipelines(
+ ImageInfo imageInfo, ImageFlavor targetFlavor) {
String originalMime = imageInfo.getMimeType();
ImageImplRegistry registry = manager.getRegistry();
- ImageProviderPipeline pipeline = null;
+ List candidates = new java.util.ArrayList();
//Get snapshot to avoid concurrent modification problems (thread-safety)
DefaultEdgeDirectory dir = getEdgeDirectory();
@@ -131,12 +160,13 @@ public class PipelineFactory {
}
loader = new CompositeImageLoader(loaders);
}
- pipeline = new ImageProviderPipeline(manager.getCache(), loader);
+ ImageProviderPipeline pipeline = new ImageProviderPipeline(manager.getCache(), loader);
+ candidates.add(pipeline);
} else {
//Need to use ImageConverters
if (log.isTraceEnabled()) {
- log.trace("No ImageLoaderFactory found that can load this format directly."
- + " Trying ImageConverters instead...");
+ log.trace("No ImageLoaderFactory found that can load this format ("
+ + targetFlavor + ") directly. Trying ImageConverters instead...");
}
ImageRepresentation destination = new ImageRepresentation(targetFlavor);
@@ -144,14 +174,13 @@ public class PipelineFactory {
// --> List of resulting flavors, possibly multiple loaders
loaderFactories = registry.getImageLoaderFactories(originalMime);
if (loaderFactories != null) {
- List candidates = new java.util.ArrayList();
//Find best pipeline -> best loader
for (int i = 0, ci = loaderFactories.length; i < ci; i++) {
ImageLoaderFactory loaderFactory = loaderFactories[i];
ImageFlavor[] flavors = loaderFactory.getSupportedFlavors(originalMime);
for (int j = 0, cj = flavors.length; j < cj; j++) {
- pipeline = findPipeline(dir, flavors[j], destination);
+ ImageProviderPipeline pipeline = findPipeline(dir, flavors[j], destination);
if (pipeline != null) {
ImageLoader loader = loaderFactory.newImageLoader(flavors[j]);
pipeline.setImageLoader(loader);
@@ -159,20 +188,13 @@ public class PipelineFactory {
}
}
}
-
- Collections.sort(candidates, new PipelineComparator());
- //Build final pipeline
- if (candidates.size() > 0) {
- pipeline = (ImageProviderPipeline)candidates.get(0);
- }
}
}
- if (pipeline != null && log.isDebugEnabled()) {
- log.debug("Pipeline: " + pipeline + " with penalty " + pipeline.getConversionPenalty());
- }
- return pipeline;
+ return (ImageProviderPipeline[])candidates.toArray(
+ new ImageProviderPipeline[candidates.size()]);
}
+ /** Compares two pipelines based on their conversion penalty. */
private static class PipelineComparator implements Comparator {
public int compare(Object o1, Object o2) {
@@ -228,12 +250,21 @@ public class PipelineFactory {
*/
public ImageProviderPipeline[] determineCandidatePipelines(ImageInfo imageInfo,
ImageFlavor[] flavors) {
+ List candidates = new java.util.ArrayList();
int count = flavors.length;
- ImageProviderPipeline[] candidates = new ImageProviderPipeline[count];
for (int i = 0; i < count; i++) {
- candidates[i] = newImageConverterPipeline(imageInfo, flavors[i]);
+ //Find the best pipeline for each flavor
+ ImageProviderPipeline pipeline = newImageConverterPipeline(imageInfo, flavors[i]);
+ if (pipeline == null) {
+ continue; //No suitable pipeline found for flavor
+ }
+ Penalty p = pipeline.getConversionPenalty(this.manager.getRegistry());
+ if (!p.isInfinitePenalty()) {
+ candidates.add(pipeline);
+ }
}
- return candidates;
+ return (ImageProviderPipeline[])candidates.toArray(
+ new ImageProviderPipeline[candidates.size()]);
}
/**
@@ -245,12 +276,17 @@ public class PipelineFactory {
*/
public ImageProviderPipeline[] determineCandidatePipelines(Image sourceImage,
ImageFlavor[] flavors) {
+ List candidates = new java.util.ArrayList();
int count = flavors.length;
- ImageProviderPipeline[] candidates = new ImageProviderPipeline[count];
for (int i = 0; i < count; i++) {
- candidates[i] = newImageConverterPipeline(sourceImage, flavors[i]);
+ //Find the best pipeline for each flavor
+ ImageProviderPipeline pipeline = newImageConverterPipeline(sourceImage, flavors[i]);
+ if (pipeline != null) {
+ candidates.add(pipeline);
+ }
}
- return candidates;
+ return (ImageProviderPipeline[])candidates.toArray(
+ new ImageProviderPipeline[candidates.size()]);
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageConverter.java Thu Mar 18 08:26:30 2010
@@ -25,6 +25,7 @@ import java.util.Map;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
/**
* Defines an image converter that can convert one image representation into another.
@@ -40,6 +41,8 @@ public interface ImageConverter {
/**
* Converts an image into a different representation.
+ * <p> The new image returned shall preserve the original {@link ImageInfo} instance.
+ * Consumers can get the effective MIME type (if any) from the associated {@link ImageFlavor}.
* @param src the source image
* @param hints the conversion hints
* @return the converted image
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageImplRegistry.java Thu Mar 18 08:26:30 2010
@@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFac
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
import org.apache.xmlgraphics.util.Service;
/**
@@ -43,6 +44,9 @@ public class ImageImplRegistry {
/** logger */
protected static Log log = LogFactory.getLog(ImageImplRegistry.class);
+ /** Infinite penalty value which shall force any implementation to become ineligible. */
+ public static final int INFINITE_PENALTY = Integer.MAX_VALUE;
+
/** Holds the list of preloaders */
private List preloaders = new java.util.ArrayList();
//Content: List<ImagePreloader>
@@ -59,15 +63,29 @@ public class ImageImplRegistry {
private int converterModifications;
+ /** A Map (key: implementation classes) with additional penalties to fine-tune the registry. */
+ private Map additionalPenalties = new java.util.HashMap(); //<String, Penalty>
+ //Note: String as key chosen to avoid possible class-unloading leaks
+
/** Singleton instance */
private static ImageImplRegistry defaultInstance;
/**
+ * Main constructor. This constructor allows to disable plug-in discovery for testing purposes.
+ * @param discover true if implementation classes shall automatically be discovered.
+ */
+ public ImageImplRegistry(boolean discover) {
+ if (discover) {
+ discoverClasspathImplementations();
+ }
+ }
+
+ /**
* Main constructor.
* @see #getDefaultInstance()
*/
public ImageImplRegistry() {
- discoverClasspathImplementations();
+ this(true);
}
/**
@@ -123,7 +141,8 @@ public class ImageImplRegistry {
return holder;
}
- private class PreloaderHolder {
+ /** Holder class for registered {@link ImagePreloader} instances. */
+ private static class PreloaderHolder {
private ImagePreloader preloader;
private int identifier;
@@ -138,10 +157,14 @@ public class ImageImplRegistry {
public int compare(Object o1, Object o2) {
PreloaderHolder h1 = (PreloaderHolder)o1;
+ long p1 = h1.preloader.getPriority();
+ p1 += getAdditionalPenalty(h1.preloader.getClass().getName()).getValue();
+
PreloaderHolder h2 = (PreloaderHolder)o2;
- int p1 = h1.preloader.getPriority();
int p2 = h2.preloader.getPriority();
- int diff = p1 - p2;
+ p2 += getAdditionalPenalty(h2.preloader.getClass().getName()).getValue();
+
+ int diff = Penalty.truncate(p1 - p2);
if (diff != 0) {
return diff;
} else {
@@ -278,7 +301,8 @@ public class ImageImplRegistry {
if (!factory.isSupported(imageInfo)) {
continue;
}
- int penalty = factory.getUsagePenalty(mime, flavor);
+ ImageLoader loader = factory.newImageLoader(flavor);
+ int penalty = loader.getUsagePenalty();
if (penalty < bestPenalty) {
bestPenalty = penalty;
bestFactory = factory;
@@ -299,7 +323,7 @@ public class ImageImplRegistry {
*/
public ImageLoaderFactory[] getImageLoaderFactories(ImageInfo imageInfo, ImageFlavor flavor) {
String mime = imageInfo.getMimeType();
- Collection matches = new java.util.TreeSet(new ImageLoaderFactoryComparator(mime, flavor));
+ Collection matches = new java.util.TreeSet(new ImageLoaderFactoryComparator(flavor));
Map flavorMap = (Map)loaders.get(mime);
if (flavorMap != null) {
Iterator flavorIter = flavorMap.keySet().iterator();
@@ -326,21 +350,28 @@ public class ImageImplRegistry {
}
}
- private static class ImageLoaderFactoryComparator implements Comparator {
+ /** Comparator for {@link ImageLoaderFactory} classes. */
+ private class ImageLoaderFactoryComparator implements Comparator {
- private String mime;
private ImageFlavor targetFlavor;
- public ImageLoaderFactoryComparator(String mime, ImageFlavor targetFlavor) {
- this.mime = mime;
+ public ImageLoaderFactoryComparator(ImageFlavor targetFlavor) {
this.targetFlavor = targetFlavor;
}
public int compare(Object o1, Object o2) {
ImageLoaderFactory f1 = (ImageLoaderFactory)o1;
+ ImageLoader l1 = f1.newImageLoader(targetFlavor);
+ long p1 = l1.getUsagePenalty();
+ p1 += getAdditionalPenalty(l1.getClass().getName()).getValue();
+
ImageLoaderFactory f2 = (ImageLoaderFactory)o2;
+ ImageLoader l2 = f2.newImageLoader(targetFlavor);
+ long p2 = l2.getUsagePenalty();
+ p2 = getAdditionalPenalty(l2.getClass().getName()).getValue();
+
//Lowest penalty first
- return f1.getUsagePenalty(mime, targetFlavor) - f2.getUsagePenalty(mime, targetFlavor);
+ return Penalty.truncate(p1 - p2);
}
}
@@ -370,4 +401,31 @@ public class ImageImplRegistry {
return null;
}
+ /**
+ * Sets an additional penalty for a particular implementation class for any of the interface
+ * administered by this registry class. No checking is performed to verify if the className
+ * parameter is valid.
+ * @param className the fully qualified class name of the implementation class
+ * @param penalty the additional penalty or null to clear any existing value
+ */
+ public void setAdditionalPenalty(String className, Penalty penalty) {
+ if (penalty != null) {
+ this.additionalPenalties.put(className, penalty);
+ } else {
+ this.additionalPenalties.remove(className);
+ }
+ this.lastPreloaderSort = -1; //Force resort, just in case this was a preloader
+ }
+
+ /**
+ * Returns the additional penalty value set for a particular implementation class.
+ * If no such value is set, 0 is returned.
+ * @param className the fully qualified class name of the implementation class
+ * @return the additional penalty value
+ */
+ public Penalty getAdditionalPenalty(String className) {
+ Penalty p = (Penalty)this.additionalPenalties.get(className);
+ return (p != null ? p : Penalty.ZERO_PENALTY);
+ }
+
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoader.java Thu Mar 18 08:26:30 2010
@@ -34,6 +34,11 @@ import org.apache.xmlgraphics.image.load
*/
public interface ImageLoader {
+ /** Used if the loading penalty is negligible (image doesn't need to be decoded). */
+ int NO_LOADING_PENALTY = 0;
+ /** Default/Medium conversion penalty (if there's some effort to load the image format) */
+ int MEDIUM_LOADING_PENALTY = 10;
+
/**
* Loads and returns an image.
* @param info the image info object indicating the image
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/spi/ImageLoaderFactory.java Thu Mar 18 08:26:30 2010
@@ -70,6 +70,7 @@ public interface ImageLoaderFactory {
* @param mime the MIME type
* @param flavor the target image flavor
* @return the usage penalty (must be a non-negative integer)
+ * @deprecated Redundancy with {@link ImageLoader#getUsagePenalty()}
*/
int getUsagePenalty(String mime, ImageFlavor flavor);
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/ImageUtil.java Thu Mar 18 08:26:30 2010
@@ -317,6 +317,7 @@ public class ImageUtil {
new Float(session.getParentContext().getSourceResolution()));
hints.put(ImageProcessingHints.TARGET_RESOLUTION,
new Float(session.getTargetResolution()));
+ hints.put(ImageProcessingHints.IMAGE_SESSION_CONTEXT, session);
return hints;
}
Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java?rev=924666&view=auto
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java Thu Mar 18 08:26:30 2010
@@ -0,0 +1,106 @@
+/*
+ * 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.xmlgraphics.image.loader.util;
+
+/**
+ * Immutable class representing a penalty value. It's valid value range is that of an
+ * {@link Integer}, but giving {@link Integer#MAX_VALUE} a special meaning: it means infinite
+ * penalty, i.e. a candidate with this penalty will be excluded from any choice.
+ */
+public class Penalty {
+
+ public static final Penalty ZERO_PENALTY = new Penalty(0);
+ public static final Penalty INFINITE_PENALTY = new Penalty(Integer.MAX_VALUE);
+
+ private final int value;
+
+ /**
+ * Turns a penalty value into a penaly object.
+ * @param value the penalty value
+ * @return the penalty object
+ */
+ public static Penalty toPenalty(int value) {
+ switch (value) {
+ case 0:
+ return ZERO_PENALTY;
+ case Integer.MAX_VALUE:
+ return INFINITE_PENALTY;
+ default:
+ return new Penalty(value);
+ }
+ }
+
+ private Penalty(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Adds a penalty to this one and returns the combined penalty.
+ * @param value the penalty value to add
+ * @return the resulting penalty
+ */
+ public Penalty add(Penalty value) {
+ return add(value.getValue());
+ }
+
+ /**
+ * Adds a penalty to this one and returns the combined penalty.
+ * @param value the penalty value to add
+ * @return the resulting penalty
+ */
+ public Penalty add(int value) {
+ long p = (long)getValue() + value;
+ return toPenalty(truncate(p));
+ }
+
+ /**
+ * Returns the penalty value.
+ * @return the penalty value
+ */
+ public int getValue() {
+ return this.value;
+ }
+
+ /**
+ * Indicates whether this is an infinite penalty, meaning that a solution with this penalty
+ * is effectively ineligible.
+ * @return true if this is an infinite penalty
+ */
+ public boolean isInfinitePenalty() {
+ return (value == Integer.MAX_VALUE);
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "Penalty: " + (isInfinitePenalty() ? "INF" : Integer.toString(getValue()));
+ }
+
+ /**
+ * Truncates the long penalty value to an integer without sign side-effects.
+ * @param penalty the penalty value as a long
+ * @return the penalty value as an int
+ */
+ public static int truncate(long penalty) {
+ penalty = Math.min(Integer.MAX_VALUE, penalty);
+ penalty = Math.max(Integer.MIN_VALUE, penalty);
+ return (int)penalty;
+ }
+
+}
Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/util/Penalty.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java?rev=924666&r1=924665&r2=924666&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java (original)
+++ xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/MockImageContext.java Thu Mar 18 08:26:30 2010
@@ -19,6 +19,16 @@
package org.apache.xmlgraphics.image.loader;
+import org.apache.xmlgraphics.image.loader.impl.ImageConverterBitmap2G2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageConverterBuffered2Rendered;
+import org.apache.xmlgraphics.image.loader.impl.ImageConverterG2D2Bitmap;
+import org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryInternalTIFF;
+import org.apache.xmlgraphics.image.loader.impl.ImageLoaderFactoryRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.PreloaderEPS;
+import org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG;
+import org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF;
+import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
+
/**
* Mock implementation for testing.
*/
@@ -26,24 +36,64 @@ public class MockImageContext implements
private static MockImageContext instance;
- private ImageManager imageManager = new ImageManager(this);
+ private ImageManager imageManager;
+ /**
+ * Returns a singleton instance of the mock image context.
+ * @return the singleton
+ */
public static MockImageContext getInstance() {
if (instance == null) {
- instance = new MockImageContext();
+ instance = new MockImageContext(true);
}
return instance;
}
+ /**
+ * Returns an image context for testing that only contains platform- and classpath-independent
+ * implementations so consistent test results can be obtained irrespective of the test
+ * environment.
+ * @return a new image context
+ */
+ public static MockImageContext newSafeInstance() {
+ MockImageContext ic = new MockImageContext(false);
+ ImageImplRegistry registry = ic.getImageManager().getRegistry();
+ registry.registerPreloader(new PreloaderTIFF());
+ registry.registerPreloader(new PreloaderJPEG());
+ registry.registerPreloader(new PreloaderEPS());
+ registry.registerLoaderFactory(new ImageLoaderFactoryInternalTIFF());
+ registry.registerLoaderFactory(new ImageLoaderFactoryRawCCITTFax());
+ registry.registerConverter(new ImageConverterBitmap2G2D());
+ registry.registerConverter(new ImageConverterG2D2Bitmap());
+ registry.registerConverter(new ImageConverterBuffered2Rendered());
+ return ic;
+ }
+
+ /**
+ * Creates a new mock image context.
+ * @param discover true to enable plug-in discovery
+ */
+ public MockImageContext(boolean discover) {
+ this.imageManager = new ImageManager(new ImageImplRegistry(discover), this);
+ }
+
/** {@inheritDoc} */
public float getSourceResolution() {
return 72;
}
+ /**
+ * Returns the image manager.
+ * @return the image manager
+ */
public ImageManager getImageManager() {
return this.imageManager;
}
+ /**
+ * Creates a new image session context.
+ * @return the image session context
+ */
public ImageSessionContext newSessionContext() {
return new MockImageSessionContext(this);
}
Added: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java?rev=924666&view=auto
==============================================================================
--- xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java (added)
+++ xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java Thu Mar 18 08:26:30 2010
@@ -0,0 +1,78 @@
+/*
+ * 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.xmlgraphics.image.loader;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlgraphics.image.loader.util.Penalty;
+
+/**
+ * Tests for the {@link Penalty}.
+ */
+public class PenaltyTestCase extends TestCase {
+
+ /**
+ * Tests for penalty handling.
+ * @throws Exception if an error occurs
+ */
+ public void testTruncatePenalty() throws Exception {
+ assertEquals(0, Penalty.truncate(0));
+ long penalty = Integer.MAX_VALUE;
+ assertEquals(Integer.MAX_VALUE, Penalty.truncate(penalty));
+
+ //Force integer wrap-around
+ penalty++;
+ assertEquals(Integer.MAX_VALUE, Penalty.truncate(penalty));
+ //For comparison, normal casting does this
+ assertEquals(Integer.MIN_VALUE, (int)penalty);
+
+ //Now on the other end of the spectrum...
+ penalty = Integer.MIN_VALUE;
+ assertEquals(Integer.MIN_VALUE, Penalty.truncate(penalty));
+
+ //Force integer wrap-around
+ penalty -= 500;
+ assertEquals(Integer.MIN_VALUE, Penalty.truncate(penalty));
+ //For comparison, normal casting does this
+ assertEquals(Integer.MAX_VALUE - 499, (int)penalty);
+ }
+
+ /**
+ * Tests for the {@link Penalty} class.
+ * @throws Exception if an error occurs
+ */
+ public void testPenalty() throws Exception {
+ Penalty p1 = Penalty.toPenalty(100);
+ assertEquals(100, p1.getValue());
+ Penalty p2 = p1.add(Penalty.toPenalty(50));
+ assertEquals(150, p2.getValue());
+
+ p1 = Penalty.toPenalty(0);
+ assertEquals(0, p1.getValue());
+
+ p1 = Penalty.INFINITE_PENALTY;
+ assertEquals(Integer.MAX_VALUE, p1.getValue());
+ assertTrue(p1.isInfinitePenalty());
+ p2 = p1.add(p2);
+ assertEquals(Integer.MAX_VALUE, p2.getValue());
+ assertTrue(p2.isInfinitePenalty());
+ }
+
+}
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PenaltyTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java?rev=924666&view=auto
==============================================================================
--- xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java (added)
+++ xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java Thu Mar 18 08:26:30 2010
@@ -0,0 +1,199 @@
+/*
+ * 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.xmlgraphics.image.loader;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
+import org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.mocks.MockImageLoaderFactoryTIFF;
+import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline;
+import org.apache.xmlgraphics.image.loader.pipeline.PipelineFactory;
+import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
+
+/**
+ * Tests the pipeline factory.
+ */
+public class PipelineFactoryTestCase extends TestCase {
+
+ /**
+ * Tests the pipeline factory by checking to load a TIFF image.
+ * @throws Exception if an error occurs
+ */
+ public void testPipelineFactoryPlain() throws Exception {
+ MockImageContext imageContext = MockImageContext.newSafeInstance();
+ ImageManager manager = imageContext.getImageManager();
+ PipelineFactory pFactory = new PipelineFactory(manager);
+
+ //Input is some TIFF file
+ ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff");
+
+ //We want a G2D image
+ ImageFlavor targetFlavor = ImageFlavor.GRAPHICS2D;
+
+ ImageProviderPipeline pipeline = pFactory.newImageConverterPipeline(
+ imageInfo, targetFlavor);
+ assertNotNull(pipeline);
+ assertEquals(pipeline.getTargetFlavor(), targetFlavor);
+
+ //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion
+ assertEquals(1010, pipeline.getConversionPenalty());
+ assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor());
+ if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+
+ ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines(
+ imageInfo, new ImageFlavor[] {targetFlavor});
+ assertEquals(1, candidates.length);
+
+ //Now add another implementation that poses as TIFF loader
+ imageContext.getImageManager().getRegistry().registerLoaderFactory(
+ new MockImageLoaderFactoryTIFF());
+
+ candidates = pFactory.determineCandidatePipelines(
+ imageInfo, targetFlavor);
+ assertEquals(3, candidates.length);
+ //3 because the mock impl provides Buffered- and RenderedImage capabilities
+
+ pipeline = pFactory.newImageConverterPipeline(imageInfo, targetFlavor);
+ assertNotNull(pipeline);
+ assertEquals(pipeline.getTargetFlavor(), targetFlavor);
+
+ //Assuming mock impl without penalty + 10 for the conversion
+ assertEquals(10, pipeline.getConversionPenalty());
+ assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor());
+ if (pipeline.toString().indexOf(MockImageLoaderFactoryTIFF.class.getName()) < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ }
+
+ /**
+ * Similar test as above but here we take raw CCITT loading into consideration, too.
+ * @throws Exception if an error occurs
+ */
+ public void testPipelineFactoryImageInfoDependency() throws Exception {
+ MockImageContext imageContext = MockImageContext.newSafeInstance();
+ ImageManager manager = imageContext.getImageManager();
+ PipelineFactory pFactory = new PipelineFactory(manager);
+
+ //Input is some TIFF file with CCITT Group 4 compression
+ ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff");
+ imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", new Integer(1));
+ imageInfo.getCustomObjects().put("TIFF_COMPRESSION", new Integer(TIFFImage.COMP_FAX_G4_2D));
+
+ //We want either a G2D image or a raw CCITT image
+ ImageFlavor[] targetFlavors = new ImageFlavor[] {
+ ImageFlavor.GRAPHICS2D, ImageFlavor.RAW_CCITTFAX};
+
+ ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines(
+ imageInfo, targetFlavors);
+ assertNotNull(candidates);
+ assertEquals(2, candidates.length);
+
+ ImageProviderPipeline pipeline = manager.choosePipeline(candidates);
+
+ //0 penalty because the raw loader is the most efficient choice here
+ assertEquals(0, pipeline.getConversionPenalty());
+ assertEquals(ImageFlavor.RAW_CCITTFAX, pipeline.getTargetFlavor());
+ if (pipeline.toString().indexOf("LoaderRawCCITTFax") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+
+ //Now, we set this to a multi-strip TIFF which should disable the raw loader
+ imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", new Integer(7));
+
+ candidates = pFactory.determineCandidatePipelines(
+ imageInfo, targetFlavors);
+ assertNotNull(candidates);
+ assertEquals(1, candidates.length);
+
+ pipeline = manager.choosePipeline(candidates);
+
+ //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion
+ assertEquals(1010, pipeline.getConversionPenalty());
+ assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor());
+ if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ }
+
+ /**
+ * Similar test as above but now we're playing with additional penalties in the registry.
+ * @throws Exception if an error occurs
+ */
+ public void testPipelineFactoryAdditionalPenalty() throws Exception {
+ MockImageContext imageContext = MockImageContext.newSafeInstance();
+ ImageManager manager = imageContext.getImageManager();
+ PipelineFactory pFactory = new PipelineFactory(manager);
+
+ //Adding additional penalty for CCITT loading
+ ImageImplRegistry registry = imageContext.getImageManager().getRegistry();
+ registry.setAdditionalPenalty(ImageLoaderRawCCITTFax.class.getName(),
+ Penalty.toPenalty(10000));
+
+ //Input is some TIFF file with CCITT Group 4 compression
+ ImageInfo imageInfo = new ImageInfo("test:tiff", "image/tiff");
+ imageInfo.getCustomObjects().put("TIFF_STRIP_COUNT", new Integer(1));
+ imageInfo.getCustomObjects().put("TIFF_COMPRESSION", new Integer(TIFFImage.COMP_FAX_G4_2D));
+
+ //We want either a G2D image or a raw CCITT image
+ ImageFlavor[] targetFlavors = new ImageFlavor[] {
+ ImageFlavor.GRAPHICS2D, ImageFlavor.RAW_CCITTFAX};
+
+ ImageProviderPipeline[] candidates = pFactory.determineCandidatePipelines(
+ imageInfo, targetFlavors);
+ assertNotNull(candidates);
+ assertEquals(2, candidates.length);
+
+ ImageProviderPipeline pipeline = manager.choosePipeline(candidates);
+
+ //penalty for internal TIFF implementation (fallback role) is 1000 + 10 for the conversion
+ assertEquals(1010, pipeline.getConversionPenalty());
+ assertEquals(ImageFlavor.GRAPHICS2D, pipeline.getTargetFlavor());
+ if (pipeline.toString().indexOf("LoaderInternalTIFF") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+ if (pipeline.toString().indexOf("ImageConverterBitmap2G2D") < 0) {
+ fail("Chose the wrong pipeline: " + pipeline.toString());
+ }
+
+ //Now set an infinite penalty making the solution ineligible
+ registry.setAdditionalPenalty(ImageLoaderRawCCITTFax.class.getName(),
+ Penalty.INFINITE_PENALTY);
+
+ candidates = pFactory.determineCandidatePipelines(imageInfo, targetFlavors);
+ assertNotNull(candidates);
+ assertEquals(1, candidates.length);
+ //While earlier 2 candidates were returned, here we only get 1 because of the infinite
+ //penalty.
+ }
+
+}
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/PipelineFactoryTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java?rev=924666&view=auto
==============================================================================
--- xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java (added)
+++ xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java Thu Mar 18 08:26:30 2010
@@ -0,0 +1,108 @@
+/*
+ * 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.xmlgraphics.image.loader.mocks;
+
+import java.io.IOException;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoaderFactory;
+import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
+import org.apache.xmlgraphics.util.MimeConstants;
+
+/**
+ * Mock implementation posing as a TIFF-compatible loader.
+ */
+public class MockImageLoaderFactoryTIFF extends AbstractImageLoaderFactory {
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedFlavors(String mime) {
+ return new ImageFlavor[] {ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE};
+ }
+
+ /** {@inheritDoc} */
+ public String[] getSupportedMIMETypes() {
+ return new String[] {MimeConstants.MIME_TIFF};
+ }
+
+ private void checkSuppportedFlavor(String mime, ImageFlavor flavor) {
+ ImageFlavor[] flavors = getSupportedFlavors(mime);
+ boolean found = false;
+ for (int i = 0; i < flavors.length; i++) {
+ if (flavors[i].equals(flavor)) {
+ found = true;
+ break;
+ }
+ }
+ Assert.assertTrue(found);
+ }
+
+ /** {@inheritDoc} */
+ public boolean isAvailable() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSupported(ImageInfo imageInfo) {
+ return MimeConstants.MIME_TIFF.equals(imageInfo.getMimeType());
+ }
+
+ /** {@inheritDoc} */
+ public ImageLoader newImageLoader(ImageFlavor targetFlavor) {
+ checkSuppportedFlavor(MimeConstants.MIME_TIFF, targetFlavor);
+ return new ImageLoaderImpl(targetFlavor);
+ }
+
+ /** Mock image loader implementation. */
+ private static class ImageLoaderImpl implements ImageLoader {
+
+ private ImageFlavor flavor;
+
+ public ImageLoaderImpl(ImageFlavor flavor) {
+ this.flavor = flavor;
+ }
+
+ public ImageFlavor getTargetFlavor() {
+ return flavor;
+ }
+
+ public int getUsagePenalty() {
+ return 0;
+ }
+
+ public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
+ throws ImageException, IOException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public Image loadImage(ImageInfo info, ImageSessionContext session) throws ImageException,
+ IOException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ }
+
+}
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/image/loader/mocks/MockImageLoaderFactoryTIFF.java
------------------------------------------------------------------------------
svn:keywords = Id
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org