changeset 207:1a65d8e43620

Servlet version 1.18b9 -- cleanup and bugfixes - fixed bug with slow color JPEGs - better pathname handling - better filehandle cleanup (hopefully)
author robcast
date Fri, 12 Mar 2004 19:52:06 +0100
parents ffbe705d1c3f
children 460cd1f18b96
files servlet/src/digilib/image/DocuImage.java servlet/src/digilib/image/DocuImageImpl.java servlet/src/digilib/image/ImageLoaderDocuImage.java
diffstat 3 files changed, 51 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/image/DocuImage.java	Fri Mar 12 19:52:06 2004 +0100
+++ b/servlet/src/digilib/image/DocuImage.java	Fri Mar 12 19:52:06 2004 +0100
@@ -207,5 +207,12 @@
 	 * @param quality The quality to set
 	 */
 	public void setQuality(int quality);
+	
+	/** Frees all resources bound to the DocuImage.
+	 * 
+	 * Things that should be freed are image objects and open files.
+	 * 
+	 */
+	public void dispose();
 
 }
--- a/servlet/src/digilib/image/DocuImageImpl.java	Fri Mar 12 19:52:06 2004 +0100
+++ b/servlet/src/digilib/image/DocuImageImpl.java	Fri Mar 12 19:52:06 2004 +0100
@@ -130,4 +130,7 @@
 		// emtpy implementation
 	}
 
+	public void dispose() {
+	}
+
 }
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java	Fri Mar 12 19:52:06 2004 +0100
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java	Fri Mar 12 19:52:06 2004 +0100
@@ -20,6 +20,7 @@
 package digilib.image;
 
 import java.awt.Rectangle;
+import java.awt.RenderingHints;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.AffineTransformOp;
@@ -38,8 +39,8 @@
 import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
 
+import digilib.io.FileOpException;
 import digilib.io.ImageFile;
