changeset 574:790cbfb58b52 stream

ripping apart ImageFileSet
author robcast
date Wed, 22 Dec 2010 18:32:06 +0100
parents beeedf90cb81
children dad720e9b12b efd7a223f819
files servlet/src/digilib/image/ImageJobDescription.java servlet/src/digilib/image/ImageLoaderDocuImage.java servlet/src/digilib/image/JAIDocuImage.java servlet/src/digilib/io/DocuDirectory.java servlet/src/digilib/io/DocuDirent.java servlet/src/digilib/io/FileOps.java servlet/src/digilib/io/ImageFile.java servlet/src/digilib/io/ImageFileset.java servlet/src/digilib/io/ImageInput.java servlet/src/digilib/io/ImageSet.java servlet/src/digilib/io/SVGFile.java servlet/src/digilib/io/TextFile.java servlet/src/digilib/servlet/DocumentBean.java servlet/src/digilib/servlet/Texter.java
diffstat 14 files changed, 454 insertions(+), 477 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/image/ImageJobDescription.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/image/ImageJobDescription.java	Wed Dec 22 18:32:06 2010 +0100
@@ -12,7 +12,7 @@
 import digilib.io.FileOps;
 import digilib.io.FileOps.FileClass;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
 import digilib.servlet.DigilibConfiguration;
 import digilib.util.OptionsSet;
 import digilib.util.Parameter;
@@ -37,7 +37,7 @@
 	protected static Logger logger = Logger.getLogger("digilib.servlet");
 
 	ImageFile fileToLoad = null;
-	ImageFileset fileset = null;
+	ImageSet fileset = null;
 	DocuDirectory fileDir = null;
 	String filePath = null;
 	ImageSize expectedSourceSize = null;
@@ -182,11 +182,11 @@
 		return fileDir;
 	}
 	
