changeset 149:04ad64b2137a

Servlet version 1.14b1 - better performance with thumbnails (really, this time :-) - new DocuInfo class - new Directory class - DocuFile uses String and Directory as data members - parameter rearrangements
author robcast
date Tue, 26 Aug 2003 22:28:43 +0200
parents 837a633a0407
children 84ddd05c95d5
files servlet/src/digilib/image/DocuImage.java servlet/src/digilib/image/DocuImageImpl.java servlet/src/digilib/image/ImageLoaderDocuImage.java servlet/src/digilib/image/ImageLoaderDocuInfo.java servlet/src/digilib/image/ImageLoaderImageInfoDocuInfo.java servlet/src/digilib/image/ImageSize.java servlet/src/digilib/image/JAIDocuImage.java servlet/src/digilib/image/JAIImageLoaderDocuImage.java servlet/src/digilib/image/JIMIDocuImage.java servlet/src/digilib/io/Directory.java servlet/src/digilib/io/DocuDirectory.java servlet/src/digilib/io/DocuFile.java servlet/src/digilib/io/DocuFileset.java servlet/src/digilib/servlet/DigilibConfiguration.java servlet/src/digilib/servlet/Scaler.java
diffstat 15 files changed, 481 insertions(+), 229 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/image/DocuImage.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/DocuImage.java	Tue Aug 26 22:28:43 2003 +0200
@@ -14,16 +14,16 @@
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 */
 
 package digilib.image;
 
 import java.awt.Rectangle;
-import java.io.File;
 import java.io.OutputStream;
 
+import digilib.io.DocuFile;
 import digilib.io.FileOpException;
 
 /** The basic class for the representation of a digilib image.
@@ -46,7 +46,7 @@
 	 * @param f Image File.
 	 * @throws FileOpException Exception thrown if any error occurs.
 	 */
-	public void loadImage(File f) throws FileOpException;
+	public void loadImage(DocuFile f) throws FileOpException;
 
 	/** This DocuImage support the loadSubImage operation.
 	 * 
@@ -61,7 +61,7 @@
 	 * @param subsample
 	 * @throws FileOpException
 	 */
-	public void loadSubimage(File f, Rectangle region, int subsample)
+	public void loadSubimage(DocuFile f, Rectangle region, int subsample)
 		throws FileOpException;
 
 	/** Writes the current image to a ServletResponse.
@@ -119,7 +119,7 @@
 	 * @param scale scaling factor
 	 * @throws ImageOpException
 	 */
-	public void scale(double scale) throws ImageOpException;
+	public void scale(double scaleX, double scaleY) throws ImageOpException;
 
 	/** Crops and scales the current image.
 	 *
--- a/servlet/src/digilib/image/DocuImageImpl.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/DocuImageImpl.java	Tue Aug 26 22:28:43 2003 +0200
@@ -21,9 +21,9 @@
 package digilib.image;
 
 import java.awt.Rectangle;
-import java.io.File;
 
 import digilib.Utils;
+import digilib.io.DocuFile;
 import digilib.io.FileOpException;
 
 /** Simple abstract implementation of the <code>DocuImage</code> interface.
@@ -116,7 +116,7 @@
 
 		setQuality(qual);
 		crop(x_off, y_off, width, height);
-		scale(scale);
+		scale(scale, scale);
 	}
 	
 	public String getMimetype() {
@@ -140,7 +140,7 @@
 		return false;
 	}
 
-	public void loadSubimage(File f, Rectangle region, int subsample)
+	public void loadSubimage(DocuFile f, Rectangle region, int subsample)
 		throws FileOpException {
 		// empty implementation
 	}
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java	Tue Aug 26 22:28:43 2003 +0200
@@ -15,7 +15,6 @@
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
 */
 
 package digilib.image;
@@ -39,6 +38,7 @@
 import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
 
+import digilib.io.DocuFile;
 import digilib.io.FileOpException;
 
 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
@@ -99,11 +99,11 @@
 	}
 
 	/* load image file */