-import digilib.io.FileOpException;
 
 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
 public class ImageLoaderDocuImage extends DocuImageImpl {
@@ -47,7 +48,7 @@
 	/** image object */
 	protected BufferedImage img;
 	/** interpolation type */
-	protected int interpol;
+	protected RenderingHints renderHint;
 	/** ImageIO image reader */
 	protected ImageReader reader;
 	/** File that was read */
@@ -60,13 +61,15 @@
 
 	public void setQuality(int qual) {
 		quality = qual;
+		renderHint = new RenderingHints(null);
+		//hint.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
 		// setup interpolation quality
 		if (qual > 0) {
 			logger.debug("quality q1");
-			interpol = AffineTransformOp.TYPE_BILINEAR;
+			renderHint.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
 		} else {
 			logger.debug("quality q0");
-			interpol = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
+			renderHint.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
 		}
 	}
 
@@ -100,7 +103,7 @@
 
 	/* load image file */
 	public void loadImage(ImageFile f) throws FileOpException {
-		logger.debug("loadImage!");
+		logger.debug("loadImage "+f.getFile());
 		//System.gc();
 		try {
 			img = ImageIO.read(f.getFile());
@@ -114,10 +117,11 @@
 
 	/** Get an ImageReader for the image file. */
 	public void preloadImage(ImageFile f) throws IOException {
+		logger.debug("preloadImage "+f.getFile());
 		if (reader != null) {
+			logger.debug("Reader was not null!");
 			// clean up old reader
-			reader.dispose();
-			reader = null;
+			dispose();
 		}
 		//System.gc();
 		RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
@@ -128,9 +132,9 @@
 		Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype());
 		reader = (ImageReader) readers.next();
 		/* are there more readers? */
-		logger.debug("this reader: " + reader.getClass());
+		logger.debug("ImageIO: this reader: " + reader.getClass());
 		while (readers.hasNext()) {
-			logger.debug("next reader: " + readers.next().getClass());
+			logger.debug("ImageIO: next reader: " + readers.next().getClass());
 		}
 		//*/
 		reader.setInput(istream);
@@ -143,6 +147,7 @@
 	/* Load an image file into the Object. */
 	public void loadSubimage(ImageFile f, Rectangle region, int prescale)
 		throws FileOpException {
+		logger.debug("loadSubimage");
 		//System.gc();
 		try {
 			if ((reader == null) || (imgFile != f.getFile())) {
@@ -153,7 +158,9 @@
 			readParam.setSourceRegion(region);
 			readParam.setSourceSubsampling(prescale, prescale, 0, 0);
 			// read image
+			logger.debug("loading..");
 			img = reader.read(0, readParam);
+			logger.debug("loaded");
 		} catch (IOException e) {
 			throw new FileOpException("Unable to load File!");
 		}
@@ -165,7 +172,7 @@
 	/* write image of type mt to Stream */
 	public void writeImage(String mt, OutputStream ostream)
 		throws FileOpException {
-		logger.debug("writeImage!");
+		logger.debug("writeImage");
 		try {
 			// setup output
 			String type = "png";
@@ -195,6 +202,7 @@
 			}
 
 			// render output
+			logger.debug("writing");
 			if (ImageIO.write(img, type, ostream)) {
 				// writing was OK
 				return;
@@ -207,20 +215,21 @@
 	}
 
 	public void scale(double scale, double scaleY) throws ImageOpException {
+		logger.debug("scale");
 		/* for downscaling in high quality the image is blurred first */
 		if ((scale <= 0.5) && (quality > 1)) {
 			int bl = (int) Math.floor(1 / scale);
 			blur(bl);
 		}
-		/* and scaled */
+		/* then scaled */
 		AffineTransformOp scaleOp =
 			new AffineTransformOp(
 				AffineTransform.getScaleInstance(scale, scale),
-				interpol);
+				renderHint);
 		BufferedImage scaledImg = null;
-		// enforce grey destination image for greyscale *Java2D BUG*
-		if ((quality > 0)
-			&& (img.getColorModel().getNumColorComponents() == 1)) {
+		// enforce destination image type (*Java2D BUG*)
+		if (quality > 0) {
+			logger.debug("creating destination image");
 			Rectangle2D dstBounds = scaleOp.getBounds2D(img);
 			scaledImg =
 				new BufferedImage(
@@ -228,7 +237,12 @@
 					(int) dstBounds.getHeight(),
 					img.getType());
 		}
+		logger.debug("scaling...");
 		scaledImg = scaleOp.filter(img, scaledImg);
+		logger.debug("destination image type "+scaledImg.getType());
+		if (scaledImg == null) {
+			throw new ImageOpException("Unable to scale");
+		}
 		//DEBUG
 		logger.debug("SCALE: "
 				+ scale
@@ -236,10 +250,8 @@
 				+ scaledImg.getWidth()
 				+ "x"
 				+ scaledImg.getHeight());
-		if (scaledImg == null) {
-			throw new ImageOpException("Unable to scale");
-		}
 		img = scaledImg;
+		scaledImg = null;
 	}
 
 	public void blur(int radius) throws ImageOpException {
@@ -256,7 +268,7 @@
 		}
 		Kernel blur = new Kernel(klen, klen, kern);
 		// blur with convolve operation
-		ConvolveOp blurOp = new ConvolveOp(blur, ConvolveOp.EDGE_NO_OP, null);
+		ConvolveOp blurOp = new ConvolveOp(blur, ConvolveOp.EDGE_NO_OP, renderHint);
 		// blur needs explicit destination image type for color *Java2D BUG*
 		BufferedImage blurredImg = null;
 		if (img.getType() == BufferedImage.TYPE_3BYTE_BGR) {
@@ -291,7 +303,8 @@
 		/*
 		 * Only one constant should work regardless of the number of bands
 		 * according to the JDK spec. Doesn't work on JDK 1.4 for OSX and Linux
-		 * (at least). RescaleOp scaleOp = new RescaleOp( (float)mult,
+		 * (at least). 
+		 * RescaleOp scaleOp = new RescaleOp( (float)mult,
 		 * (float)add, null); scaleOp.filter(img, img);
 		 */
 
@@ -382,7 +395,7 @@
 		double y = (h / 2);
 		trafo.rotate(rangle, x, y);
 		// try rotation to see how far we're out of bounds
-		AffineTransformOp rotOp = new AffineTransformOp(trafo, interpol);
+		AffineTransformOp rotOp = new AffineTransformOp(trafo, renderHint);
 		Rectangle2D rotbounds = rotOp.getBounds2D(img);
 		double xoff = rotbounds.getX();
 		double yoff = rotbounds.getY();
@@ -390,7 +403,7 @@
 		trafo.preConcatenate(
 			AffineTransform.getTranslateInstance(-xoff, -yoff));
 		// transform image
-		rotOp = new AffineTransformOp(trafo, interpol);
+		rotOp = new AffineTransformOp(trafo, renderHint);
 		BufferedImage rotImg = rotOp.filter(img, null);
 		// calculate new bounding box
 		//Rectangle2D bounds = rotOp.getBounds2D(img);
@@ -431,7 +444,7 @@
 		AffineTransformOp mirOp =
 			new AffineTransformOp(
 				new AffineTransform(mx, 0, 0, my, tx, ty),
-				interpol);
+				renderHint);
 		BufferedImage mirImg = mirOp.filter(img, null);
 		if (mirImg == null) {
 			throw new ImageOpException("Unable to mirror");
@@ -441,12 +454,16 @@
 
 	/* (non-Javadoc) @see java.lang.Object#finalize() */
 	protected void finalize() throws Throwable {
+		dispose();
+		super.finalize();
+	}
+
+	public void dispose() {
 		// we must dispose the ImageReader because it keeps the filehandle
 		// open!
 		reader.dispose();
 		reader = null;
 		img = null;
-		super.finalize();
 	}
 
 }