-    public ImageFileset getFileset() throws FileOpException {
+    public ImageSet getFileset() throws FileOpException {
         if(fileset==null){
             DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
     
-            fileset = (ImageFileset) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
+            fileset = (ImageSet) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
             if (fileset == null) {
                 throw new FileOpException("File " + getFilePath() + "("
                         + getAsInt("pn") + ") not found.");
@@ -245,7 +245,7 @@
 		logger.debug("get_hiresSize()");
 
 		ImageSize hiresSize = null;
-		ImageFileset fileset = getFileset();
+		ImageSet fileset = getFileset();
 		if (getAbsoluteScale()) {
 			ImageFile hiresFile = fileset.getBiggest();
 			if (!hiresFile.isChecked()) {
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java	Wed Dec 22 18:32:06 2010 +0100
@@ -50,7 +50,7 @@
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
 import digilib.io.ImageInput;
 
 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
@@ -127,7 +127,7 @@
             return imf;
         }
         // fileset to store the information
-        ImageFileset imgfs = imageFile.getParent();
+        ImageSet imgfs = imageFile.getParent();
         File f = imageFile.getFile();
         if (f == null) {
             throw new IOException("File not found!");
--- a/servlet/src/digilib/image/JAIDocuImage.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/image/JAIDocuImage.java	Wed Dec 22 18:32:06 2010 +0100
@@ -47,7 +47,7 @@
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
 import digilib.io.ImageInput;
 
 /** A DocuImage implementation using Java Advanced Imaging Library. */
@@ -112,7 +112,7 @@
 			return imf;
 		}
 		// fileset to store the information
-		ImageFileset imgfs = imageFile.getParent();
+		ImageSet imgfs = imageFile.getParent();
 		File f = imageFile.getFile();
 		if (f == null) {
 			throw new IOException("File not found!");
--- a/servlet/src/digilib/io/DocuDirectory.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/DocuDirectory.java	Wed Dec 22 18:32:06 2010 +0100
@@ -127,11 +127,11 @@
 	 * @param index
 	 * @return
 	 */
-	public ImageFileset get(int index) {
+	public ImageSet get(int index) {
 		if ((list == null) || (list.get(0) == null) || (index >= list.get(0).size())) {
 			return null;
 		}
-		return (ImageFileset) list.get(0).get(index);
+		return (ImageSet) list.get(0).get(index);
 	}
 
 	/**
--- a/servlet/src/digilib/io/DocuDirent.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/DocuDirent.java	Wed Dec 22 18:32:06 2010 +0100
@@ -57,19 +57,19 @@
 	 * 
 	 * @return
 	 */
-	public abstract File getFile();
+	public abstract File getInput();
 
 	/**
 	 * Reads meta-data for this Fileset if there is any.
 	 *  
 	 */
 	public void readMeta() {
-		if ((fileMeta != null) || (getFile() == null)) {
+		if ((fileMeta != null) || (getInput() == null)) {
 			// there is already metadata or there is no file
 			return;
 		}
 		// metadata is in the file {filename}.meta
-		String fn = getFile().getAbsolutePath();
+		String fn = getInput().getAbsolutePath();
 		File mf = new File(fn + ".meta");
 		if (mf.canRead()) {
 			XMLMetaLoader ml = new XMLMetaLoader();
@@ -95,7 +95,7 @@
 	 * @return
 	 */
 	public String getName() {
-		File f = getFile();
+		File f = getInput();
 		return (f != null) ? f.getName() : null;
 	} 
 	
--- a/servlet/src/digilib/io/FileOps.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/FileOps.java	Wed Dec 22 18:32:06 2010 +0100
@@ -329,7 +329,7 @@
 	/**
 	 * Factory for DocuDirents based on file class.
 	 * 
-	 * Returns an ImageFileset, TextFile or SVGFile. baseDirs and scalext are
+	 * Returns an ImageSet, TextFile or SVGFile. baseDirs and scalext are
 	 * only for ImageFilesets.
 	 * 
 	 * @param fileClass
@@ -342,7 +342,7 @@
 		// what class of file do we have?
 		if (fileClass == FileClass.IMAGE) {
 			// image file
-			return new ImageFileset(file, hints);
+			return new ImageSet(file, hints);
 		} else if (fileClass == FileClass.TEXT) {
 			// text file
 			return new TextFile(file);
--- a/servlet/src/digilib/io/ImageFile.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/ImageFile.java	Wed Dec 22 18:32:06 2010 +0100
@@ -22,7 +22,6 @@
 package digilib.io;
 
 import java.io.File;
-import java.io.InputStream;
 
 import digilib.image.ImageSize;
 
@@ -33,12 +32,12 @@
 	
 	// file name
 	private String filename = null;
-	// parent ImageFileset
-	private ImageFileset parent = null;
+	// parent ImageSet
+	private ImageSet parent = null;
 	// parent directory
 	private Directory dir = null;
 
-	public ImageFile(String fn, ImageFileset parent, Directory dir) {
+	public ImageFile(String fn, ImageSet parent, Directory dir) {
 		this.filename = fn;
 		this.parent = parent;
 		this.dir = dir;
@@ -79,9 +78,9 @@
 	}
 
 	/**
-	 * @return ImageFileset
+	 * @return ImageSet
 	 */
-	public ImageFileset getParent() {
+	public ImageSet getParent() {
 		return parent;
 	}
 
@@ -89,7 +88,7 @@
 	 * Sets the parent.
 	 * @param parent The parent to set
 	 */
-	public void setParent(ImageFileset parent) {
+	public void setParent(ImageSet parent) {
 		this.parent = parent;
 	}
 
--- a/servlet/src/digilib/io/ImageFileset.java	Wed Dec 22 09:54:34 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/* ImageFileset -- digilib image file info 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  
- */
-
-package digilib.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import digilib.image.ImageSize;
-import digilib.io.FileOps.FileClass;
-import digilib.servlet.DigilibConfiguration;
-
-/**
- * @author casties
- */
-public class ImageFileset extends DocuDirent {
-
-	/** this is an image file */
-	protected static FileClass fileClass = FileClass.IMAGE;
-	
-	/** list of files (ImageFile) */
-	private List<ImageFile> list = null;
-
-	/** aspect ratio (width/height) */
-	private float aspect = 0;
-
-	/** resolution of the biggest image (DPI) */
-	private float resX = 0;
-
-	/** resolution of the biggest image (DPI) */
-	private float resY = 0;
-
-	/**
-	 * Creator for empty fileset.
-	 * 
-	 * 
-	 * @param initialCapacity
-	 */
-	public ImageFileset() {
-		list = new ArrayList<ImageFile>();
-	}
-
-	/**
-	 * Constructor with a file and hints.
-	 * 
-	 * The hints are expected to contain 'basedirs' and 'scaledfilext' keys.
-	 * 
-	 * @param file
-	 * @param hints
-	 */
-	public ImageFileset(File file, Map<Integer,Object> hints) {
-		Directory[] dirs = (Directory[]) hints.get(FileOps.HINT_BASEDIRS);
-		int nb = dirs.length;
-		list = new ArrayList<ImageFile>(nb);
-		parent = dirs[0];
-		fill(dirs, file, hints);
-	}
-
-	/**
-	 * Adds an ImageFile to this Fileset.
-	 * 
-	 * The files should be added in the order of higher to lower resolutions.
-	 * The first file is considered the hires "original".
-	 * 
-	 * 
-	 * @param f
-	 *            file to add
-	 * @return true (always)
-	 */
-	public boolean add(ImageFile f) {
-		f.setParent(this);
-		return list.add(f);
-	}
-
-	/**
-	 * The number of image files in this Fileset.
-	 * 
-	 * 
-	 * @return number of image files
-	 */
-	public int size() {
-		return (list != null) ? list.size() : 0;
-	}
-
-	/**
-	 * Gets the default File.
-	 *  
-	 */
-	public File getFile() {
-		return (list != null) ? list.get(0).getFile() : null;
-	}
-
-	/**
-	 * Get the ImageFile at the index.
-	 * 
-	 * 
-	 * @param index
-	 * @return
-	 */
-	public ImageFile get(int index) {
-		return list.get(index);
-	}
-
-	/**
-	 * Get the next smaller ImageFile than the given size.
-	 * 
-	 * Returns the ImageFile from the set that has a width and height smaller or
-	 * equal the given size. Returns null if there isn't any smaller image.
-	 * Needs DocuInfo instance to checkFile().
-	 * 
-	 * 
-	 * @param size
-	 * @param info
-	 * @return
-	 */
-	public ImageFile getNextSmaller(ImageSize size) {
-		for (Iterator<ImageFile> i = getHiresIterator(); i.hasNext();) {
-			ImageFile f = i.next();
-			try {
-				if (!f.isChecked()) {
-					DigilibConfiguration.docuImageIdentify(f);
-				}
-				if (f.getSize().isTotallySmallerThan(size)) {
-					return f;
-				}
-			} catch (IOException e) {
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Get the next bigger ImageFile than the given size.
-	 * 
-	 * Returns the ImageFile from the set that has a width or height bigger or
-	 * equal the given size. Returns null if there isn't any bigger image. Needs
-	 * DocuInfo instance to checkFile().
-	 * 
-	 * 
-	 * @param size
-	 * @param info
-	 * @return
-	 */
-	public ImageFile getNextBigger(ImageSize size) {
-		for (ListIterator<ImageFile> i = getLoresIterator(); i.hasPrevious();) {
-			ImageFile f = i.previous();
-			try {
-				if (!f.isChecked()) {
-					DigilibConfiguration.docuImageIdentify(f);
-				}
-				if (f.getSize().isBiggerThan(size)) {
-					return f;
-				}
-			} catch (IOException e) {
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the biggest ImageFile in the set.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ImageFile getBiggest() {
-		return this.get(0);
-	}
-
-	/**
-	 * Returns the biggest ImageFile in the set.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ImageFile getSmallest() {
-		return this.get(this.size() - 1);
-	}
-
-	/**
-	 * Get an Iterator for this Fileset starting at the highest resolution
-	 * images.
-	 * 
-	 * 
-	 * @return
-	 */
-	public ListIterator<ImageFile> getHiresIterator() {
-		return list.listIterator();
-	}
-
-	/**
-	 * Get an Iterator for this Fileset starting at the lowest resolution
-	 * images.
-	 * 
-	 * The Iterator starts at the last element, so you have to use it backwards
-	 * with hasPrevious() and previous().
-	 * 
-	 * 
-	 * @return
-	 */
-	public ListIterator<ImageFile> getLoresIterator() {
-		return list.listIterator(list.size());
-	}
-
-	/**
-	 * Fill the ImageFileset with files from different base directories.
-	 * 
-	 * 
-	 * @param dirs
-	 *            list of base directories
-	 * @param fl
-	 *            file (from first base dir)
-	 * @param hints
-	 *  
-	 */
-	void fill(Directory[] dirs, File fl, Map<Integer,Object> hints) {
-		int nb = dirs.length;
-		String fn = fl.getName();
-		String baseFn = FileOps.basename(fn);
-		// add the first ImageFile to the ImageFileset
-		add(new ImageFile(fn, this, parent));
-		// iterate the remaining base directories
-		for (int dirIdx = 1; dirIdx < nb; dirIdx++) {
-			if (dirs[dirIdx] == null) {
-				continue;
-			}
-			// read the directory
-			if (dirs[dirIdx].getFilenames() == null) {
-				dirs[dirIdx].readDir();
-			}
-			String[] dirFiles = dirs[dirIdx].getFilenames();
-			// try the same filename as the original
-			int fileIdx = Arrays.binarySearch(dirFiles, fn);
-			if (fileIdx < 0) {
-				// try closest matches without extension
-				fileIdx = -fileIdx - 1;
-				// try idx
-				if ((fileIdx < dirFiles.length)
-						&& (FileOps.basename(dirFiles[fileIdx]).equals(baseFn))) {
-					// idx ok
-				} else if ((fileIdx > 0)
-						&& (FileOps.basename(dirFiles[fileIdx - 1])
-								.equals(baseFn))) {
-					// idx-1 ok
-					fileIdx = fileIdx - 1;
-				} else if ((fileIdx+1 < dirFiles.length)
-						&& (FileOps.basename(dirFiles[fileIdx + 1])
-								.equals(baseFn))) {
-					// idx+1 ok
-					fileIdx = fileIdx + 1;
-				} else {
-					// basename doesn't match
-					continue;
-				}
-			}
-			if (FileOps.classForFilename(dirFiles[fileIdx]) == fileClass) {
-				/* logger.debug("adding file " + dirFiles[fileIdx]
-						+ " to Fileset " + this.getName()); */
-				add(new ImageFile(dirFiles[fileIdx], this, dirs[dirIdx]));
-			}
-		}
-	}
-
-	/**
-	 * Checks metadata and sets resolution in resX and resY.
-	 *  
-	 */
-	public void checkMeta() {
-		if (metaChecked) {
-			return;
-		}
-		if (fileMeta == null) {
-			// try to read metadata file
-			readMeta();
-			if (fileMeta == null) {
-				// try directory metadata
-				((DocuDirectory) parent).checkMeta();
-				if (((DocuDirectory) parent).getDirMeta() != null) {
-					fileMeta = ((DocuDirectory) parent).getDirMeta();
-				} else {
-					// try parent directory metadata
-					DocuDirectory gp = (DocuDirectory) parent.getParent();
-					if (gp != null) {
-						gp.checkMeta();
-						if (gp.getDirMeta() != null) {
-							fileMeta = gp.getDirMeta();
-						}
-					}
-				}
-			}
-		}
-		if (fileMeta == null) {
-			// no metadata available
-			metaChecked = true;
-			return;
-		}
-		metaChecked = true;
-		float dpi = 0;
-		float dpix = 0;
-		float dpiy = 0;
-		float sizex = 0;
-		float sizey = 0;
-		float pixx = 0;
-		float pixy = 0;
-		// DPI is valid for X and Y
-		if (fileMeta.containsKey("original-dpi")) {
-			try {
-				dpi = Float.parseFloat((String) fileMeta.get("original-dpi"));
-			} catch (NumberFormatException e) {
-			}
-			if (dpi != 0) {
-				resX = dpi;
-				resY = dpi;
-				return;
-			}
-		}
-		// DPI-X and DPI-Y
-		if (fileMeta.containsKey("original-dpi-x")
-				&& fileMeta.containsKey("original-dpi-y")) {
-			try {
-				dpix = Float.parseFloat((String) fileMeta
-						.get("original-dpi-x"));
-				dpiy = Float.parseFloat((String) fileMeta
-						.get("original-dpi-y"));
-			} catch (NumberFormatException e) {
-			}
-			if ((dpix != 0) && (dpiy != 0)) {
-				resX = dpix;
-				resY = dpiy;
-				return;
-			}
-		}
-		// SIZE-X and SIZE-Y and PIXEL-X and PIXEL-Y
-		if (fileMeta.containsKey("original-size-x")
-				&& fileMeta.containsKey("original-size-y")
-				&& fileMeta.containsKey("original-pixel-x")
-				&& fileMeta.containsKey("original-pixel-y")) {
-			try {
-				sizex = Float.parseFloat((String) fileMeta
-						.get("original-size-x"));
-				sizey = Float.parseFloat((String) fileMeta
-						.get("original-size-y"));
-				pixx = Float.parseFloat((String) fileMeta
-						.get("original-pixel-x"));
-				pixy = Float.parseFloat((String) fileMeta
-						.get("original-pixel-y"));
-			} catch (NumberFormatException e) {
-			}
-			if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) {
-				resX = pixx / (sizex * 100 / 2.54f);
-				resY = pixy / (sizey * 100 / 2.54f);
-				return;
-			}
-		}
-	}
-
-	/**
-	 * @return
-	 */
-	public float getResX() {
-		return resX;
-	}
-
-	/**
-	 * @return
-	 */
-	public float getResY() {
-		return resY;
-	}
-
-	/**
-	 * Sets the aspect ratio from an ImageSize.
-	 * 
-	 * 
-	 * @param f
-	 */
-	public void setAspect(ImageSize s) {
-		aspect = s.getAspect();
-	}
-
-	/**
-	 * Returns the aspect ratio.
-	 * 
-	 * Aspect ratio is (width/height). So it's <1 for portrait and >1 for
-	 * landscape.
-	 * 
-	 * 
-	 * @return
-	 */
-	public float getAspect() {
-		return aspect;
-	}
-
-}
\ No newline at end of file
--- a/servlet/src/digilib/io/ImageInput.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/ImageInput.java	Wed Dec 22 18:32:06 2010 +0100
@@ -21,9 +21,6 @@
 
 package digilib.io;
 
-import java.io.File;
-import java.io.InputStream;
-
 import digilib.image.ImageSize;
 
 public abstract class ImageInput {
@@ -33,36 +30,6 @@
 	// image size in pixels
 	protected ImageSize pixelSize = null;
 
-	/** Returns if this ImageInput is File-based.
-	 * @return
-	 */
-	public boolean hasFile() {
-		return false;
-	}
-	
-	/** Returns the underlying File (if applicable)
-	 * 
-	 * @return
-	 */
-	public File getFile() {
-		return null;
-	}
-
-	/** Returns if this ImageInput is Stream-based.
-	 * @return
-	 */
-	public boolean hasStream() {
-		return false;
-	}
-
-	/** Returns the underlying Stream (if applicable)
-	 * 
-	 * @return
-	 */
-	public InputStream getStream() {
-		return null;
-	}
-
 	/**
 	 * @return ImageSize
 	 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/src/digilib/io/ImageSet.java	Wed Dec 22 18:32:06 2010 +0100
@@ -0,0 +1,425 @@
+/* ImageSet -- digilib image file info 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  
+ */
+
+package digilib.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import digilib.image.ImageSize;
+import digilib.io.FileOps.FileClass;
+import digilib.servlet.DigilibConfiguration;
+
+/**
+ * @author casties
+ */
+public class ImageSet {
+
+	/** this is an image file */
+	protected static FileClass fileClass = FileClass.IMAGE;
+	
+	/** list of files (ImageFile) */
+	private List<ImageInput> list = null;
+
+	/** aspect ratio (width/height) */
+	private float aspect = 0f;
+
+	/** resolution of the biggest image (DPI) */
+	private float resX = 0f;
+
+	/** resolution of the biggest image (DPI) */
+	private float resY = 0f;
+
+	private Directory parent;
+
+	private boolean metaChecked;
+
+	private Map fileMeta;
+
+	/**
+	 * Creator for empty fileset.
+	 * 
+	 * 
+	 * @param initialCapacity
+	 */
+	public ImageSet() {
+		list = new ArrayList<ImageInput>();
+	}
+
+	/**
+	 * Constructor with a file and hints.
+	 * 
+	 * The hints are expected to contain 'basedirs' and 'scaledfilext' keys.
+	 * 
+	 * @param file
+	 * @param hints
+	 */
+	public ImageSet(File file, Map<Integer,Object> hints) {
+		Directory[] dirs = (Directory[]) hints.get(FileOps.HINT_BASEDIRS);
+		int nb = dirs.length;
+		list = new ArrayList<ImageInput>(nb);
+		parent = dirs[0];
+		fill(dirs, file, hints);
+	}
+
+	/**
+	 * Adds an ImageFile to this Fileset.
+	 * 
+	 * The files should be added in the order of higher to lower resolutions.
+	 * The first file is considered the hires "original".
+	 * 
+	 * 
+	 * @param f
+	 *            file to add
+	 * @return true (always)
+	 */
+	public boolean add(ImageFile f) {
+		f.setParent(this);
+		return list.add(f);
+	}
+
+	/**
+	 * The number of image files in this Fileset.
+	 * 
+	 * 
+	 * @return number of image files
+	 */
+	public int size() {
+		return (list != null) ? list.size() : 0;
+	}
+
+	/**
+	 * Gets the default File.
+	 *  
+	 */
+	public ImageInput getInput() {
+		//return (list != null) ? list.get(0).getFile() : null;
+		return null;
+	}
+
+	/**
+	 * Get the ImageFile at the index.
+	 * 
+	 * 
+	 * @param index
+	 * @return
+	 */
+	public ImageInput get(int index) {
+		return list.get(index);
+	}
+
+	/**
+	 * Get the next smaller ImageFile than the given size.
+	 * 
+	 * Returns the ImageFile from the set that has a width and height smaller or
+	 * equal the given size. Returns null if there isn't any smaller image.
+	 * Needs DocuInfo instance to checkFile().
+	 * 
+	 * 
+	 * @param size
+	 * @param info
+	 * @return
+	 */
+	public ImageInput getNextSmaller(ImageSize size) {
+		for (ListIterator<ImageInput> i = getHiresIterator(); i.hasNext();) {
+			ImageInput f = i.next();
+			try {
+				if (!f.isChecked()) {
+					DigilibConfiguration.docuImageIdentify((ImageFile) f);
+				}
+				if (f.getSize().isTotallySmallerThan(size)) {
+					return f;
+				}
+			} catch (IOException e) {
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Get the next bigger ImageFile than the given size.
+	 * 
+	 * Returns the ImageFile from the set that has a width or height bigger or
+	 * equal the given size. Returns null if there isn't any bigger image. Needs
+	 * DocuInfo instance to checkFile().
+	 * 
+	 * 
+	 * @param size
+	 * @param info
+	 * @return
+	 */
+	public ImageInput getNextBigger(ImageSize size) {
+		for (ListIterator<ImageInput> i = getLoresIterator(); i.hasPrevious();) {
+			ImageInput f = i.previous();
+			try {
+				if (!f.isChecked()) {
+					DigilibConfiguration.docuImageIdentify((ImageFile) f);
+				}
+				if (f.getSize().isBiggerThan(size)) {
+					return f;
+				}
+			} catch (IOException e) {
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the biggest ImageFile in the set.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ImageInput getBiggest() {
+		return this.get(0);
+	}
+
+	/**
+	 * Returns the biggest ImageFile in the set.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ImageInput getSmallest() {
+		return this.get(this.size() - 1);
+	}
+
+	/**
+	 * Get an Iterator for this Fileset starting at the highest resolution
+	 * images.
+	 * 
+	 * 
+	 * @return
+	 */
+	public ListIterator<ImageInput> getHiresIterator() {
+		return list.listIterator();
+	}
+
+	/**
+	 * Get an Iterator for this Fileset starting at the lowest resolution
+	 * images.
+	 * 
+	 * The Iterator starts at the last element, so you have to use it backwards
+	 * with hasPrevious() and previous().
+	 * 
+	 * 
+	 * @return
+	 */
+	public ListIterator<ImageInput> getLoresIterator() {
+		return list.listIterator(list.size());
+	}
+
+	/**
+	 * Fill the ImageSet with files from different base directories.
+	 * 
+	 * 
+	 * @param dirs
+	 *            list of base directories
+	 * @param fl
+	 *            file (from first base dir)
+	 * @param hints
+	 *  
+	 */
+	void fill(Directory[] dirs, File fl, Map<Integer,Object> hints) {
+		int nb = dirs.length;
+		String fn = fl.getName();
+		String baseFn = FileOps.basename(fn);
+		// add the first ImageFile to the ImageSet
+		add(new ImageFile(fn, this, parent));
+		// iterate the remaining base directories
+		for (int dirIdx = 1; dirIdx < nb; dirIdx++) {
+			if (dirs[dirIdx] == null) {
+				continue;
+			}
+			// read the directory
+			if (dirs[dirIdx].getFilenames() == null) {
+				dirs[dirIdx].readDir();
+			}
+			String[] dirFiles = dirs[dirIdx].getFilenames();
+			// try the same filename as the original
+			int fileIdx = Arrays.binarySearch(dirFiles, fn);
+			if (fileIdx < 0) {
+				// try closest matches without extension
+				fileIdx = -fileIdx - 1;
+				// try idx
+				if ((fileIdx < dirFiles.length)
+						&& (FileOps.basename(dirFiles[fileIdx]).equals(baseFn))) {
+					// idx ok
+				} else if ((fileIdx > 0)
+						&& (FileOps.basename(dirFiles[fileIdx - 1])
+								.equals(baseFn))) {
+					// idx-1 ok
+					fileIdx = fileIdx - 1;
+				} else if ((fileIdx+1 < dirFiles.length)
+						&& (FileOps.basename(dirFiles[fileIdx + 1])
+								.equals(baseFn))) {
+					// idx+1 ok
+					fileIdx = fileIdx + 1;
+				} else {
+					// basename doesn't match
+					continue;
+				}
+			}
+			if (FileOps.classForFilename(dirFiles[fileIdx]) == fileClass) {
+				/* logger.debug("adding file " + dirFiles[fileIdx]
+						+ " to Fileset " + this.getName()); */
+				add(new ImageFile(dirFiles[fileIdx], this, dirs[dirIdx]));
+			}
+		}
+	}
+
+	/**
+	 * Checks metadata and sets resolution in resX and resY.
+	 *  
+	 */
+	public void checkMeta() {
+		if (metaChecked) {
+			return;
+		}
+		if (fileMeta == null) {
+			// try to read metadata file
+			readMeta();
+			if (fileMeta == null) {
+				// try directory metadata
+				((DocuDirectory) parent).checkMeta();
+				if (((DocuDirectory) parent).getDirMeta() != null) {
+					fileMeta = ((DocuDirectory) parent).getDirMeta();
+				} else {
+					// try parent directory metadata
+					DocuDirectory gp = (DocuDirectory) parent.getParent();
+					if (gp != null) {
+						gp.checkMeta();
+						if (gp.getDirMeta() != null) {
+							fileMeta = gp.getDirMeta();
+						}
+					}
+				}
+			}
+		}
+		if (fileMeta == null) {
+			// no metadata available
+			metaChecked = true;
+			return;
+		}
+		metaChecked = true;
+		float dpi = 0;
+		float dpix = 0;
+		float dpiy = 0;
+		float sizex = 0;
+		float sizey = 0;
+		float pixx = 0;
+		float pixy = 0;
+		// DPI is valid for X and Y
+		if (fileMeta.containsKey("original-dpi")) {
+			try {
+				dpi = Float.parseFloat((String) fileMeta.get("original-dpi"));
+			} catch (NumberFormatException e) {
+			}
+			if (dpi != 0) {
+				resX = dpi;
+				resY = dpi;
+				return;
+			}
+		}
+		// DPI-X and DPI-Y
+		if (fileMeta.containsKey("original-dpi-x")
+				&& fileMeta.containsKey("original-dpi-y")) {
+			try {
+				dpix = Float.parseFloat((String) fileMeta
+						.get("original-dpi-x"));
+				dpiy = Float.parseFloat((String) fileMeta
+						.get("original-dpi-y"));
+			} catch (NumberFormatException e) {
+			}
+			if ((dpix != 0) && (dpiy != 0)) {
+				resX = dpix;
+				resY = dpiy;
+				return;
+			}
+		}
+		// SIZE-X and SIZE-Y and PIXEL-X and PIXEL-Y
+		if (fileMeta.containsKey("original-size-x")
+				&& fileMeta.containsKey("original-size-y")
+				&& fileMeta.containsKey("original-pixel-x")
+				&& fileMeta.containsKey("original-pixel-y")) {
+			try {
+				sizex = Float.parseFloat((String) fileMeta
+						.get("original-size-x"));
+				sizey = Float.parseFloat((String) fileMeta
+						.get("original-size-y"));
+				pixx = Float.parseFloat((String) fileMeta
+						.get("original-pixel-x"));
+				pixy = Float.parseFloat((String) fileMeta
+						.get("original-pixel-y"));
+			} catch (NumberFormatException e) {
+			}
+			if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) {
+				resX = pixx / (sizex * 100 / 2.54f);
+				resY = pixy / (sizey * 100 / 2.54f);
+				return;
+			}
+		}
+	}
+
+	private void readMeta() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/**
+	 * @return
+	 */
+	public float getResX() {
+		return resX;
+	}
+
+	/**
+	 * @return
+	 */
+	public float getResY() {
+		return resY;
+	}
+
+	/**
+	 * Sets the aspect ratio from an ImageSize.
+	 * 
+	 * 
+	 * @param f
+	 */
+	public void setAspect(ImageSize s) {
+		aspect = s.getAspect();
+	}
+
+	/**
+	 * Returns the aspect ratio.
+	 * 
+	 * Aspect ratio is (width/height). So it's <1 for portrait and >1 for
+	 * landscape.
+	 * 
+	 * 
+	 * @return
+	 */
+	public float getAspect() {
+		return aspect;
+	}
+
+}
\ No newline at end of file
--- a/servlet/src/digilib/io/SVGFile.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/SVGFile.java	Wed Dec 22 18:32:06 2010 +0100
@@ -55,7 +55,7 @@
 	/* (non-Javadoc)
 	 * @see digilib.io.DocuDirent#getFile()
 	 */
-	public File getFile() {
+	public File getInput() {
 		return file;
 	}
 
--- a/servlet/src/digilib/io/TextFile.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/io/TextFile.java	Wed Dec 22 18:32:06 2010 +0100
@@ -55,7 +55,7 @@
 	/* (non-Javadoc)
 	 * @see digilib.io.DocuDirent#getFile()
 	 */
-	public File getFile() {
+	public File getInput() {
 		return file;
 	}
 
--- a/servlet/src/digilib/servlet/DocumentBean.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/servlet/DocumentBean.java	Wed Dec 22 18:32:06 2010 +0100
@@ -38,7 +38,7 @@
 import digilib.io.DocuDirectory;
 import digilib.io.FileOps.FileClass;
 import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageSet;
 
 public class DocumentBean {
 
@@ -191,7 +191,7 @@
 		}
 		String fn = dlRequest.getFilePath();
 		// get information about the file
-		ImageFileset fileset = (ImageFileset) dirCache.getFile(fn, dlRequest
+		ImageSet fileset = (ImageSet) dirCache.getFile(fn, dlRequest
 				.getAsInt("pn"), FileClass.IMAGE);
 		if (fileset == null) {
 			return;
--- a/servlet/src/digilib/servlet/Texter.java	Wed Dec 22 09:54:34 2010 +0100
+++ b/servlet/src/digilib/servlet/Texter.java	Wed Dec 22 18:32:06 2010 +0100
@@ -140,11 +140,11 @@
 			 */
 			TextFile f = getTextFile(dlRequest, "/txt");
 			if (f != null) {
-				ServletOps.sendFile(f.getFile(), null, null, response);
+				ServletOps.sendFile(f.getInput(), null, null, response);
 			} else {
 				f = getTextFile(dlRequest, "");
 				if (f != null) {
-					ServletOps.sendFile(f.getFile(),	null, null, response);
+					ServletOps.sendFile(f.getInput(),	null, null, response);
 				} else {
 					response.sendError(HttpServletResponse.SC_NOT_FOUND, "Text-File not found!");
 					//ServletOps.htmlMessage("No Text-File!", response);