changeset 906:28d007673346

really works with streams now. (only with ImageLoaderDocuImage with reuseReader=true)
author robcast
date Wed, 04 May 2011 15:04:38 +0200
parents afd82fe0c48a
children 52598b5e5518
files common/src/main/java/digilib/image/DocuImage.java common/src/main/java/digilib/image/DocuImageImpl.java common/src/main/java/digilib/image/ImageJobDescription.java common/src/main/java/digilib/image/ImageLoaderDocuImage.java common/src/main/java/digilib/image/ImageOpException.java common/src/main/java/digilib/image/ImageWorker.java common/src/main/java/digilib/image/JAIDocuImage.java common/src/main/java/digilib/image/JAIImageLoaderDocuImage.java common/src/main/java/digilib/io/FileOpException.java common/src/main/java/digilib/io/ImageCacheStream.java common/src/main/java/digilib/io/ImageStream.java common/src/main/java/digilib/servlet/DigilibConfiguration.java
diffstat 12 files changed, 201 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/common/src/main/java/digilib/image/DocuImage.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/DocuImage.java	Wed May 04 15:04:38 2011 +0200
@@ -25,7 +25,6 @@
 import java.io.OutputStream;
 import java.util.Iterator;
 
-import javax.servlet.ServletException;
 
 import digilib.io.FileOpException;
 import digilib.io.ImageInput;
@@ -72,11 +71,11 @@
 	 * 
 	 * @param mt mime-type of the image to be sent.
 	 * @param ostream OutputStream where the image is sent.
-	 * @throws ServletException Exception thrown on sending data.
 	 * @throws ImageOpException Exception in other cases.
+	 * @throws FileOpException Exception on sending data
 	 */
 	public void writeImage(String mt, OutputStream ostream)
-		throws ServletException, ImageOpException;
+		throws ImageOpException, FileOpException;
 
 	/** The width of the current image in pixel.
 	 * 
--- a/common/src/main/java/digilib/image/DocuImageImpl.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/DocuImageImpl.java	Wed May 04 15:04:38 2011 +0200
@@ -28,7 +28,6 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import javax.servlet.ServletException;
 
 import org.apache.log4j.Logger;
 
@@ -193,7 +192,7 @@
     public abstract void scale(double scaleX, double scaleY) throws ImageOpException;
 
     public abstract void writeImage(String mt, OutputStream ostream)
-            throws ServletException, ImageOpException;
+            throws ImageOpException, FileOpException;
 
 	
 }
--- a/common/src/main/java/digilib/image/ImageJobDescription.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/ImageJobDescription.java	Wed May 04 15:04:38 2011 +0200
@@ -39,6 +39,7 @@
 	ImageInput input = null;
 	ImageSet imageSet = null;
 	DocuDirectory fileDir = null;
+	DocuImage docuImage = null;
 	String filePath = null;
 	ImageSize expectedSourceSize = null;
 	Float scaleXY = null;
@@ -142,7 +143,15 @@
 		return mimeType;
 	}
 	
-	/** Returns the ImageInput to use.
+	/**
+     * @param input the input to set
+     */
+    public void setInput(ImageInput input) {
+        this.input = input;
+    }
+
+
+    /** Returns the ImageInput to use.
 	 * @return
 	 * @throws IOException
 	 */
@@ -560,4 +569,20 @@
 			|| (!(isLoresOnly() || isHiresOnly()) && is.fitsIn(ess)));
 		return ! nt;
 	}
+
+
+    /**
+     * @return the docuImage
+     */
+    public DocuImage getDocuImage() {
+        return docuImage;
+    }
+
+
+    /**
+     * @param docuImage the docuImage to set
+     */
+    public void setDocuImage(DocuImage docuImage) {
+        this.docuImage = docuImage;
+    }
 }
\ No newline at end of file
--- a/common/src/main/java/digilib/image/ImageLoaderDocuImage.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/ImageLoaderDocuImage.java	Wed May 04 15:04:38 2011 +0200
@@ -52,7 +52,6 @@
 import javax.imageio.stream.FileImageInputStream;
 import javax.imageio.stream.ImageInputStream;
 import javax.imageio.stream.ImageOutputStream;