-	public void loadImage(File f) throws FileOpException {
+	public void loadImage(DocuFile f) throws FileOpException {
 		util.dprintln(10, "loadImage!");
 		System.gc();
 		try {
-			img = ImageIO.read(f);
+			img = ImageIO.read(f.getFile());
 			if (img == null) {
 				util.dprintln(3, "ERROR(loadImage): unable to load file");
 				throw new FileOpException("Unable to load File!");
@@ -116,37 +116,40 @@
 	/** Get an ImageReader for the image file.
 	 * 
 	 */
-	public void preloadImage(File f) throws IOException {
+	public void preloadImage(DocuFile f) throws IOException {
 		if (reader != null) {
 			// clean up old reader
 			reader.dispose();
 			reader = null;
 		}
 		System.gc();
-		RandomAccessFile rf = new RandomAccessFile(f, "r");
+		RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
 		ImageInputStream istream = ImageIO.createImageInputStream(rf);
-		Iterator readers = ImageIO.getImageReaders(istream);
+		//Iterator readers = ImageIO.getImageReaders(istream);
+		//String ext = f.getName().substring(f.getName().lastIndexOf('.')+1);
+		//Iterator readers = ImageIO.getImageReadersBySuffix(ext);
+		Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype());
 		reader = (ImageReader) readers.next();
-		/* are there more readers?
+		/* are there more readers? */
 		System.out.println("this reader: " + reader.getClass());
 		while (readers.hasNext()) {
 			System.out.println("next reader: " + readers.next().getClass());
 		}
-		*/
+		//*/
 		reader.setInput(istream);
 		if (reader == null) {
 			util.dprintln(3, "ERROR(loadImage): unable to load file");
 			throw new FileOpException("Unable to load File!");
 		}
-		imgFile = f;
+		imgFile = f.getFile();
 	}
 
 	/* Load an image file into the Object. */
-	public void loadSubimage(File f, Rectangle region, int prescale)
+	public void loadSubimage(DocuFile f, Rectangle region, int prescale)
 		throws FileOpException {
 		System.gc();
 		try {
-			if ((reader == null) || (imgFile != f)) {
+			if ((reader == null) || (imgFile != f.getFile())) {
 				preloadImage(f);
 			}
 			// set up reader parameters
@@ -164,7 +167,7 @@
 			throw new FileOpException("Unable to load File!");
 		}
 	}
-
+	
 	/* write image of type mt to Stream */
 	public void writeImage(String mt, OutputStream ostream)
 		throws FileOpException {
@@ -209,7 +212,7 @@
 		}
 	}
 
-	public void scale(double scale) throws ImageOpException {
+	public void scale(double scale, double scaleY) throws ImageOpException {
 		/*
 		 * for downscaling in high quality the image is blurred first
 		 */
--- a/servlet/src/digilib/image/ImageLoaderDocuInfo.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/ImageLoaderDocuInfo.java	Tue Aug 26 22:28:43 2003 +0200
@@ -17,11 +17,10 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
  * Created on 11.06.2003
- *
  */
+
 package digilib.image;
 
-import java.awt.Dimension;
 import java.io.IOException;
 
 import digilib.io.DocuFile;
@@ -37,19 +36,17 @@
 
 	/* check image size and type and store in DocuFile f */
 	public boolean checkFile(DocuFile f) throws IOException {
-		// see if f is already loaded
-		if ((img.reader == null) || (img.imgFile != f.getFile())) {
-			img.preloadImage(f.getFile());
-		}
-		Dimension d =
-			new Dimension(img.reader.getWidth(0), img.reader.getHeight(0));
+		ImageLoaderDocuImage img = new ImageLoaderDocuImage();
+		img.preloadImage(f);
+		img.reader = img.reader;
+		ImageSize d =
+			new ImageSize(img.reader.getWidth(0), img.reader.getHeight(0));
 		f.setSize(d);
 		String t = img.reader.getFormatName();
 		t = FileOps.mimeForFile(f.getFile());
 		f.setMimetype(t);
-		f.setChecked(true);
 		// clean up
-		img.reader.reset();
+		//img.reader.reset();
 		//img.reader = null;
 		return true;
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/image/ImageLoaderImageInfoDocuInfo.java	Tue Aug 26 22:28:43 2003 +0200
@@ -0,0 +1,82 @@
+/* ImageLoaderImageInfoDocuInfo -- DocuInfo implementation using ImageInfo and ImageLoader API
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2003 Robert Casties (robcast@mail.berlios.de)
+
+  This program is free software; you can redistribute  it and/or modify it
+  under  the terms of  the GNU General  Public License as published by the
+  Free Software Foundation;  either version 2 of the  License, or (at your
+  option) any later version.
+   
+  Please read license.txt for the full details. A copy of the GPL
+  may be found at http://www.gnu.org/copyleft/lgpl.html
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+ * Created on 11.06.2003
+ */
+package digilib.image;
+
+import ImageInfo;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+import digilib.io.DocuFile;
+import digilib.io.FileOps;
+
+/**
+ * @author casties
+ *
+ */
+public class ImageLoaderImageInfoDocuInfo implements DocuInfo {
+
+	/* check image size and type and store in DocuFile f */
+	public boolean checkFile(DocuFile f) throws IOException {
+		RandomAccessFile raf = new RandomAccessFile(f.getFile(), "r");
+		// set up ImageInfo object
+		ImageInfo iif = new ImageInfo();
+		iif.setInput(raf);
+		iif.setCollectComments(false);
+		iif.setDetermineImageNumber(false);
+		// try with ImageInfo first
+		if (iif.check()) {
+			ImageSize d =
+				new ImageSize(iif.getWidth(), iif.getHeight());
+			f.setSize(d);
+			f.setMimetype(iif.getMimeType());
+			raf.close();
+		} else {
+			// else use ImageReader
+			ImageInputStream istream = ImageIO.createImageInputStream(raf);
+			Iterator readers = ImageIO.getImageReaders(istream);
+			//String ext = f.getName().substring(f.getName().lastIndexOf('.')+1);
+			//Iterator readers = ImageIO.getImageReadersBySuffix(ext);
+			ImageReader reader = (ImageReader) readers.next();
+			/* are there more readers? */
+			System.out.println("this reader: " + reader.getClass());
+			while (readers.hasNext()) {
+				System.out.println("next reader: " + readers.next().getClass());
+			}
+			reader.setInput(istream);
+			ImageSize d =
+				new ImageSize(reader.getWidth(0), reader.getHeight(0));
+			f.setSize(d);
+			String t = reader.getFormatName();
+			t = FileOps.mimeForFile(f.getFile());
+			f.setMimetype(t);
+			// dispose the reader to free resources
+			reader.dispose();
+		}
+		return true;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/image/ImageSize.java	Tue Aug 26 22:28:43 2003 +0200
@@ -0,0 +1,135 @@
+/* DocuFile.java -- digilib image file class.
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2003 Robert Casties (robcast@mail.berlios.de)
+
+  This program is free software; you can redistribute  it and/or modify it
+  under  the terms of  the GNU General  Public License as published by the
+  Free Software Foundation;  either version 2 of the  License, or (at your
+  option) any later version.
+   
+  Please read license.txt for the full details. A copy of the GPL
+  may be found at http://www.gnu.org/copyleft/lgpl.html
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * Created on 26.08.2003
+ */
+
+package digilib.image;
+
+/** Class for image size (width, height).
+ * 
+ * @author casties
+ *
+ */
+public class ImageSize {
+	public int width;
+	public int height;
+
+	public ImageSize() {
+		super();
+	}
+
+	public ImageSize(int width, int height) {
+		this.width = width;
+		this.height = height;
+	}
+
+	public ImageSize(ImageSize i) {
+		this.width = i.width;
+		this.height = i.height;
+	}
+
+	public void setSize(int width, int height) {
+		this.width = width;
+		this.height = height;
+	}
+
+	/** Returns if the size of this image is smaller in every dimension than the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean isTotallySmallerThan(ImageSize is) {
+		return ((this.width <= is.width) && (this.height <= is.height));
+	}
+
+	/** Returns if the size of this image is smaller in at least one dimension than the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean isSmallerThan(ImageSize is) {
+		return ((this.width <= is.width) || (this.height <= is.height));
+	}
+
+	/** Returns if the size of this image is bigger in every dimension than the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean isTotallyBiggerThan(ImageSize is) {
+		return ((this.width >= is.width) && (this.height >= is.height));
+	}
+
+	/** Returns if the size of this image is bigger in at least one dimension than the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean isBiggerThan(ImageSize is) {
+		return ((this.width >= is.width) || (this.height >= is.height));
+	}
+
+	/** Returns if this image has the same size or height as the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean fitsIn(ImageSize is) {
+		return ((this.width == is.width)&&(this.height <= is.height)
+		||(this.width <= is.width)&&(this.height == is.height));
+	}
+
+	/** Returns if the size of this image is the same as the other image.
+	 * 
+	 * @param is
+	 * @return
+	 */
+	public boolean equals(ImageSize is) {
+		return ((this.width == is.width)&&(this.height == is.height));
+	}
+
+	/**
+	 * @return
+	 */
+	public int getHeight() {
+		return height;
+	}
+
+	/**
+	 * @param height
+	 */
+	public void setHeight(int height) {
+		this.height = height;
+	}
+
+	/**
+	 * @return
+	 */
+	public int getWidth() {
+		return width;
+	}
+
+	/**
+	 * @param width
+	 */
+	public void setWidth(int width) {
+		this.width = width;
+	}
+
+}
--- a/servlet/src/digilib/image/JAIDocuImage.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/JAIDocuImage.java	Tue Aug 26 22:28:43 2003 +0200
@@ -23,7 +23,6 @@
 import java.awt.RenderingHints;
 import java.awt.image.RenderedImage;
 import java.awt.image.renderable.ParameterBlock;
-import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 
@@ -36,6 +35,7 @@
 import javax.media.jai.operator.TransposeType;
 
 import digilib.Utils;
+import digilib.io.DocuFile;
 import digilib.io.FileOpException;
 
 /** A DocuImage implementation using Java Advanced Imaging Library. */
@@ -56,9 +56,9 @@
 	}
 
 	/* Load an image file into the Object. */
-	public void loadImage(File f) throws FileOpException {
+	public void loadImage(DocuFile f) throws FileOpException {
 		System.gc();
-		img = JAI.create("fileload", f.getAbsolutePath());
+		img = JAI.create("fileload", f.getFile().getAbsolutePath());
 		if (img == null) {
 			util.dprintln(3, "ERROR(loadImage): unable to load file");
 			throw new FileOpException("Unable to load File!");
@@ -129,7 +129,7 @@
 	}
 
 	/* scales the current image */
-	public void scale(double scale) throws ImageOpException {
+	public void scale(double scale, double scaleY) throws ImageOpException {
 		if ((scale < 1)
 			&& (img.getColorModel().getPixelSize() == 1)
 			&& (quality > 0)) {
--- a/servlet/src/digilib/image/JAIImageLoaderDocuImage.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/JAIImageLoaderDocuImage.java	Tue Aug 26 22:28:43 2003 +0200
@@ -20,7 +20,6 @@
 
 package digilib.image;
 
-import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.awt.image.renderable.ParameterBlock;
 import java.io.File;
@@ -37,7 +36,6 @@
 
 import digilib.io.DocuFile;
 import digilib.io.FileOpException;
-import digilib.io.FileOps;
 
 /** DocuImage implementation using the Java Advanced Imaging API and the ImageLoader
  * API of Java 1.4.
@@ -83,9 +81,9 @@
 	}
 
 	/* Load an image file into the Object. */
-	public void loadImage(File f) throws FileOpException {
+	public void loadImage(DocuFile f) throws FileOpException {
 		System.gc();
-		img = JAI.create("ImageRead", f.getAbsolutePath());
+		img = JAI.create("ImageRead", f.getFile().getAbsolutePath());
 		if (img == null) {
 			util.dprintln(3, "ERROR(loadImage): unable to load file");
 			throw new FileOpException("Unable to load File!");
@@ -93,11 +91,12 @@
 	}
 
 	/* Get an ImageReader for the image file. */
-	public void preloadImage(File f) throws IOException {
+	public void preloadImage(DocuFile f) throws IOException {
 		System.gc();
-		RandomAccessFile rf = new RandomAccessFile(f, "r");
+		RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
 		ImageInputStream istream = ImageIO.createImageInputStream(rf);
-		Iterator readers = ImageIO.getImageReaders(istream);
+		//Iterator readers = ImageIO.getImageReaders(istream);
+		Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype());
 		reader = (ImageReader) readers.next();
 		reader.setInput(istream);
 		if (reader == null) {
@@ -107,11 +106,11 @@
 	}
 
 	/* Load an image file into the Object. */
-	public void loadSubimage(File f, Rectangle region, int prescale)
+	public void loadSubimage(DocuFile f, Rectangle region, int prescale)
 		throws FileOpException {
 		System.gc();
 		try {
-			if ((reader == null) || (imgFile != f)) {
+			if ((reader == null) || (imgFile != f.getFile())) {
 				preloadImage(f);
 			}
 			ImageInputStream istream = (ImageInputStream) reader.getInput();
@@ -134,9 +133,10 @@
 			util.dprintln(3, "ERROR(loadImage): unable to load file");
 			throw new FileOpException("Unable to load File!");
 		}
-		imgFile = f;
+		imgFile = f.getFile();
 	}
 
+
 	/* Write the current image to an OutputStream. */
 	public void writeImage(String mt, OutputStream ostream)
 		throws FileOpException {
@@ -162,24 +162,6 @@
 	}
 
 	/* (non-Javadoc)
-	 * @see digilib.image.DocuImage#checkFile(digilib.io.DocuFile)
-	 */
-	public boolean checkFile(DocuFile f) throws IOException {
-		// see if f is already loaded
-		if ((reader == null) || (imgFile != f.getFile())) {
-			preloadImage(f.getFile());
-		}
-		Dimension d = new Dimension();
-		d.setSize(reader.getWidth(0), reader.getHeight(0));
-		f.setSize(d);
-		//	String t = reader.getFormatName();
-		String t = FileOps.mimeForFile(f.getFile());
-		f.setMimetype(t);
-		f.setChecked(true);
-		return true;
-	}
-
-	/* (non-Javadoc)
 	 * @see java.lang.Object#finalize()
 	 */
 	protected void finalize() throws Throwable {
--- a/servlet/src/digilib/image/JIMIDocuImage.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/image/JIMIDocuImage.java	Tue Aug 26 22:28:43 2003 +0200
@@ -23,7 +23,6 @@
 import java.awt.image.FilteredImageSource;
 import java.awt.image.ImageFilter;
 import java.awt.image.ImageProducer;
-import java.io.File;
 import java.io.OutputStream;
 
 import com.sun.jimi.core.Jimi;
@@ -33,6 +32,7 @@
 import com.sun.jimi.core.raster.JimiRasterImage;
 
 import digilib.Utils;
+import digilib.io.DocuFile;
 import digilib.io.FileOpException;
 
 /** Implementation of DocuImage using the JIMI image Library. */
@@ -53,10 +53,10 @@
 	/**
 	 *  load image file
 	 */
-	public void loadImage(File f) throws FileOpException {
+	public void loadImage(DocuFile f) throws FileOpException {
 		System.gc();
 		try {
-			img = Jimi.getRasterImage(f.toURL());
+			img = Jimi.getRasterImage(f.getFile().toURL());
 		} catch (java.net.MalformedURLException e) {
 			util.dprintln(3, "ERROR(loadImage): MalformedURLException");
 		} catch (JimiException e) {
@@ -94,7 +94,7 @@
 		return imgHeight;
 	}
 
-	public void scale(double scale) throws ImageOpException {
+	public void scale(double scale, double scaleY) throws ImageOpException {
 
 		ImageFilter scaleFilter;
 		int destWidth = (int) (scale * (float) imgWidth);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/Directory.java	Tue Aug 26 22:28:43 2003 +0200
@@ -0,0 +1,71 @@
+/* Directory -- 
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2003 Robert Casties (robcast@mail.berlios.de)
+
+  This program is free software; you can redistribute  it and/or modify it
+  under  the terms of  the GNU General  Public License as published by the
+  Free Software Foundation;  either version 2 of the  License, or (at your
+  option) any later version.
+   
+  Please read license.txt for the full details. A copy of the GPL
+  may be found at http://www.gnu.org/copyleft/lgpl.html
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * Created on 26.08.2003
+ *
+ */
+package digilib.io;
+
+import java.io.File;
+
+/** Class for filesystem directories
+ * @author casties
+ *
+ */
+public class Directory {
+	// File object pointing to the directory
+	File dir = null;
+
+	/** Default constructor.
+	 * 
+	 */
+	public Directory() {
+		super();
+	}
+	
+	/** Constructor taking a File object.
+	 * 
+	 * @param d
+	 */
+	public Directory(File d) {
+		dir = d;
+	}
+
+	/** Constructor taking a directory name.
+	 * 
+	 * @param d
+	 */
+	public Directory(String dn) {
+		dir = new File(dn);
+	}
+	
+	/**
+	 * @return
+	 */
+	public File getDir() {
+		return dir;
+	}
+
+	/**
+	 * @param dir
+	 */
+	public void setDir(File dir) {
+		this.dir = dir;
+	}
+
+}
--- a/servlet/src/digilib/io/DocuDirectory.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/io/DocuDirectory.java	Tue Aug 26 22:28:43 2003 +0200
@@ -33,7 +33,7 @@
 /**
  * @author casties
  */
-public class DocuDirectory {
+public class DocuDirectory extends Directory {
 
 	// list of files (DocuFileSet)
 	private ArrayList list = null;
@@ -43,8 +43,6 @@
 	private String[] baseDirNames = null;
 	// directory name (digilib canonical form)
 	private String dirName = null;
-	// default/hires directory
-	private File dir = null;
 	// directory metadata
 	private HashMap dirMeta = null;
 	// time of last access of this object (not the filesystem)
@@ -101,7 +99,7 @@
 		// number of base dirs
 		int nb = baseDirNames.length;
 		// array of base dirs
-		File[] dirs = new File[nb];
+		Directory[] dirs = new Directory[nb];
 		// the first directory has to exist
 		dir = new File(baseDirNames[0] + dirName);
 
@@ -110,7 +108,7 @@
 			for (int j = 1; j < nb; j++) {
 				File d = new File(baseDirNames[j] + dirName);
 				if (d.isDirectory()) {
-					dirs[j] = d;
+					dirs[j] = new Directory(d);
 				}
 			}
 
@@ -133,7 +131,7 @@
 						fn.substring(0, fn.lastIndexOf('.') + 1);
 					// add the first DocuFile to a new DocuFileset 
 					DocuFileset fs = new DocuFileset(nb);
-					fs.add(new DocuFile(fl[i]));
+					fs.add(new DocuFile(fn, fs, this));
 					// iterate the remaining base directories
 					for (int j = 1; j < nb; j++) {
 						if (dirs[j] == null) {
@@ -142,14 +140,14 @@
 						File f;
 						if (fext != null) {
 							// use the last extension
-							f = new File(dirs[j], fnx + fext);
+							f = new File(dirs[j].getDir(), fnx + fext);
 						} else {
 							// try the same filename as the original
-							f = new File(dirs[j], fn);
+							f = new File(dirs[j].getDir(), fn);
 						}
 						// if the file exists, add to the DocuFileset
 						if (f.canRead()) {
-							fs.add(new DocuFile(f));
+							fs.add(new DocuFile(f.getName(), fs, dirs[j]));
 						} else {
 							// try other file extensions
 							Iterator exts = FileOps.getImageExtensionIterator();
@@ -157,11 +155,11 @@
 								String s = (String) exts.next();
 								f =
 									new File(
-										dirs[j],
+										dirs[j].getDir(),
 										fnx + s);
 								// if the file exists, add to the DocuFileset
 								if (f.canRead()) {
-									fs.add(new DocuFile(f));
+									fs.add(new DocuFile(f.getName(), fs, dirs[j]));
 									fext = s;
 									break;
 								}
--- a/servlet/src/digilib/io/DocuFile.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/io/DocuFile.java	Tue Aug 26 22:28:43 2003 +0200
@@ -21,11 +21,9 @@
  
 package digilib.io;
 
-import java.awt.Dimension;
 import java.io.File;
-import java.io.IOException;
 
-import digilib.image.DocuInfo;
+import digilib.image.ImageSize;
 
 /**
  * @author casties
@@ -33,18 +31,26 @@
 public class DocuFile {
 	
 	// file object
-	private File file = null;
+	private String filename = null;
 	// parent DocuFileset
 	private DocuFileset parent = null;
+	// parent directory
+	private Directory dir = null;
 	// mime file type
 	private String mimetype = null;
 	// image size in pixels
-	private Dimension pixelSize = null;
-	// image size and type are valid
-	private boolean checked = false;
+	private ImageSize pixelSize = null;
 
-	public DocuFile(File f) {
-		file = f;
+	public DocuFile(String fn, DocuFileset parent, Directory dir) {
+		this.filename = fn;
+		this.parent = parent;
+		this.dir = dir;
+	}
+	
+	public DocuFile(String fn) {
+		File f = new File(fn);
+		this.dir = new Directory(f.getParentFile());
+		this.filename = f.getName();
 	}
 	
 	/** Returns the file name (without path).
@@ -52,36 +58,22 @@
 	 * @return
 	 */
 	public String getName() {
-		if (file != null) {
-			return file.getName();
-		}
-		return null;
+		return filename;
 	}
 
 
-	/** Checks the file using the provided DocuInfo instance.
-	 *  
-	 * @param info
-	 */
-	public void check(DocuInfo info) {
-		try {
-			info.checkFile(this);
-		} catch (IOException e) {
-			checked = false;
-		}
-	}
-
 	/**
 	 * @return File
 	 */
 	public File getFile() {
-		return file;
+		File f = new File(dir.getDir(), filename);
+		return f;
 	}
 
 	/**
-	 * @return Dimension
+	 * @return ImageSize
 	 */
-	public Dimension getSize() {
+	public ImageSize getSize() {
 		return pixelSize;
 	}
 
@@ -93,19 +85,10 @@
 	}
 
 	/**
-	 * Sets the file.
-	 * @param file The file to set
-	 */
-	public void setFile(File f) {
-		this.file = f;
-		mimetype = FileOps.mimeForFile(f);
-	}
-
-	/**
 	 * Sets the imageSize.
 	 * @param imageSize The imageSize to set
 	 */
-	public void setSize(Dimension imageSize) {
+	public void setSize(ImageSize imageSize) {
 		this.pixelSize = imageSize;
 	}
 
@@ -136,15 +119,7 @@
 	 * @return boolean
 	 */
 	public boolean isChecked() {
-		return checked;
-	}
-
-	/**
-	 * Sets the checked.
-	 * @param checked The checked to set
-	 */
-	public void setChecked(boolean checked) {
-		this.checked = checked;
+		return (pixelSize != null);
 	}
 
 }
--- a/servlet/src/digilib/io/DocuFileset.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/io/DocuFileset.java	Tue Aug 26 22:28:43 2003 +0200
@@ -19,14 +19,15 @@
  */
 package digilib.io;
 
-import java.awt.Dimension;
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.ListIterator;
 
 import digilib.image.DocuInfo;
+import digilib.image.ImageSize;
 
 /**
  * @author casties
@@ -98,15 +99,19 @@
 	 * @param info
 	 * @return
 	 */
-	public DocuFile getNextSmaller(Dimension size, DocuInfo info) {
+	public DocuFile getNextSmaller(ImageSize size, DocuInfo info) {
 		for (Iterator i = getHiresIterator(); i.hasNext();) {
 			DocuFile f = (DocuFile) i.next();
-			if (!f.isChecked()) {
-				f.check(info);
-			}
-			if ((f.getSize().getHeight() <= size.getHeight())
-				&& (f.getSize().getWidth() <= size.getWidth())) {
-				return f;
+			try {
+				if (!f.isChecked()) {
+					info.checkFile(f);
+				}
+				if (f.getSize().isTotallySmallerThan(size)) {
+					return f;
+				}
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
 			}
 		}
 		return null;
@@ -123,15 +128,19 @@
 	 * @param info
 	 * @return
 	 */
-	public DocuFile getNextBigger(Dimension size, DocuInfo info) {
+	public DocuFile getNextBigger(ImageSize size, DocuInfo info) {
 		for (ListIterator i = getLoresIterator(); i.hasPrevious();) {
 			DocuFile f = (DocuFile) i.previous();
-			if (!f.isChecked()) {
-				f.check(info);
-			}
-			if ((f.getSize().getHeight() >= size.getHeight())
-				|| (f.getSize().getWidth() >= size.getWidth())) {
-				return f;
+			try {
+				if (!f.isChecked()) {
+					info.checkFile(f);
+				}
+				if (f.getSize().isBiggerThan(size)) {
+					return f;
+				}
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
 			}
 		}
 		return null;
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/servlet/DigilibConfiguration.java	Tue Aug 26 22:28:43 2003 +0200
@@ -95,6 +95,8 @@
 	private String minSubsampleParam = "subsample-minimum";
 	// DocuDirCache instance
 	private DocuDirCache dirCache = null;
+	// DocuImage class instance
+	private Class docuImageClass = null;
 
 	/** Constructor taking a ServletConfig.
 	 * Reads the config file location from an init parameter and loads the
@@ -256,7 +258,10 @@
 	public DocuImage getDocuImageInstance() {
 		DocuImageImpl di = null;
 		try {
-			di = (DocuImageImpl) Class.forName(docuImageType).newInstance();
+			if (docuImageClass == null) {
+				docuImageClass = Class.forName(docuImageType);
+			}
+			di = (DocuImageImpl) docuImageClass.newInstance();
 			di.setUtils(util);
 		} catch (Exception e) {
 		}
--- a/servlet/src/digilib/servlet/Scaler.java	Fri Aug 22 21:12:24 2003 +0200
+++ b/servlet/src/digilib/servlet/Scaler.java	Tue Aug 26 22:28:43 2003 +0200
@@ -14,13 +14,12 @@
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 */
 
 package digilib.servlet;
 
-import java.awt.Dimension;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Rectangle2D;
@@ -40,8 +39,9 @@
 import digilib.auth.AuthOps;
 import digilib.image.DocuImage;
 import digilib.image.DocuInfo;
-import digilib.image.ImageLoaderDocuInfo;
+import digilib.image.ImageLoaderImageInfoDocuInfo;
 import digilib.image.ImageOpException;
+import digilib.image.ImageSize;
 import digilib.io.DocuDirCache;
 import digilib.io.DocuFile;
 import digilib.io.DocuFileset;
@@ -58,7 +58,7 @@
 public class Scaler extends HttpServlet {
 
 	// digilib servlet version (for all components)
-	public static final String dlVersion = "1.13a2";
+	public static final String dlVersion = "1.14b1";
 
 	// Utils instance with debuglevel
 	Utils util;
@@ -176,9 +176,11 @@
 		boolean absoluteScale = false;
 		// only crop the image to fit
 		boolean cropToFit = false;
-		// try different resolution images automatically 
-		boolean autoRes = true;
-		// use hires images (if autoRes == false) 
+		// send the file as is
+		boolean sendFile = false;
+		// use low resolution images only
+		boolean loresOnly = false;
+		// use hires images only
 		boolean hiresOnly = false;
 		// interpolation to use for scaling
 		int scaleQual = 1;
@@ -246,30 +248,45 @@
 			scaleToFit = false;
 			absoluteScale = false;
 			cropToFit = true;
-			autoRes = true;
+			sendFile = false;
+			hiresOnly = true;
 		} else if (dlRequest.isOption("fit")) {
 			scaleToFit = true;
 			absoluteScale = false;
 			cropToFit = false;
-			autoRes = true;
+			sendFile = false;
+			hiresOnly = false;
 		} else if (dlRequest.isOption("osize")) {
 			scaleToFit = false;
 			absoluteScale = true;
 			cropToFit = false;
-			autoRes = false;
+			sendFile = false;
 			hiresOnly = true;
 		} else if (dlRequest.isOption("file")) {
 			scaleToFit = false;
 			absoluteScale = false;
 			if (dlConfig.isSendFileAllowed()) {
 				cropToFit = false;
+				sendFile = true;
 			} else {
 				// crop to fit if send file not allowed
 				cropToFit = true;
+				sendFile = false;
 			}
-			autoRes = false;
 			hiresOnly = true;
 		}
+		// operation mode: "lores": try to use scaled image, "hires": use unscaled image
+		//   "autores": try best fitting resolution
+		if (dlRequest.isOption("lores")) {
+			loresOnly = true;
+			hiresOnly = false;
+		} else if (dlRequest.isOption("hires")) {
+			loresOnly = false;
+			hiresOnly = true;
+		} else if (dlRequest.isOption("autores")) {
+			loresOnly = false;
+			hiresOnly = false;
+		}
 		// operation mode: "errtxt": error message in html, "errimg": error image
 		if (dlRequest.isOption("errtxt")) {
 			errorMsgHtml = true;
@@ -284,32 +301,15 @@
 		} else if (dlRequest.isOption("q2")) {
 			scaleQual = 2;
 		}
-		// operation mode: "lores": try to use scaled image, "hires": use unscaled image
-		//   "autores": try best fitting resolution
-		if (dlRequest.isOption("lores")) {
-			autoRes = false;
-			hiresOnly = false;
-		} else if (dlRequest.isOption("hires")) {
-			autoRes = false;
-			hiresOnly = true;
-		} else if (dlRequest.isOption("autores")) {
-			autoRes = true;
-		}
 
 		//"big" try for all file/image actions
 		try {
 
-			// new DocuImage instance
-			DocuImage docuImage = dlConfig.getDocuImageInstance();
-			if (docuImage == null) {
-				throw new ImageOpException("Unable to load DocuImage class!");
-			}
+			// DocuFileset of the image to load
+			DocuFileset fileset = null;
 
 			// new DocuInfo instance
-			DocuInfo docuInfo = new ImageLoaderDocuInfo();
-
-			// set interpolation quality
-			docuImage.setQuality(scaleQual);
+			DocuInfo docuInfo = new ImageLoaderImageInfoDocuInfo();
 
 			/*
 			 *  find the file to load/send
@@ -347,8 +347,7 @@
 
 			// find the file(set)
 			DocuFile fileToLoad;
-			DocuFileset fileset =
-				dirCache.getFileset(loadPathName, dlRequest.getPn());
+			fileset = dirCache.getFileset(loadPathName, dlRequest.getPn());
 			if (fileset == null) {
 				throw new FileOpException(
 					"File "
@@ -362,20 +361,33 @@
 			 * calculate expected source image size
 			 * 
 			 */
-			Dimension expectedSourceSize = new Dimension();
+			ImageSize expectedSourceSize = new ImageSize();
 			if (scaleToFit) {
 				double scale = (1 / Math.min(paramWW, paramWH)) * paramWS;
-				expectedSourceSize.setSize(paramDW * scale, paramDH * scale);
+				expectedSourceSize.setSize(
+					(int) (paramDW * scale),
+					(int) (paramDH * scale));
 			} else {
 				expectedSourceSize.setSize(
-					paramDW * paramWS,
-					paramDH * paramWS);
+					(int) (paramDW * paramWS),
+					(int) (paramDH * paramWS));
 			}
 
 			/* 
 			 * select a resolution
 			 */
-			if (autoRes) {
+			if (hiresOnly) {
+				// get first element (= highest resolution)
+				fileToLoad = fileset.get(0);
+			} else if (loresOnly) {
+				// enforced lores uses next smaller resolution
+				fileToLoad =
+					fileset.getNextSmaller(expectedSourceSize, docuInfo);
+				if (fileToLoad == null) {
+					// this is the smallest we have
+					fileToLoad = fileset.get(fileset.size() - 1);
+				}
+			} else {
 				// autores: use next higher resolution
 				fileToLoad =
 					fileset.getNextBigger(expectedSourceSize, docuInfo);
@@ -383,20 +395,6 @@
 					// this is the highest we have
 					fileToLoad = fileset.get(0);
 				}
-			} else {
-				// enforced hires or lores
-				if (hiresOnly) {
-					// get first element
-					fileToLoad = fileset.get(0);
-				} else {
-					// enforced lores uses next smaller resolution
-					fileToLoad =
-						fileset.getNextSmaller(expectedSourceSize, docuInfo);
-					if (fileToLoad == null) {
-						// this is the smallest we have
-						fileToLoad = fileset.get(fileset.size() - 1);
-					}
-				}
 			}
 			util.dprintln(1, "Loading: " + fileToLoad.getFile());
 
@@ -416,10 +414,13 @@
 
 			// check the source image
 			if (!fileToLoad.isChecked()) {
-				fileToLoad.check(docuInfo);
+				docuInfo.checkFile(fileToLoad);
 			}
 			// get the source image type
 			mimeType = fileToLoad.getMimetype();
+			// get the source image size
+			ImageSize imgSize = fileToLoad.getSize();
+
 			// decide if the image can be sent as is
 			boolean mimetypeSendable =
 				mimeType.equals("image/jpeg")
@@ -441,17 +442,11 @@
 			 * if not autoScale and not scaleToFit nor cropToFit 
 			 * then send as is (mo=file)
 			 */
-			if ((!autoRes
+			if ((loresOnly
 				&& imageSendable
-				&& (fileToLoad.getSize().width <= expectedSourceSize.width)
-				&& (fileToLoad.getSize().height <= expectedSourceSize.height))
-				|| (autoRes
-					&& ((fileToLoad.getSize().width == expectedSourceSize.width)
-					&& (fileToLoad.getSize().height <= expectedSourceSize.height)))
-				|| (autoRes
-					&& ((fileToLoad.getSize().width <= expectedSourceSize.width)
-					&& (fileToLoad.getSize().height == expectedSourceSize.height)))
-				|| (!autoRes && !scaleToFit && !cropToFit && !absoluteScale)) {
+				&& fileToLoad.getSize().isSmallerThan(expectedSourceSize))
+				|| (!(loresOnly || hiresOnly) && fileToLoad.getSize().fitsIn(expectedSourceSize))
+				|| sendFile) {
 
 				util.dprintln(1, "Sending File as is.");
 
@@ -465,25 +460,22 @@
 				return;
 			}
 
+			// new DocuImage instance
+			DocuImage docuImage = dlConfig.getDocuImageInstance();
+			if (docuImage == null) {
+				throw new ImageOpException("Unable to load DocuImage class!");
+			}
+
+			// set interpolation quality
+			docuImage.setQuality(scaleQual);
+
 			/*
 			 *  crop and scale the image
 			 */
 
-			int imgWidth = 0;
-			int imgHeight = 0;
-			// get image size
-			if (fileToLoad.getSize() == null) {
-				// size unknown so far 
-				imgWidth = docuImage.getWidth();
-				imgHeight = docuImage.getHeight();
-				// remember size
-				fileToLoad.setSize(new Dimension(imgWidth, imgHeight));
-			} else {
-				imgWidth = fileToLoad.getSize().width;
-				imgHeight = fileToLoad.getSize().height;
-			}
-
-			util.dprintln(2, "IMG: " + imgWidth + "x" + imgHeight);
+			util.dprintln(
+				2,
+				"IMG: " + imgSize.getWidth() + "x" + imgSize.getHeight());
 			util.dprintln(
 				2,
 				"time " + (System.currentTimeMillis() - startTime) + "ms");
@@ -500,13 +492,19 @@
 			// coordinates using Java2D
 			// image size in pixels
 			Rectangle2D imgBounds =
-				new Rectangle2D.Double(0, 0, imgWidth, imgHeight);
+				new Rectangle2D.Double(
+					0,
+					0,
+					imgSize.getWidth(),
+					imgSize.getHeight());
 			// user window area in [0,1] coordinates
 			Rectangle2D relUserArea =
 				new Rectangle2D.Double(paramWX, paramWY, paramWW, paramWH);
 			// transform from relative [0,1] to image coordinates.
 			AffineTransform imgTrafo =
-				AffineTransform.getScaleInstance(imgWidth, imgHeight);
+				AffineTransform.getScaleInstance(
+					imgSize.getWidth(),
+					imgSize.getHeight());
 			// transform user coordinate area to image coordinate area
 			Rectangle2D userImgArea =
 				imgTrafo.createTransformedShape(relUserArea).getBounds2D();
@@ -643,7 +641,7 @@
 				}
 
 				docuImage.loadSubimage(
-					fileToLoad.getFile(),
+					fileToLoad,
 					outerUserImgArea.getBounds(),
 					(int) subsamp);
 
@@ -655,18 +653,18 @@
 						+ "x"
 						+ docuImage.getHeight());
 
-				docuImage.scale(scaleXY);
+				docuImage.scale(scaleXY, scaleXY);
 
 			} else {
 				// else load and crop the whole file
-				docuImage.loadImage(fileToLoad.getFile());
+				docuImage.loadImage(fileToLoad);
 				docuImage.crop(
 					(int) areaXoff,
 					(int) areaYoff,
 					(int) areaWidth,
 					(int) areaHeight);
 
-				docuImage.scale(scaleXY);
+				docuImage.scale(scaleXY, scaleXY);
 			}
 
 			// mirror image
@@ -770,7 +768,6 @@
 				}
 			} catch (FileOpException ex) {
 			} // so we don't get a loop
-			return;
 		} catch (AuthOpException e) {
 			util.dprintln(1, "ERROR: Authorization error: " + e);
 			try {
@@ -785,7 +782,6 @@
 				}
 			} catch (FileOpException ex) {
 			} // so we don't get a loop
-			return;
 		} catch (ImageOpException e) {
 			util.dprintln(1, "ERROR: Image Error: " + e);
 			try {
@@ -800,7 +796,6 @@
 				}
 			} catch (FileOpException ex) {
 			} // so we don't get a loop
-			return;
 		} catch (RuntimeException e) {
 			// JAI likes to throw RuntimeExceptions ;-(
 			util.dprintln(1, "ERROR: Other Image Error: " + e);
@@ -816,7 +811,7 @@
 				}
 			} catch (FileOpException ex) {
 			} // so we don't get a loop
-			return;
+
 		}
 	}