-import javax.servlet.ServletException;
 
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
@@ -65,6 +64,12 @@
 	/** image object */
 	protected BufferedImage img;
 	
+	/** the reader object */
+	protected ImageReader reader = null;
+	
+    /** try to reuse reader object */
+    public boolean reuseReader = false;
+    
 	/** interpolation type */
 	protected RenderingHints renderHint = null;
 
@@ -172,7 +177,7 @@
             int w = 0;
             try {
                 if (img == null) {
-                    ImageReader reader = getReader(input);
+                    reader = getReader(input);
                     // get size from ImageReader
                     h = reader.getHeight(0);
                     w = reader.getWidth(0);
@@ -197,13 +202,15 @@
 
     /* Check image size and type and store in ImageInput */
     public ImageInput identify(ImageInput input) throws IOException {
-        // try parent method first
-        ImageInput ii = super.identify(input);
-        if (ii != null) {
-            return ii;
+        ImageInput ii = null;
+        if (!reuseReader) {
+            // try parent method first
+            ii = super.identify(input);
+            if (ii != null) {
+                return ii;
+            }
         }
         logger.debug("identifying (ImageIO) " + input);
-        ImageReader reader = null;
         try {
             /*
              * try ImageReader
@@ -229,7 +236,7 @@
             logger.error("ImageLoaderDocuimage unable to identify:", e);
             return null;
         } finally {
-            if (reader != null) {
+            if (!reuseReader && reader != null) {
                 reader.dispose();
             }
         }
@@ -246,7 +253,10 @@
 		        img = ImageIO.read(ii.getFile());
 		    }
 		} catch (IOException e) {
-			throw new FileOpException("Error reading image.");
+			throw new FileOpException("Error reading image!", e);
+		}
+		if (img == null) {
+		    throw new FileOpException("Unable to read image!");
 		}
 	}
 
@@ -257,9 +267,13 @@
 	 */
 	public ImageReader getReader(ImageInput input) throws IOException {
 		logger.debug("get ImageReader for " + input);
+		if (reuseReader && reader != null) {
+		    logger.debug("reuseing ImageReader");
+		    return reader;
+		}
 		ImageInputStream istream = null;
 		if (input.hasImageInputStream()) {
-			// stream input
+			// ImageInputStream input
 			istream = input.getImageInputStream();
 		} else if (input.hasFile()) {
 			// file only input
@@ -302,9 +316,9 @@
 			throws FileOpException {
 		logger.debug("loadSubimage");
         this.input = ii;
-        ImageReader reader = null;
+        //ImageReader reader = null;
 		try {
-			reader = getReader(ii);
+		    reader = getReader(ii);
 			// set up reader parameters
 			ImageReadParam readParam = reader.getDefaultReadParam();
 			readParam.setSourceRegion(region);
@@ -323,9 +337,9 @@
 	            img = dest;
 	        } */
 		} catch (IOException e) {
-			throw new FileOpException("Unable to load File!");
+			throw new FileOpException("Unable to load File!", e);
 		} finally {
-		    if (reader != null) {
+		    if (!reuseReader && reader != null) {
 		        reader.dispose();
 		    }
 		}
@@ -333,7 +347,7 @@
 
 	/* write image of type mt to Stream */
 	public void writeImage(String mt, OutputStream ostream)
-			throws ImageOpException, ServletException {
+			throws ImageOpException, FileOpException {
 		logger.debug("writeImage");
 		// setup output
 		ImageWriter writer = null;
@@ -382,7 +396,7 @@
 
 		} catch (IOException e) {
 		    logger.error("Error writing image:", e);
-			throw new ServletException("Error writing image:", e);
+			throw new FileOpException("Error writing image!", e);
 		}
 		// TODO: should we: finally { writer.dispose(); }
 	}
@@ -638,6 +652,9 @@
     }
 
 	public void dispose() {
+	    if (reader != null) {
+	        reader.dispose();
+	    }
 	    // is this necessary?
 		img = null;
 	}
--- a/common/src/main/java/digilib/image/ImageOpException.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/ImageOpException.java	Wed May 04 15:04:38 2011 +0200
@@ -22,7 +22,7 @@
 
 public class ImageOpException extends Exception {
 
-	private static final long serialVersionUID = -8662921779682407942L;
+    private static final long serialVersionUID = -8662921779682407942L;
 
 	public ImageOpException() {
 	}
@@ -30,4 +30,9 @@
 	public ImageOpException(String s) {
 		super(s);
 	}
+
+	public ImageOpException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
 }
--- a/common/src/main/java/digilib/image/ImageWorker.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/ImageWorker.java	Wed May 04 15:04:38 2011 +0200
@@ -37,12 +37,12 @@
         logger.debug("image worker starting");
         long startTime = System.currentTimeMillis();
 
-        /* crop and scale image */
-
-        // new DocuImage instance
-        DocuImage docuImage = DigilibConfiguration.getDocuImageInstance();
+        DocuImage docuImage = jobinfo.getDocuImage();
         if (docuImage == null) {
-            throw new ImageOpException("Unable to load DocuImage class!");
+            docuImage = DigilibConfiguration.getDocuImageInstance();
+            if (docuImage == null) {
+                throw new ImageOpException("Unable to load DocuImage class!");
+            }
         }
 
         // set interpolation quality
--- a/common/src/main/java/digilib/image/JAIDocuImage.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/JAIDocuImage.java	Wed May 04 15:04:38 2011 +0200
@@ -39,7 +39,6 @@
 import javax.media.jai.RenderedOp;
 import javax.media.jai.operator.TransposeDescriptor;
 import javax.media.jai.operator.TransposeType;
-import javax.servlet.ServletException;
 
 import com.sun.media.jai.codec.ImageCodec;
 
@@ -188,7 +187,7 @@
 	}
 
 	/* Write the current image to an OutputStream. */
-	public void writeImage(String mt, OutputStream ostream) throws ServletException, ImageOpException {
+	public void writeImage(String mt, OutputStream ostream) throws ImageOpException, FileOpException {
 		try {
 			// setup output
 			ParameterBlock pb3 = new ParameterBlock();
@@ -207,7 +206,7 @@
 
 		} catch (RuntimeException e) {
 		    // JAI likes to throw RuntimeExceptions
-			throw new ServletException("Error writing image:", e);
+			throw new FileOpException("Error writing image: "+e);
 		}
 	}
 
--- a/common/src/main/java/digilib/image/JAIImageLoaderDocuImage.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/image/JAIImageLoaderDocuImage.java	Wed May 04 15:04:38 2011 +0200
@@ -35,7 +35,6 @@
 import javax.imageio.stream.FileImageInputStream;
 import javax.imageio.stream.ImageInputStream;
 import javax.media.jai.JAI;
-import javax.servlet.ServletException;
 
 import digilib.io.FileOpException;
 import digilib.io.ImageInput;
@@ -173,7 +172,7 @@
 
 	/* Write the current image to an OutputStream. */
 	public void writeImage(String mt, OutputStream ostream)
-		throws ImageOpException, ServletException {
+		throws ImageOpException, FileOpException {
 		logger.debug("writeImage");
 		try {
 			// setup output
@@ -191,7 +190,7 @@
 			// render output
 			JAI.create("ImageWrite", pb3);
 		} catch (RuntimeException e) {
-			throw new ServletException("Error writing image.");
+			throw new FileOpException("Error writing image.");
 		}
 	}
 
--- a/common/src/main/java/digilib/io/FileOpException.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/io/FileOpException.java	Wed May 04 15:04:38 2011 +0200
@@ -32,4 +32,8 @@
 	public FileOpException(String s) {
 		super(s);
 	}
+
+    public FileOpException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
--- a/common/src/main/java/digilib/io/ImageCacheStream.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/io/ImageCacheStream.java	Wed May 04 15:04:38 2011 +0200
@@ -3,10 +3,11 @@
  */
 package digilib.io;
 
+import java.io.IOException;
 import java.io.InputStream;
 
+import javax.imageio.ImageIO;
 import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.MemoryCacheImageInputStream;
 
 /**
  * @author casties
@@ -14,8 +15,24 @@
  */
 public class ImageCacheStream extends ImageStream {
 
-    public ImageCacheStream(InputStream stream, String mimeType) {
+    private ImageInputStream iis = null;
+    
+    /** Create ImageCacheStream from InputStream and mime-type.
+     * 
+     * @param stream
+     * @param mimeType
+     * @throws IOException 
+     */
+    public ImageCacheStream(InputStream stream, String mimeType) throws IOException {
         super(stream, mimeType);
+        /*
+         * Type of stream backing configured via ImageIO.setUseCache(). 
+         * [...] In general, it is preferable to
+         * use a FileCacheImageInputStream when reading from a regular
+         * InputStream. This class is provided for cases where it is not
+         * possible to create a writable temporary file.
+         */
+        iis = ImageIO.createImageInputStream(stream);
     }
 
     /*
@@ -35,14 +52,6 @@
      */
     @Override
     public ImageInputStream getImageInputStream() {
-        /*
-         * TODO: which type of stream backing? 
-         * In general, it is preferable to
-         * use a FileCacheImageInputStream when reading from a regular
-         * InputStream. This class is provided for cases where it is not
-         * possible to create a writable temporary file.
-         */
-        ImageInputStream iis = new MemoryCacheImageInputStream(this.stream);
         return iis;
     }
 
--- a/common/src/main/java/digilib/io/ImageStream.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/io/ImageStream.java	Wed May 04 15:04:38 2011 +0200
@@ -13,6 +13,11 @@
 
     protected InputStream stream = null;
 
+    /** Create ImageStream from InputStream and String.
+     * 
+     * @param stream
+     * @param mimeType mime-type
+     */
     public ImageStream(InputStream stream, String mimeType) {
         this.stream = stream;
         this.mimetype = mimeType;
--- a/common/src/main/java/digilib/servlet/DigilibConfiguration.java	Tue May 03 12:18:08 2011 +0200
+++ b/common/src/main/java/digilib/servlet/DigilibConfiguration.java	Wed May 04 15:04:38 2011 +0200
@@ -34,84 +34,115 @@
 /**
  * Class to hold the digilib servlet configuration parameters. The parameters
  * can be read from the digilib-config file and be passed to other servlets or
- * beans. <br>errorImgFileName: image file to send in case of error. <br>
- * denyImgFileName: image file to send if access is denied. <br>baseDirs:
- * array of base directories in order of preference (prescaled versions first).
- * <br>useAuth: use authentication information. <br>authConfPath:
- * authentication configuration file. <br>... <br>
+ * beans. <br>
+ * errorImgFileName: image file to send in case of error. <br>
+ * denyImgFileName: image file to send if access is denied. <br>
+ * baseDirs: array of base directories in order of preference (prescaled
+ * versions first). <br>
+ * useAuth: use authentication information. <br>
+ * authConfPath: authentication configuration file. <br>
+ * ... <br>
  * 
  * @author casties
- *  
+ * 
  */
-public abstract class DigilibConfiguration extends ParameterMap {
+public class DigilibConfiguration extends ParameterMap {
 
-	/** DocuImage class instance */
-	protected static Class<DocuImageImpl> docuImageClass = null;
+    /** DocuImage class instance */
+    protected static Class<DocuImageImpl> docuImageClass = null;
 
-	/** Log4J logger */
-	protected Logger logger = Logger.getLogger("digilib.config");
+    /** Log4J logger */
+    protected Logger logger = Logger.getLogger("digilib.config");
 
-	/**
-	 * Default constructor defines all parameters and their default values.
-	 *  
-	 */
-	public DigilibConfiguration() {
-		super(20);
-		// we start with a default logger config
-		BasicConfigurator.configure();
-		initParams();
-	}
+    /**
+     * Default constructor defines all parameters and their default values.
+     * 
+     */
+    public DigilibConfiguration() {
+        super(20);
+        // we start with a default logger config
+        BasicConfigurator.configure();
+        initParams();
+    }
 
-	/**
+    /** Definition of parameters and default values.
 	 * 
 	 */
-	protected void initParams() {
-		/*
-		 * Definition of parameters and default values. System parameters that
-		 * are not read from config file have a type 's'.
-		 */
-	}
+    protected void initParams() {
+        /*
+         * Definition of parameters and default values. System parameters that
+         * are not read from config file have a type 's'.
+         */
+        // digilib servlet version
+        newParameter("digilib.version", "2.0b1", null, 's');
+        // DocuImage class instance
+        newParameter("servlet.docuimage.class",
+                digilib.image.ImageLoaderDocuImage.class, null, 's');
+        // sending image files as-is allowed
+        newParameter("sendfile-allowed", Boolean.TRUE, null, 'f');
+        // Type of DocuImage instance
+        newParameter("docuimage-class", "digilib.image.ImageLoaderDocuImage", null, 'f');
+        // degree of subsampling on image load
+        newParameter("subsample-minimum", new Float(2f), null, 'f');
+        // default scaling quality
+        newParameter("default-quality", new Integer(1), null, 'f');
+        // maximum destination image size (0 means no limit)
+        newParameter("max-image-size", new Integer(0), null, 'f');
+        // allow image toolkit to use disk cache
+        newParameter("img-diskcache-allowed", Boolean.TRUE, null, 'f');
+        // default type of error message (image, text, code)
+        newParameter("default-errmsg-type", "image", null, 'f');
 
-	/**
-	 * Creates a new DocuImage instance.
-	 * 
-	 * The type of DocuImage is specified by docuimage-class.
-	 * 
-	 * @return DocuImage
-	 */
+        // initialise static DocuImage class instance
+        try {
+            DigilibConfiguration.docuImageClass = (Class<DocuImageImpl>) Class.forName(getAsString("docuimage-class"));
+        } catch (ClassNotFoundException e) {
+            logger.error("Unable to set docuImageClass!");
+        }
+    }
+
+    /**
+     * Creates a new DocuImage instance.
+     * 
+     * The type of DocuImage is specified by docuimage-class.
+     * 
+     * @return DocuImage
+     */
     public static DocuImage getDocuImageInstance() {
-		DocuImageImpl di = null;
-		try {
-			di = docuImageClass.newInstance();
-		} catch (Exception e) {
-		}
-		return di;
-	}
+        DocuImageImpl di = null;
+        try {
+            di = docuImageClass.newInstance();
+        } catch (Exception e) {
+        }
+        return di;
+    }
 
-	/**
+    /**
      * Check image size and type and store in ImageFile imgf
      * 
-	 * @param imgf
-	 * @return
-	 * @throws IOException
-	 */
-	public static ImageInput identifyDocuImage(ImageInput imgf) throws IOException {
-	    // use fresh DocuImage instance
-	    DocuImage di = getDocuImageInstance();
-		return di.identify(imgf);
-	}
-	
-	/**
-	 * @return Returns the docuImageClass.
-	 */
-	public static Class<DocuImageImpl> getDocuImageClass() {
-		return docuImageClass;
-	}
+     * @param imgf
+     * @return
+     * @throws IOException
+     */
+    public static ImageInput identifyDocuImage(ImageInput imgf)
+            throws IOException {
+        // use fresh DocuImage instance
+        DocuImage di = getDocuImageInstance();
+        return di.identify(imgf);
+    }
 
-	/**
-	 * @param docuImageClass The docuImageClass to set.
-	 */
-	public static void setDocuImageClass(Class<DocuImageImpl> dic) {
-		docuImageClass = dic;
-	}
+    /**
+     * @return Returns the docuImageClass.
+     */
+    public static Class<DocuImageImpl> getDocuImageClass() {
+        return docuImageClass;
+    }
+
+    /**
+     * @param docuImageClass
+     *            The docuImageClass to set.
+     */
+    public static void setDocuImageClass(Class<DocuImageImpl> dic) {
+        docuImageClass = dic;
+    }
 }