# HG changeset patch
# User robcast
# Date 1298279709 -3600
# Node ID e6d0cdaa79236ddd4ed512e399ea3702fa97522d
# Parent 5de6c7a738556724c9785859eddb3774981cd199# Parent 60e8cca7ac8125ec431f9b05a829c74aa2ca5ef6
Merge from jquery branch
60e8cca7ac8125ec431f9b05a829c74aa2ca5ef6
diff -r 60e8cca7ac81 -r e6d0cdaa7923 client/digitallibrary/ImgInfo-json.jsp
--- a/client/digitallibrary/ImgInfo-json.jsp Mon Feb 21 01:20:22 2011 +0100
+++ b/client/digitallibrary/ImgInfo-json.jsp Mon Feb 21 10:15:09 2011 +0100
@@ -1,6 +1,6 @@
<%@page language="java"
- import="digilib.io.FileOps, digilib.io.ImageFileset, digilib.io.ImageFile,
- digilib.image.ImageSize, digilib.servlet.DigilibConfiguration"
+ import="digilib.io.FileOps, digilib.io.ImageFileSet, digilib.io.ImageFile,
+ digilib.util.ImageSize, digilib.servlet.DigilibConfiguration"
contentType="application/json"%><%!
// create DocumentBean instance for all JSP requests
digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean();
@@ -23,14 +23,11 @@
digilib.io.DocuDirCache dirCache = (digilib.io.DocuDirCache) dlConfig.getValue("servlet.dir.cache");
// get file
FileOps.FileClass fc = FileOps.FileClass.IMAGE;
-ImageFileset imgFile = (ImageFileset) dirCache.getFile(dlRequest.getFilePath(), dlRequest.getAsInt("pn"), fc);
+ImageFileSet imgFile = (ImageFileSet) dirCache.getFile(dlRequest.getFilePath(), dlRequest.getAsInt("pn"), fc);
%>{ <%
if (imgFile != null) {
- ImageFile img = imgFile.getBiggest();
- if (!img.isChecked()) {
- DigilibConfiguration.docuImageIdentify(img);
- }
+ ImageFile img = (ImageFile) imgFile.getBiggest();
ImageSize imgSize = img.getSize();
%>
"filename" : "<%= imgFile.getName() %>",
diff -r 60e8cca7ac81 -r e6d0cdaa7923 client/digitallibrary/WEB-INF/digilib-config.xml
--- a/client/digitallibrary/WEB-INF/digilib-config.xml Mon Feb 21 01:20:22 2011 +0100
+++ b/client/digitallibrary/WEB-INF/digilib-config.xml Mon Feb 21 10:15:09 2011 +0100
@@ -23,7 +23,7 @@
-
+
diff -r 60e8cca7ac81 -r e6d0cdaa7923 client/digitallibrary/WEB-INF/web-2.3.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/digitallibrary/WEB-INF/web-2.3.xml Mon Feb 21 10:15:09 2011 +0100
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+ digilib
+
+
+ This is the web frontend of the Digital Document Library.
+
+
+
+
+ digilib.servlet.Initialiser
+
+
+
+
+
+ Scaler
+
+
+ digilib.servlet.ScalerNoAsync
+
+
+
+ 5
+
+
+
+
+
+ Texter
+
+
+ digilib.servlet.Texter
+
+
+
+
+
+ PDFCache
+
+
+ digilib.servlet.PDFCache
+
+
+
+
+
+ Scaler
+
+
+ /servlet/Scaler/*
+
+
+
+
+ Scaler
+
+
+ /Scaler
+
+
+
+
+ Scaler
+
+
+ /authenticated/servlet/Scaler/*
+
+
+
+
+
+ Texter
+
+
+ /servlet/Texter/*
+
+
+
+
+ Texter
+
+
+ /authenticated/servlet/Texter/*
+
+
+
+
+
+ PDFCache
+
+
+ /servlet/PDFCache/*
+
+
+
+
+ PDFCache
+
+
+ /authenticated/servlet/PDFCache/*
+
+
+
+
+
+
+ Authenticated Digilib
+
+
+ /authenticated/*
+
+
+
+
+
+
+
+
+ FORM
+
+
+
+ /digilib-login.html
+
+
+ /digilib-fail.html
+
+
+
+
diff -r 60e8cca7ac81 -r e6d0cdaa7923 client/digitallibrary/WEB-INF/web.xml
--- a/client/digitallibrary/WEB-INF/web.xml Mon Feb 21 01:20:22 2011 +0100
+++ b/client/digitallibrary/WEB-INF/web.xml Mon Feb 21 10:15:09 2011 +0100
@@ -1,8 +1,10 @@
-
-
-
+
+
+
digilib
@@ -10,30 +12,17 @@
This is the web frontend of the Digital Document Library.
-
-
-
- Initialiser
-
-
- The inialisation servlet (must run first).
-
-
+
+
+
digilib.servlet.Initialiser
-
-
-
- 1
-
-
-
+
+
+
Scaler
-
- The servlet to scale the digilib images.
-
digilib.servlet.Scaler
@@ -47,9 +36,6 @@
Texter
-
- The servlet for text.
-
digilib.servlet.Texter
@@ -59,9 +45,6 @@
PDFCache
-
- The servlet for PDF.
-
digilib.servlet.PDFCache
@@ -80,6 +63,14 @@
Scaler
+ /Scaler
+
+
+
+
+ Scaler
+
+
/authenticated/servlet/Scaler/*
diff -r 60e8cca7ac81 -r e6d0cdaa7923 client/digitallibrary/digimage_tbl_inc.jsp
--- a/client/digitallibrary/digimage_tbl_inc.jsp Mon Feb 21 01:20:22 2011 +0100
+++ b/client/digitallibrary/digimage_tbl_inc.jsp Mon Feb 21 10:15:09 2011 +0100
@@ -1,6 +1,6 @@
<%@ page language="java" %><%
// retrieve objects from context
-digilib.servlet.DocumentBean docBean = (digilib.servlet.DocumentBean) pageContext.getAttribute("docBean", pageContext.REQUEST_SCOPE);
+digilib.servlet.DocumentBean docBean = (digilib.servlet.DocumentBean) pageContext.getAttribute("docBean", PageContext.REQUEST_SCOPE);
digilib.servlet.DigilibRequest dlRequest = docBean.getRequest();
String ua = request.getHeader("User-Agent");
boolean isN4 = ((ua.indexOf("Mozilla/4.") > -1)&&(ua.indexOf("MSIE") == -1));
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/DigilibServlet.jardesc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlet/DigilibServlet.jardesc Mon Feb 21 10:15:09 2011 +0100
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/auth/HashTree.java
--- a/servlet/src/digilib/auth/HashTree.java Mon Feb 21 01:20:22 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/* HashTree -- Tree in a Hashtable
-
- Digital Image Library servlet components
-
- Copyright (C) 2001, 2002 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.auth;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Tree representation wrapper for a HashMap.
- *
- * The HashTree is constructed from a HashMap filled with 'branches' with
- * 'leaves'. The branches are stored as String keys in the HashMap. The String
- * values are leaves.
- *
- * Branches are matched in 'twigs' separated by 'twig separator' Strings. The
- * return values for a match are leaf values separated by 'leaf separator'
- * Strings.
- *
- * @author casties
- */
-public class HashTree {
-
- private Map table;
-
- private String twigSep = "/";
-
- private String leafSep = ",";
-
- /**
- * Constructor of a HashTree.
- *
- * Creates a HashTree wrapper around a given HashMap, using the given twig
- * separator and leaf separator.
- *
- * @param t
- * @param twig_separator
- * @param leaf_separator
- */
- public HashTree(Map t, String twig_separator, String leaf_separator) {
- table = t;
- twigSep = twig_separator;
- leafSep = leaf_separator;
- optimizeTable();
- }
-
- void optimizeTable() {
- }
-
- /**
- * Matches the given branch against the HashTree.
- *
- * Returns a LinkedList of all leaves on all matching branches in the tree.
- * Branches in the tree match if they are substrings starting at the same
- * root.
- *
- * @param branch
- * @return
- */
- List match(String branch) {
- String b = "";
- String m;
- LinkedList matches = new LinkedList();
-
- // split branch
- StringTokenizer twig = new StringTokenizer(branch, twigSep);
- // walk branch and check with tree
- while (twig.hasMoreTokens()) {
- if (b.length() == 0) {
- b = twig.nextToken();
- } else {
- b += twigSep + twig.nextToken();
- }
- m = table.get(b);
- if (m != null) {
- if (m.indexOf(leafSep) < 0) {
- // single leaf
- matches.add(m);
- } else {
- // split leaves
- StringTokenizer leaf = new StringTokenizer(m, leafSep);
- while (leaf.hasMoreTokens()) {
- matches.add(leaf.nextToken());
- }
- }
- }
- }
- if (matches.size() > 0) {
- return matches;
- } else {
- return null;
- }
- }
-}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/auth/XMLAuthOps.java
--- a/servlet/src/digilib/auth/XMLAuthOps.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/auth/XMLAuthOps.java Mon Feb 21 10:15:09 2011 +0100
@@ -26,8 +26,9 @@
import javax.servlet.http.HttpServletRequest;
-import digilib.io.XMLListLoader;
import digilib.servlet.DigilibRequest;
+import digilib.util.HashTree;
+import digilib.util.XMLListLoader;
/** Implementation of AuthOps using XML files.
*
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/DocuImage.java
--- a/servlet/src/digilib/image/DocuImage.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/DocuImage.java Mon Feb 21 10:15:09 2011 +0100
@@ -27,8 +27,9 @@
import javax.servlet.ServletException;
-import digilib.io.ImageFile;
import digilib.io.FileOpException;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** The basic class for the representation of a digilib image.
*
@@ -41,12 +42,12 @@
/** Loads an image file into the Object.
*
- * @param f Image File.
+ * @param ii Image File.
* @throws FileOpException Exception thrown if any error occurs.
*/
- public void loadImage(ImageFile f) throws FileOpException;
+ public void loadImage(ImageInput ii) throws FileOpException;
- /** This DocuImage support the loadSubImage operation.
+ /** This DocuImage supports the loadSubImage operation.
*
* @return boolean
*/
@@ -54,12 +55,12 @@
/** Load only a subsampled region of the image file.
*
- * @param f
+ * @param ii
* @param region
* @param subsample
* @throws FileOpException
*/
- public void loadSubimage(ImageFile f, Rectangle region, int subsample)
+ public void loadSubimage(ImageInput ii, Rectangle region, int subsample)
throws FileOpException;
/** Writes the current image to a ServletResponse.
@@ -95,7 +96,7 @@
*/
public ImageSize getSize();
- /** The mime-type of the current image.
+ /** The mime-type of the image, i.e. the mime-type of the input that was read.
*
* @return String the mime-type of this image.
*/
@@ -221,9 +222,9 @@
public void dispose();
/**
- * Check image size and type and store in ImageFile f
+ * Check image size and type and store in ImageInput ii
*/
- public ImageFile identify(ImageFile imgf) throws IOException;
+ public ImageInput identify(ImageInput ii) throws IOException;
/**
* Returns a list of supported image formats
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/DocuImageImpl.java
--- a/servlet/src/digilib/image/DocuImageImpl.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/DocuImageImpl.java Mon Feb 21 10:15:09 2011 +0100
@@ -33,7 +33,8 @@
import org.apache.log4j.Logger;
import digilib.io.FileOpException;
-import digilib.io.ImageFile;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** Simple abstract implementation of the DocuImage
interface.
*
@@ -53,13 +54,13 @@
/** epsilon for float comparisons. */
public final double epsilon = 1e-5;
-
- /** image mime-type */
- protected String mimeType = null;
/** image size */
protected ImageSize imgSize = null;
+ /** ImageInput that was read */
+ protected ImageInput input;
+
/**
* Returns the quality.
* @return int
@@ -99,14 +100,20 @@
scale(scale, scale);
}
+ /* (non-Javadoc)
+ * @see digilib.image.DocuImage#getMimetype()
+ */
public String getMimetype() {
- return mimeType;
+ if (input != null) {
+ return input.getMimetype();
+ }
+ return null;
}
/* (non-Javadoc)
* @see digilib.image.DocuImage#identify(digilib.io.ImageFile)
*/
- public ImageFile identify(ImageFile imgf) throws IOException {
+ public ImageInput identify(ImageInput ii) throws IOException {
// just a do-nothing implementation
return null;
}
@@ -128,7 +135,7 @@
return false;
}
- public void loadSubimage(ImageFile f, Rectangle region, int subsample)
+ public void loadSubimage(ImageInput ii, Rectangle region, int subsample)
throws FileOpException {
// empty implementation
}
@@ -177,19 +184,11 @@
return imgSize;
}
- public void loadImage(ImageFile f) throws FileOpException {
- // TODO Auto-generated method stub
-
- }
+ public abstract void loadImage(ImageInput ii) throws FileOpException;
- public void scale(double scaleX, double scaleY) throws ImageOpException {
- // TODO Auto-generated method stub
-
- }
+ public abstract void scale(double scaleX, double scaleY) throws ImageOpException;
- public void writeImage(String mt, OutputStream ostream)
- throws ServletException, ImageOpException {
- // TODO Auto-generated method stub
- }
+ public abstract void writeImage(String mt, OutputStream ostream)
+ throws ServletException, ImageOpException;
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/ImageInfoDocuImage.java
--- a/servlet/src/digilib/image/ImageInfoDocuImage.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/ImageInfoDocuImage.java Mon Feb 21 10:15:09 2011 +0100
@@ -3,13 +3,13 @@
*/
package digilib.image;
-import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.marcoschmidt.image.ImageInfo;
-import digilib.io.ImageFile;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** Simple abstract implementation of the DocuImage
interface.
* Implements only the identify method using the ImageInfo class.
@@ -18,31 +18,28 @@
*/
public abstract class ImageInfoDocuImage extends DocuImageImpl {
- /** Check image size and type and store in ImageFile f */
- public ImageFile identify(ImageFile imgf) throws IOException {
- // fileset to store the information
- File f = imgf.getFile();
- if (f == null) {
- throw new IOException("File not found!");
- }
- RandomAccessFile raf = new RandomAccessFile(f, "r");
+ /* Check image size and type and store in ImageFile f */
+ public ImageInput identify(ImageInput ii) throws IOException {
+ logger.debug("identifying (ImageInfo) " + ii);
// set up ImageInfo object
ImageInfo iif = new ImageInfo();
- iif.setInput(raf);
+ if (ii.hasImageInputStream()) {
+ iif.setInput(ii.getImageInputStream());
+ } else if (ii.hasFile()) {
+ RandomAccessFile raf = new RandomAccessFile(ii.getFile(), "r");
+ iif.setInput(raf);
+ } else {
+ return null;
+ }
iif.setCollectComments(false);
iif.setDetermineImageNumber(false);
- logger.debug("identifying (ImageInfo) " + f);
// try with ImageInfo first
if (iif.check()) {
ImageSize d = new ImageSize(iif.getWidth(), iif.getHeight());
- imgf.setSize(d);
- imgf.setMimetype(iif.getMimeType());
- //logger.debug(" format:"+iif.getFormatName());
- raf.close();
- logger.debug("image size: " + imgf.getSize());
- return imgf;
- } else {
- raf.close();
+ ii.setSize(d);
+ ii.setMimetype(iif.getMimeType());
+ logger.debug("image size: " + ii.getSize());
+ return ii;
}
return null;
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/ImageJobDescription.java
--- a/servlet/src/digilib/image/ImageJobDescription.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/ImageJobDescription.java Mon Feb 21 10:15:09 2011 +0100
@@ -11,24 +11,23 @@
import digilib.io.FileOpException;
import digilib.io.FileOps;
import digilib.io.FileOps.FileClass;
-import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageInput;
+import digilib.io.ImageSet;
import digilib.servlet.DigilibConfiguration;
+import digilib.util.ImageSize;
import digilib.util.OptionsSet;
import digilib.util.Parameter;
import digilib.util.ParameterMap;
-
-/**
- * A container class for storing a set of instructional parameters
- * used for content generating classes like MakePDF.
+/**
+ * A class for storing the set of parameters necessary for scaling images
+ * with an ImageWorker.
*
- * This contains the functionality formerly found in Scaler, processRequest, only factorized.
- *
- * TODO clean up...
+ * This contains the functionality formerly found in Scaler.processRequest(),
+ * only factorized.
*
* @author cmielack, casties
- *
+ *
*/
public class ImageJobDescription extends ParameterMap {
@@ -36,18 +35,18 @@
DigilibConfiguration dlConfig = null;
protected static Logger logger = Logger.getLogger("digilib.servlet");
- ImageFile fileToLoad = null;
- ImageFileset fileset = null;
+ ImageInput input = null;
+ ImageSet imageSet = null;
DocuDirectory fileDir = null;
String filePath = null;
ImageSize expectedSourceSize = null;
Float scaleXY = null;
Rectangle2D userImgArea = null;
- Rectangle2D outerUserImgArea= null;
+ Rectangle2D outerUserImgArea = null;
Boolean imageSendable = null;
- String mimeType;
- Integer paramDW;
- Integer paramDH;
+ String mimeType = null;
+ Integer paramDW = null;
+ Integer paramDH = null;
/** create empty ImageJobDescription.
* @param dlcfg
@@ -128,48 +127,56 @@
}
+ /** Returns the mime-type (of the input).
+ * @return
+ * @throws IOException
+ */
public String getMimeType() throws IOException {
if (mimeType == null) {
- fileToLoad = getFileToLoad();
- if(! fileToLoad.isChecked()){
- DigilibConfiguration.docuImageIdentify(fileToLoad);
- }
- mimeType = fileToLoad.getMimetype();
+ input = getInput();
+ mimeType = input.getMimetype();
}
return mimeType;
}
- public ImageFile getFileToLoad() throws IOException {
-
- if(fileToLoad == null){
- fileset = getFileset();
+ /** Returns the ImageInput to use.
+ * @return
+ * @throws IOException
+ */
+ public ImageInput getInput() throws IOException {
+ if(input == null){
+ imageSet = getImageSet();
/* select a resolution */
- if (getHiresOnly()) {
+ if (isHiresOnly()) {
// get first element (= highest resolution)
- fileToLoad = fileset.getBiggest();
- } else if (getLoresOnly()) {
+ input = imageSet.getBiggest();
+ } else if (isLoresOnly()) {
// enforced lores uses next smaller resolution
- fileToLoad = fileset.getNextSmaller(getExpectedSourceSize());
- if (fileToLoad == null) {
+ input = imageSet.getNextSmaller(getExpectedSourceSize());
+ if (input == null) {
// this is the smallest we have
- fileToLoad = fileset.getSmallest();
+ input = imageSet.getSmallest();
}
} else {
// autores: use next higher resolution
- fileToLoad = fileset.getNextBigger(getExpectedSourceSize());
- if (fileToLoad == null) {
+ input = imageSet.getNextBigger(getExpectedSourceSize());
+ if (input == null) {
// this is the highest we have
- fileToLoad = fileset.getBiggest();
+ input = imageSet.getBiggest();
}
}
- logger.info("Planning to load: " + fileToLoad.getFile());
+ logger.info("Planning to load: " + input);
}
- return fileToLoad;
+ return input;
}
+ /** Returns the DocuDirectory for the input (file).
+ * @return
+ * @throws FileOpException
+ */
public DocuDirectory getFileDirectory() throws FileOpException {
if(fileDir == null){
DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
@@ -182,19 +189,26 @@
return fileDir;
}
- public ImageFileset getFileset() throws FileOpException {
- if(fileset==null){
+ /** Returns the ImageSet to load.
+ * @return
+ * @throws FileOpException
+ */
+ public ImageSet getImageSet() throws FileOpException {
+ if(imageSet==null){
DocuDirCache dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
- fileset = (ImageFileset) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
- if (fileset == null) {
+ imageSet = (ImageSet) dirCache.getFile(getFilePath(), getAsInt("pn"), FileClass.IMAGE);
+ if (imageSet == null) {
throw new FileOpException("File " + getFilePath() + "("
+ getAsInt("pn") + ") not found.");
}
}
- return fileset;
+ return imageSet;
}
+ /** Returns the file path name from the request.
+ * @return
+ */
public String getFilePath() {
if(filePath == null){
String s = this.getAsString("request.path");
@@ -204,32 +218,36 @@
return filePath;
}
- public boolean getHiresOnly(){
+ public boolean isHiresOnly(){
return hasOption("clip") || hasOption("hires");
}
- public boolean getLoresOnly(){
+ public boolean isLoresOnly(){
return hasOption("lores");
}
- public boolean getScaleToFit() {
+ public boolean isScaleToFit() {
return !(hasOption("clip") || hasOption("osize") || hasOption("ascale"));
}
- public boolean getAbsoluteScale(){
+ public boolean isAbsoluteScale(){
return hasOption("osize") || hasOption("ascale");
}
+ /** Returns the minimum size the source image should have for scaling.
+ * @return
+ * @throws IOException
+ */
public ImageSize getExpectedSourceSize() throws IOException {
if (expectedSourceSize == null){
expectedSourceSize = new ImageSize();
- if (getScaleToFit()) {
+ if (isScaleToFit()) {
// scale to fit -- calculate minimum source size
float scale = (1 / Math.min(getAsFloat("ww"), getAsFloat("wh"))) * getAsFloat("ws");
expectedSourceSize.setSize((int) (getDw() * scale),
(int) (getDh() * scale));
- } else if (getAbsoluteScale() && hasOption("ascale")) {
+ } else if (isAbsoluteScale() && hasOption("ascale")) {
// absolute scale -- apply scale to hires size
expectedSourceSize = getHiresSize().getScaled(getAsFloat("scale"));
} else {
@@ -241,16 +259,17 @@
return expectedSourceSize;
}
+ /** Returns the size of the highest resolution image.
+ * @return
+ * @throws IOException
+ */
public ImageSize getHiresSize() throws IOException {
logger.debug("get_hiresSize()");
ImageSize hiresSize = null;
- ImageFileset fileset = getFileset();
- if (getAbsoluteScale()) {
- ImageFile hiresFile = fileset.getBiggest();
- if (!hiresFile.isChecked()) {
- DigilibConfiguration.docuImageIdentify(hiresFile);
- }
+ ImageSet fileset = getImageSet();
+ if (isAbsoluteScale()) {
+ ImageInput hiresFile = fileset.getBiggest();
hiresSize = hiresFile.getSize();
}
return hiresSize;
@@ -270,7 +289,7 @@
float areaWidth;
float areaHeight;
float ws = getAsFloat("ws");
- ImageSize imgSize = getFileToLoad().getSize();
+ ImageSize imgSize = getInput().getSize();
// user window area in [0,1] coordinates
Rectangle2D relUserArea = new Rectangle2D.Float(getAsFloat("wx"), getAsFloat("wy"),
getAsFloat("ww"), getAsFloat("wh"));
@@ -281,20 +300,20 @@
userImgArea = imgTrafo.createTransformedShape(
relUserArea).getBounds2D();
- if (getScaleToFit()) {
+ if (isScaleToFit()) {
// calculate scaling factors based on inner user area
areaWidth = (float) userImgArea.getWidth();
areaHeight = (float) userImgArea.getHeight();
float scaleX = getDw() / areaWidth * ws;
float scaleY = getDh() / areaHeight * ws;
scaleXY = (scaleX > scaleY) ? scaleY : scaleX;
- } else if (getAbsoluteScale()) {
+ } else if (isAbsoluteScale()) {
// absolute scaling factor
if (hasOption("osize")) {
// get original resolution from metadata
- fileset.checkMeta();
- float origResX = fileset.getResX();
- float origResY = fileset.getResY();
+ imageSet.checkMeta();
+ float origResX = imageSet.getResX();
+ float origResY = imageSet.getResY();
if ((origResX == 0) || (origResY == 0)) {
throw new ImageOpException("Missing image DPI information!");
}
@@ -340,6 +359,11 @@
return (float) scaleXY;
}
+ /** Returns the width of the destination image.
+ * Uses dh parameter and aspect ratio if dw parameter is empty.
+ * @return
+ * @throws IOException
+ */
public int getDw() throws IOException {
logger.debug("get_paramDW()");
if (paramDW == null) {
@@ -347,7 +371,7 @@
paramDW = getAsInt("dw");
paramDH = getAsInt("dh");
- float imgAspect = getFileToLoad().getAspect();
+ float imgAspect = getInput().getAspect();
if (paramDW == 0) {
// calculate dw
paramDW = Math.round(paramDH * imgAspect);
@@ -361,6 +385,11 @@
return paramDW;
}
+ /** Returns the height of the destination image.
+ * Uses dw parameter and aspect ratio if dh parameter is empty.
+ * @return
+ * @throws IOException
+ */
public int getDh() throws IOException {
logger.debug("get_paramDH()");
if (paramDH == null) {
@@ -368,7 +397,7 @@
paramDW = getAsInt("dw");
paramDH = getAsInt("dh");
- float imgAspect = getFileToLoad().getAspect();
+ float imgAspect = getInput().getAspect();
if (paramDW == 0) {
// calculate dw
paramDW = Math.round(paramDH * imgAspect);
@@ -382,9 +411,12 @@
return paramDH;
}
- public Integer getScaleQual(){
+ /** Returns image quality as an integer.
+ * @return
+ */
+ public int getScaleQual(){
logger.debug("get_scaleQual()");
- Integer qual = dlConfig.getAsInt("default-quality");
+ int qual = dlConfig.getAsInt("default-quality");
if(hasOption("q0"))
qual = 0;
else if(hasOption("q1"))
@@ -395,21 +427,33 @@
}
+ /**
+ * Returns the area of the source image that will be transformed into the
+ * destination image.
+ *
+ * @return
+ * @throws IOException
+ * @throws ImageOpException
+ */
public Rectangle2D getUserImgArea() throws IOException, ImageOpException{
if(userImgArea == null) {
// getScaleXY sets userImgArea
getScaleXY();
}
return userImgArea;
-
}
+ /** Returns the maximal area of the source image that will be used.
+ * @return
+ * @throws IOException
+ * @throws ImageOpException
+ */
public Rectangle2D getOuterUserImgArea() throws IOException, ImageOpException {
if(outerUserImgArea == null){
outerUserImgArea = getUserImgArea();
// image size in pixels
- ImageSize imgSize = getFileToLoad().getSize();
+ ImageSize imgSize = getInput().getSize();
Rectangle2D imgBounds = new Rectangle2D.Float(0, 0, imgSize.getWidth(),
imgSize.getHeight());
@@ -437,10 +481,7 @@
float[] paramRGBM = null;//{0f,0f,0f};
Parameter p = params.get("rgbm");
if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) {
- paramRGBM = p.parseAsFloatArray("/");
- if ((paramRGBM == null) || (paramRGBM.length != 3)) {
- return null;
- }
+ return p.parseAsFloatArray("/");
}
return paramRGBM;
}
@@ -450,9 +491,6 @@
Parameter p = params.get("rgba");
if (p.hasValue() && (!p.getAsString().equals("0/0/0"))) {
paramRGBA = p.parseAsFloatArray("/");
- if ((paramRGBA == null) || (paramRGBA.length != 3)) {
- return null;
- }
}
return paramRGBA;
}
@@ -465,11 +503,13 @@
|| hasOption("rawfile");
}
- /** Could the image be sent without processing?
- * Takes image type and additional image operations into account.
- * Does not check requested size transformation.
+ /**
+ * Returns if the image can be sent without processing. Takes image type and
+ * additional image operations into account. Does not check requested size
+ * transformation.
+ *
* @return
- * @throws IOException
+ * @throws IOException
*/
public boolean isImageSendable() throws IOException {
// cached result?
@@ -492,15 +532,22 @@
}
+ /**
+ * Returns if any transformation of the source image (image manipulation or
+ * format conversion) is required.
+ *
+ * @return
+ * @throws IOException
+ */
public boolean isTransformRequired() throws IOException {
- ImageSize is = getFileToLoad().getSize();
+ ImageSize is = getInput().getSize();
ImageSize ess = getExpectedSourceSize();
// nt = no transform required
boolean nt = isImageSendable() && (
// lores: send if smaller
- (getLoresOnly() && is.isSmallerThan(ess))
+ (isLoresOnly() && is.isSmallerThan(ess))
// else send if it fits
- || (!(getLoresOnly() || getHiresOnly()) && is.fitsIn(ess)));
+ || (!(isLoresOnly() || isHiresOnly()) && is.fitsIn(ess)));
return ! nt;
}
}
\ No newline at end of file
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/ImageLoaderDocuImage.java
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java Mon Feb 21 10:15:09 2011 +0100
@@ -29,7 +29,6 @@
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.RescaleOp;
-import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
@@ -49,12 +48,12 @@
import digilib.io.FileOpException;
import digilib.io.FileOps;
-import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
public class ImageLoaderDocuImage extends ImageInfoDocuImage {
-
+
/** image object */
protected BufferedImage img;
@@ -64,9 +63,14 @@
/** ImageIO image reader */
protected ImageReader reader;
- /** File that was read */
- protected File imgFile;
-
+ protected static Kernel[] convolutionKernels = {
+ null,
+ new Kernel(1, 1, new float[] {1f}),
+ new Kernel(2, 2, new float[] {0.25f, 0.25f, 0.25f, 0.25f}),
+ new Kernel(3, 3, new float[] {1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f})
+ };
+
+
/* loadSubimage is supported. */
public boolean isSubimageSupported() {
return true;
@@ -118,44 +122,50 @@
return Arrays.asList(formats).iterator();
}
- /** Check image size and type and store in ImageFile f */
- public ImageFile identify(ImageFile imageFile) throws IOException {
+ /* Check image size and type and store in ImageInput */
+ public ImageInput identify(ImageInput input) throws IOException {
// try parent method first
- ImageFile imf = super.identify(imageFile);
- if (imf != null) {
- return imf;
+ ImageInput ii = super.identify(input);
+ if (ii != null) {
+ return ii;
}
- // fileset to store the information
- ImageFileset imgfs = imageFile.getParent();
- File f = imageFile.getFile();
- if (f == null) {
- throw new IOException("File not found!");
- }
- logger.debug("identifying (ImageIO) " + f);
+ logger.debug("identifying (ImageIO) " + input);
/*
* try ImageReader
*/
- if ((reader == null) || (imgFile != imageFile.getFile())) {
- getReader(imageFile);
+ try {
+ reader = getReader(input);
+ } catch (FileOpException e) {
+ // maybe just our class doesn't know what to do
+ return null;
}
+ // set size
ImageSize d = new ImageSize(reader.getWidth(0), reader.getHeight(0));
- imageFile.setSize(d);
- // String t = reader.getFormatName();
- String t = FileOps.mimeForFile(f);
- imageFile.setMimetype(t);
- // logger.debug(" format:"+t);
- if (imgfs != null) {
- imgfs.setAspect(d);
+ input.setSize(d);
+ // set mime type
+ if (input.getMimetype() == null) {
+ if (input.hasFile()) {
+ String t = FileOps.mimeForFile(input.getFile());
+ input.setMimetype(t);
+ } else {
+ // FIXME: is format name a mime type???
+ String t = reader.getFormatName();
+ input.setMimetype(t);
+ }
}
- return imageFile;
+ return input;
}
/* load image file */
- public void loadImage(ImageFile f) throws FileOpException {
- logger.debug("loadImage " + f.getFile());
+ public void loadImage(ImageInput ii) throws FileOpException {
+ logger.debug("loadImage: " + ii);
+ this.input = ii;
try {
- img = ImageIO.read(f.getFile());
- mimeType = f.getMimetype();
+ if (ii.hasImageInputStream()) {
+ img = ImageIO.read(ii.getImageInputStream());
+ } else if (ii.hasFile()) {
+ img = ImageIO.read(ii.getFile());
+ }
} catch (IOException e) {
throw new FileOpException("Error reading image.");
}
@@ -166,17 +176,32 @@
*
* @return
*/
- public ImageReader getReader(ImageFile f) throws IOException {
- logger.debug("preloadImage " + f.getFile());
- if (reader != null) {
- logger.debug("Reader was not null!");
- // clean up old reader
+ public ImageReader getReader(ImageInput input) throws IOException {
+ logger.debug("get ImageReader for " + input);
+ if (this.reader != null) {
+ if (this.input == input) {
+ // it was the same input
+ logger.debug("reusing Reader");
+ return reader;
+ }
+ // clean up old reader (this shouldn't really happen)
+ logger.debug("cleaning Reader!");
dispose();
}
- RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
- ImageInputStream istream = new FileImageInputStream(rf);
+ this.input = input;
+ ImageInputStream istream = null;
+ if (input.hasImageInputStream()) {
+ // stream input
+ istream = input.getImageInputStream();
+ } else if (input.hasFile()) {
+ // file only input
+ RandomAccessFile rf = new RandomAccessFile(input.getFile(), "r");
+ istream = new FileImageInputStream(rf);
+ } else {
+ throw new FileOpException("Unable to get data from ImageInput");
+ }
Iterator readers;
- String mt = f.getMimetype();
+ String mt = input.getMimetype();
if (mt == null) {
logger.debug("No mime-type. Trying automagic.");
readers = ImageIO.getImageReaders(istream);
@@ -185,7 +210,6 @@
readers = ImageIO.getImageReadersByMIMEType(mt);
}
if (!readers.hasNext()) {
- rf.close();
throw new FileOpException("Can't find Reader to load File!");
}
reader = readers.next();
@@ -195,18 +219,15 @@
logger.debug("ImageIO: next reader: " + readers.next().getClass());
} */
reader.setInput(istream);
- imgFile = f.getFile();
return reader;
}
/* Load an image file into the Object. */
- public void loadSubimage(ImageFile f, Rectangle region, int prescale)
+ public void loadSubimage(ImageInput ii, Rectangle region, int prescale)
throws FileOpException {
logger.debug("loadSubimage");
try {
- if ((reader == null) || (imgFile != f.getFile())) {
- getReader(f);
- }
+ reader = getReader(ii);
// set up reader parameters
ImageReadParam readParam = reader.getDefaultReadParam();
readParam.setSourceRegion(region);
@@ -216,7 +237,6 @@
// read image
logger.debug("loading..");
img = reader.read(0, readParam);
- mimeType = f.getMimetype();
logger.debug("loaded");
} catch (IOException e) {
throw new FileOpException("Unable to load File!");
@@ -285,12 +305,8 @@
} catch (IOException e) {
logger.error("Error writing image:", e);
throw new ServletException("Error writing image:", e);
- } finally {
- // clean up
- if (writer != null) {
- writer.dispose();
- }
}
+ // TODO: should we: finally { writer.dispose(); }
}
public void scale(double scale, double scaleY) throws ImageOpException {
@@ -325,19 +341,23 @@
}
public void blur(int radius) throws ImageOpException {
- // DEBUG
logger.debug("blur: " + radius);
// minimum radius is 2
int klen = Math.max(radius, 2);
- // FIXME: use constant kernels for most common sizes
- int ksize = klen * klen;
- // kernel is constant 1/k
- float f = 1f / ksize;
- float[] kern = new float[ksize];
- for (int i = 0; i < ksize; i++) {
- kern[i] = f;
+ Kernel blur = null;
+ if (klen < convolutionKernels.length) {
+ blur = convolutionKernels[klen];
+ } else {
+ // calculate our own kernel
+ int ksize = klen * klen;
+ // kernel is constant 1/k
+ float f = 1f / ksize;
+ float[] kern = new float[ksize];
+ for (int i = 0; i < ksize; ++i) {
+ kern[i] = f;
+ }
+ blur = new Kernel(klen, klen, kern);
}
- Kernel blur = new Kernel(klen, klen, kern);
// blur with convolve operation
ConvolveOp blurOp = new ConvolveOp(blur, ConvolveOp.EDGE_NO_OP,
renderHint);
@@ -403,7 +423,7 @@
/**
* Ensures that the array f is in the right order to map the images RGB
- * components. (not shure what happens
+ * components. (not sure what happens otherwise)
*/
public float[] rgbOrdered(float[] fa) {
/*
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/ImageSize.java
--- a/servlet/src/digilib/image/ImageSize.java Mon Feb 21 01:20:22 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-/*
- * ImageSize.java -- digilib image size 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).
- *
- * A width or height of 0 is treated as a 'wildcard' that matches any size.
- *
- * @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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height <= is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width <= is.width);
- }
- 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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height <= is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width <= is.width);
- }
- 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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height >= is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width >= is.width);
- }
- 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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height >= is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width >= is.width);
- }
- 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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height == is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width == is.width);
- }
- 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) {
- if ((this.width == 0)||(is.width == 0)) {
- // width wildcard
- return (this.height == is.height);
- }
- if ((this.height == 0)||(is.height == 0)) {
- // height wildcard
- return (this.width == is.width);
- }
- 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;
- }
-
- /**
- * Returns the aspect ratio.
- *
- * Aspect ratio is (width/height). So it's <1 for portrait and >1 for
- * landscape.
- *
- * @return
- */
- public float getAspect() {
- return (height > 0) ? ((float) width / (float) height) : 0;
- }
-
- /**
- * Returns a scaled copy of this image size.
- *
- * @param scale
- * @return
- */
- public ImageSize getScaled(float scale) {
- return new ImageSize((int) (width * scale), (int) (height * scale));
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- String s = "[" + width + "x" + height + "]";
- return s;
- }
-}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/ImageWorker.java
--- a/servlet/src/digilib/image/ImageWorker.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/ImageWorker.java Mon Feb 21 10:15:09 2011 +0100
@@ -69,19 +69,14 @@
logger.debug("Using subsampling: " + subsamp + " rest "
+ scaleXY);
}
-
- docuImage.loadSubimage(jobinfo.getFileToLoad(), loadRect, (int) subsamp);
-
+ docuImage.loadSubimage(jobinfo.getInput(), loadRect, (int) subsamp);
logger.debug("SUBSAMP: " + subsamp + " -> " + docuImage.getSize());
-
docuImage.scale(scaleXY, scaleXY);
-
} else {
// else load and crop the whole file
- docuImage.loadImage(jobinfo.getFileToLoad());
+ docuImage.loadImage(jobinfo.getInput());
docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(),
(int) loadRect.getWidth(), (int) loadRect.getHeight());
-
docuImage.scale(scaleXY, scaleXY);
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/JAIDocuImage.java
--- a/servlet/src/digilib/image/JAIDocuImage.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/JAIDocuImage.java Mon Feb 21 10:15:09 2011 +0100
@@ -24,7 +24,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;
import java.util.ArrayList;
@@ -46,8 +45,8 @@
import digilib.io.FileOpException;
import digilib.io.FileOps;
-import digilib.io.ImageFile;
-import digilib.io.ImageFileset;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** A DocuImage implementation using Java Advanced Imaging Library. */
/**
@@ -104,53 +103,64 @@
}
/* Check image size and type and store in ImageFile f */
- public ImageFile identify(ImageFile imageFile) throws IOException {
+ public ImageInput identify(ImageInput input) throws IOException {
+ this.input = input;
// try parent method first
- ImageFile imf = super.identify(imageFile);
+ ImageInput imf = super.identify(input);
if (imf != null) {
return imf;
}
- // fileset to store the information
- ImageFileset imgfs = imageFile.getParent();
- File f = imageFile.getFile();
- if (f == null) {
- throw new IOException("File not found!");
- }
/*
* try JAI
*/
- logger.debug("identifying (JAI) " + f);
+ logger.debug("identifying (JAI) " + input);
try {
- RenderedOp img = JAI.create("fileload", f.getAbsolutePath());
+ RenderedOp img = null;
+ if (input.hasFile()) {
+ String t = FileOps.mimeForFile(input.getFile());
+ input.setMimetype(t);
+ img = JAI.create("fileload", input.getFile().getAbsolutePath());
+ } else if (input.hasInputStream()) {
+ img = JAI.create("stream", input.getInputStream());
+ // FIXME: where do we get the mimetype?
+ } else {
+ throw new FileOpException("unable to get data for image!");
+ }
ImageSize d = new ImageSize(img.getWidth(), img.getHeight());
- imageFile.setSize(d);
- String t = FileOps.mimeForFile(f);
- imageFile.setMimetype(t);
- // logger.debug(" format:"+t);
- if (imgfs != null) {
- imgfs.setAspect(d);
- }
- logger.debug("image size: " + imageFile.getSize());
- return imageFile;
+ input.setSize(d);
+ logger.debug("image size: " + d);
+ return input;
} catch (Exception e) {
- throw new FileOpException("ERROR: unknown image file format!");
+ throw new FileOpException("ERROR: unable to identify image!");
}
}
/* Load an image file into the Object. */
- public void loadImage(ImageFile f) throws FileOpException {
- img = JAI.create("fileload", f.getFile().getAbsolutePath());
+ public void loadImage(ImageInput ii) throws FileOpException {
+ this.input = ii;
+ if (ii.hasFile()) {
+ img = JAI.create("fileload", ii.getFile().getAbsolutePath());
+ } else if (ii.hasInputStream()) {
+ img = JAI.create("stream", ii.getInputStream());
+ } else {
+ throw new FileOpException("unable to get data for image!");
+ }
if (img == null) {
throw new FileOpException("Unable to load File!");
}
- mimeType = f.getMimetype();
}
/* Load an image file into the Object. */
- public void loadSubimage(ImageFile f, Rectangle region, int subsample)
- throws FileOpException {
+ public void loadSubimage(ImageInput ii, Rectangle region, int subsample) throws FileOpException {
logger.debug("loadSubimage");
- img = JAI.create("fileload", f.getFile().getAbsolutePath());
+ this.input = ii;
+ if (ii.hasFile()) {
+ img = JAI.create("fileload", ii.getFile().getAbsolutePath());
+ } else if (ii.hasInputStream()) {
+ img = JAI.create("stream", ii.getInputStream());
+ } else {
+ throw new FileOpException("unable to get data for image!");
+ }
if ((region.width < img.getWidth())
|| (region.height < img.getHeight())) {
// setup Crop
@@ -174,7 +184,6 @@
// scale
logger.debug("loadSubimage: scale");
img = JAI.create("scale", sp);
- mimeType = f.getMimetype();
}
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/image/JAIImageLoaderDocuImage.java
--- a/servlet/src/digilib/image/JAIImageLoaderDocuImage.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/image/JAIImageLoaderDocuImage.java Mon Feb 21 10:15:09 2011 +0100
@@ -38,7 +38,8 @@
import javax.servlet.ServletException;
import digilib.io.FileOpException;
-import digilib.io.ImageFile;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
/** DocuImage implementation using the Java Advanced Imaging API and the ImageLoader
* API of Java 1.4.
@@ -80,44 +81,73 @@
/* Load an image file into the Object. */
- public void loadImage(ImageFile f) throws FileOpException {
- logger.debug("loadImage: "+f.getFile());
- //System.gc();
- img = JAI.create("ImageRead", f.getFile().getAbsolutePath());
+ public void loadImage(ImageInput ii) throws FileOpException {
+ logger.debug("loadImage: "+ii);
+ if (ii.hasImageInputStream()) {
+ img = JAI.create("ImageRead", ii.getImageInputStream());
+ } else if (ii.hasFile()) {
+ img = JAI.create("ImageRead", ii.getFile().getAbsolutePath());
+ }
if (img == null) {
throw new FileOpException("Unable to load File!");
}
- mimeType = f.getMimetype();
}
/* Get an ImageReader for the image file. */
- public ImageReader getReader(ImageFile f) throws IOException {
- logger.debug("preloadImage: "+f.getFile());
- //System.gc();
- RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
- ImageInputStream istream = new FileImageInputStream(rf);
- //Iterator readers = ImageIO.getImageReaders(istream);
- Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype());
- if (! readers.hasNext()) {
- throw new FileOpException("Unable to load File!");
- }
- reader = readers.next();
- logger.debug("JAIImageIO: this reader: " + reader.getClass());
- while (readers.hasNext()) {
- logger.debug(" next reader: " + readers.next().getClass());
- }
- reader.setInput(istream);
- return reader;
+ public ImageReader getReader(ImageInput input) throws IOException {
+ logger.debug("get ImageReader for " + input);
+ if (this.reader != null) {
+ if (this.input == input) {
+ // it was the same input
+ logger.debug("reusing Reader");
+ return reader;
+ }
+ // clean up old reader
+ logger.debug("cleaning Reader!");
+ dispose();
+ }
+ this.input = input;
+ ImageInputStream istream = null;
+ if (input.hasImageInputStream()) {
+ // stream input
+ istream = input.getImageInputStream();
+ } else if (input.hasFile()) {
+ // file only input
+ RandomAccessFile rf = new RandomAccessFile(input.getFile(), "r");
+ istream = new FileImageInputStream(rf);
+ } else {
+ throw new FileOpException("Unable to get data from ImageInput");
+ }
+ Iterator readers;
+ String mt = input.getMimetype();
+ if (mt == null) {
+ logger.debug("No mime-type. Trying automagic.");
+ readers = ImageIO.getImageReaders(istream);
+ } else {
+ logger.debug("File type:" + mt);
+ readers = ImageIO.getImageReadersByMIMEType(mt);
+ }
+ if (!readers.hasNext()) {
+ throw new FileOpException("Can't find Reader to load File!");
+ }
+ reader = readers.next();
+ logger.debug("ImageIO: this reader: " + reader.getClass());
+ /* are there more readers? */
+ /* while (readers.hasNext()) {
+ logger.debug("ImageIO: next reader: " + readers.next().getClass());
+ } */
+ reader.setInput(istream);
+ return reader;
}
/* Load an image file into the Object. */
- public void loadSubimage(ImageFile f, Rectangle region, int prescale)
+ public void loadSubimage(ImageInput ii, Rectangle region, int prescale)
throws FileOpException {
- logger.debug("loadSubimage: "+f.getFile());
+ logger.debug("loadSubimage: "+ii.getFile());
//System.gc();
try {
- if ((reader == null) || (imgFile != f.getFile())) {
- getReader(f);
+ if ((reader == null) || (imgFile != ii.getFile())) {
+ getReader(ii);
}
ImageReadParam readParam = reader.getDefaultReadParam();
readParam.setSourceRegion(region);
@@ -137,8 +167,7 @@
if (img == null) {
throw new FileOpException("Unable to load File!");
}
- imgFile = f.getFile();
- mimeType = f.getMimetype();
+ imgFile = ii.getFile();
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/io/AliasingDocuDirCache.java
--- a/servlet/src/digilib/io/AliasingDocuDirCache.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/io/AliasingDocuDirCache.java Mon Feb 21 10:15:09 2011 +0100
@@ -28,6 +28,7 @@
import digilib.io.FileOps.FileClass;
import digilib.servlet.DigilibConfiguration;
+import digilib.util.XMLListLoader;
/**
* @author casties
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/io/DigilibInfoReader.java
--- a/servlet/src/digilib/io/DigilibInfoReader.java Mon Feb 21 01:20:22 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-package digilib.io;
-
-/** DigilibInfoReader
- * A class for reading the information from info.xml files used in digilib image directories.
- *
- */
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-
-
-
-public class DigilibInfoReader {
-
- /** gengeral logger for this class */
- protected static Logger logger = Logger.getLogger("digilib.servlet");
-
- private String filename = null;
- //private static String base_element = "info";
-
- public DigilibInfoReader(String fn){
- filename = fn;
- }
-
- /**
- * Returns the attribute defined by 'attr' as a String.
- *
- * @param attr
- * @return
- */
- @SuppressWarnings("unchecked") // Element.getChildren() returns naked List
- public String getAsString(String attr){
- try{
- SAXBuilder builder = new SAXBuilder();
- Document doc = builder.build(new File(filename));
- Element root = doc.getRootElement();
- List mainElements = root.getChildren();
- // logger.debug("XML mainElements:"+mainElements.toString());
-
- for(int i=0; i map = null;
+ ConcurrentMap map = new ConcurrentHashMap();
/** names of base directories */
String[] baseDirNames = null;
@@ -71,7 +71,6 @@
public DocuDirCache(String[] bd, FileClass[] fcs,
DigilibConfiguration dlConfig) {
baseDirNames = bd;
- map = new HashMap();
this.fileClasses = fcs;
}
@@ -83,7 +82,6 @@
*/
public DocuDirCache(String[] bd) {
baseDirNames = bd;
- map = new HashMap();
// default file class is CLASS_IMAGE
fileClasses = new FileClass[] { FileClass.IMAGE };
}
@@ -99,38 +97,49 @@
/**
* Add a DocuDirectory to the cache.
+ * Always returns the correct Object from the cache,
+ * either newdir one or another one.
*
* @param newdir
+ * @return dir
*/
- public void put(DocuDirectory newdir) {
+ public DocuDirectory put(DocuDirectory newdir) {
String s = newdir.getDirName();
logger.debug("DocuDirCache.put for "+s+" in "+this);
- if (map.containsKey(s)) {
+ DocuDirectory olddir = map.putIfAbsent(s, newdir);
+ if (olddir != null) {
logger.warn("Duplicate key in DocuDirCache.put -- ignoring!");
- } else {
- map.put(s, newdir);
- numFiles += newdir.size();
+ return olddir;
}
+ numFiles += newdir.size();
+ return newdir;
}
/**
* Add a directory to the cache and check its parents.
- *
+ * Always returns the correct Object from the cache,
+ * either newDir one or another one.
+ *
* @param newDir
+ * @return dir
*/
- public void putDir(DocuDirectory newDir) {
- put(newDir);
- String parent = FileOps.parent(newDir.getDirName());
- if (parent != "") {
- // check the parent in the cache
- DocuDirectory pd = map.get(parent);
- if (pd == null) {
- // the parent is unknown
- pd = new DocuDirectory(parent, this);
- putDir(pd);
+ public DocuDirectory putDir(DocuDirectory newDir) {
+ DocuDirectory dd = put(newDir);
+ if (dd.getParent() == null) {
+ // no parent link yet
+ String parent = FileOps.parent(newDir.getDirName());
+ if (parent != "") {
+ // check the parent in the cache
+ DocuDirectory pd = map.get(parent);
+ if (pd == null) {
+ // the parent is unknown
+ pd = new DocuDirectory(parent, this);
+ pd = putDir(pd);
+ }
+ newDir.setParent(pd);
}
- newDir.setParent(pd);
}
+ return dd;
}
/**
@@ -182,8 +191,6 @@
int n = in - 1;
// first, assume fn is a directory and look in the cache
dd = map.get(fn);
- // logger.debug("fn: " + fn);
- // logger.debug("dd: " + dd);
if (dd == null) {
// cache miss
misses++;
@@ -196,7 +203,7 @@
dd = new DocuDirectory(fn, this);
if (dd.isValid()) {
// add to the cache
- putDir(dd);
+ dd = putDir(dd);
}
} else {
/*
@@ -214,7 +221,7 @@
if (dd.isValid()) {
// add to the cache
// logger.debug(dd + " is valid");
- putDir(dd);
+ dd = putDir(dd);
} else {
// invalid path
return null;
@@ -225,17 +232,14 @@
}
// get the file's index
n = dd.indexOf(f.getName(), fc);
- // logger.debug(f.getName() + ", index is " + n + ", fc = " + fc);
}
} else {
// cache hit
hits++;
}
dd.refresh();
- // logger.debug(dd + " refreshed");
if (dd.isValid()) {
try {
- // logger.debug(dd + " is valid");
return dd.get(n, fc);
} catch (IndexOutOfBoundsException e) {
// logger.debug(fn + " not found in directory");
@@ -266,7 +270,7 @@
dd = new DocuDirectory(fn, this);
if (dd.isValid()) {
// add to the cache
- putDir(dd);
+ dd = putDir(dd);
}
} else {
// maybe it's a file
@@ -278,7 +282,7 @@
dd = new DocuDirectory(f.getParent(), this);
if (dd.isValid()) {
// add to the cache
- putDir(dd);
+ dd = putDir(dd);
} else {
// invalid path
return null;
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/io/DocuDirectory.java
--- a/servlet/src/digilib/io/DocuDirectory.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/io/DocuDirectory.java Mon Feb 21 10:15:09 2011 +0100
@@ -31,6 +31,8 @@
import org.xml.sax.SAXException;
import digilib.io.FileOps.FileClass;
+import digilib.meta.MetadataMap;
+import digilib.meta.XMLMetaLoader;
/**
* @author casties
@@ -40,9 +42,6 @@
/** list of files (DocuDirent) */
private List> list = null;
- /** default FileClass for unspecified calls */
- public static FileClass defaultFileClass = FileClass.IMAGE;
-
/** directory object is valid (exists on disk) */
private boolean isValid = false;
@@ -52,6 +51,9 @@
/** directory name (digilib canonical form) */
private String dirName = null;
+ /** array of parallel dirs for scaled images */
+ private Directory[] dirs = null;
+
/** directory metadata */
private MetadataMap dirMeta = null;
@@ -83,15 +85,6 @@
public DocuDirectory(String path, DocuDirCache cache) {
this.dirName = path;
this.cache = cache;
- initDir();
- checkDir();
- }
-
- /**
- * Sets and checks the dir object.
- *
- */
- protected void initDir() {
String baseDirName = cache.getBaseDirNames()[0];
// clear directory list
FileClass[] fcs = FileClass.values();
@@ -100,10 +93,10 @@
for (@SuppressWarnings("unused") FileClass fc: fcs) {
list.add(null);
}
- isValid = false;
dirMTime = 0;
// the first directory has to exist
- dir = new File(baseDirName, dirName);
+ dir = new File(baseDirName, path);
+ isValid = dir.isDirectory();
}
/**
@@ -111,7 +104,7 @@
*
*/
public int size() {
- return size(defaultFileClass);
+ return ((list != null) && (list.get(0) != null)) ? list.get(0).size() : 0;
}
/**
@@ -121,13 +114,7 @@
* fileClass
*/
public int size(FileClass fc) {
- if (list != null) {
- List l = list.get(fc.ordinal());
- if (l != null) {
- return l.size();
- }
- }
- return 0;
+ return ((list != null) && (list.get(fc.ordinal()) != null)) ? list.get(fc.ordinal()).size() : 0;
}
/**
@@ -136,8 +123,11 @@
* @param index
* @return
*/
- public ImageFileset get(int index) {
- return (ImageFileset) get(index, defaultFileClass);
+ public DocuDirent get(int index) {
+ if ((list == null) || (list.get(0) == null) || (index >= list.get(0).size())) {
+ return null;
+ }
+ return list.get(0).get(index);
}
/**
@@ -156,102 +146,84 @@
}
/**
- * Checks if the directory exists on the filesystem.
- *
- * Sets isValid.
- *
- * @return
- */
- public boolean checkDir() {
- if (dir == null) {
- initDir();
- }
- isValid = dir.isDirectory();
- return isValid;
- }
-
- /**
* Read the filesystem directory and fill this object.
*
* Clears the List and (re)reads all files.
*
* @return boolean the directory exists
*/
- public boolean readDir() {
+ public synchronized boolean readDir() {
// check directory first
- checkDir();
if (!isValid) {
return false;
}
- // first file extension to try for scaled directories
- String scalext = null;
+ // re-check modification time because the thread may have slept
+ if (dir.lastModified() <= dirMTime) {
+ return true;
+ }
// read all filenames
- logger.debug("reading directory " + dir.getPath());
+ logger.debug("reading directory "+this+" = "+dir.getPath());
+ File[] allFiles = null;
/*
* using ReadableFileFilter is safer (we won't get directories with file
* extensions) but slower.
*/
- File[] allFiles = null;
- // allFiles = dir.listFiles(new FileOps.ReadableFileFilter());
+ // allFiles = dir.listFiles(new FileOps.ReadableFileFilter());
allFiles = dir.listFiles();
- //logger.debug(" done");
if (allFiles == null) {
// not a directory
return false;
}
- // list of base dirs from the parent cache
- String[] baseDirNames = cache.getBaseDirNames();
- // number of base dirs
- int nb = baseDirNames.length;
- // array of base dirs
- Directory[] dirs = new Directory[nb];
- // first entry is this directory
- dirs[0] = this;
- // fill array with the remaining directories
- for (int j = 1; j < nb; j++) {
- File d = new File(baseDirNames[j], dirName);
- if (d.isDirectory()) {
- dirs[j] = new Directory(d);
- logger.debug(" reading scaled directory " + d.getPath());
- dirs[j].readDir();
- //logger.debug(" done");
+ // init parallel directories
+ if (dirs == null) {
+ // list of base dirs from the parent cache
+ String[] baseDirNames = cache.getBaseDirNames();
+ // number of base dirs
+ int nb = baseDirNames.length;
+ // array of parallel dirs
+ dirs = new Directory[nb];
+ // first entry is this directory
+ dirs[0] = this;
+ // fill array with the remaining directories
+ for (int j = 1; j < nb; j++) {
+ // add dirName to baseDirName
+ File d = new File(baseDirNames[j], dirName);
+ if (d.isDirectory()) {
+ dirs[j] = new Directory(d);
+ logger.debug(" reading scaled directory " + d.getPath());
+ dirs[j].readDir();
+ }
}
}
// go through all file classes
- //for (int classIdx = 0; classIdx < FileOps.NUM_CLASSES; classIdx++) {
- for (FileClass fileClass: cache.getFileClasses()) {
- //fileClass = cache.getFileClasses()[classIdx];
- File[] fileList = FileOps.listFiles(allFiles, FileOps
- .filterForClass(fileClass));
- //logger.debug(" done");
+ for (FileClass fileClass : cache.getFileClasses()) {
+ File[] fileList = FileOps.listFiles(allFiles,
+ FileOps.filterForClass(fileClass));
// number of files in the directory
int numFiles = fileList.length;
if (numFiles > 0) {
// create new list
- list.set(fileClass.ordinal(), new ArrayList(numFiles));
- // sort the file names alphabetically and iterate the list
- // Arrays.sort(fileList); // not needed
- Map hints = FileOps.newHints(FileOps.HINT_BASEDIRS, dirs);
- hints.put(FileOps.HINT_FILEEXT, scalext);
- for (int i = 0; i < numFiles; i++) {
- DocuDirent f = FileOps.fileForClass(fileClass, fileList[i],
- hints);
+ ArrayList dl = new ArrayList(numFiles);
+ list.set(fileClass.ordinal(), dl);
+ for (File f : fileList) {
+ DocuDirent df = FileOps.fileForClass(fileClass, f, dirs);
+ df.setParent(this);
// add the file to our list
- // logger.debug(f.getName());
-
- list.get(fileClass.ordinal()).add(f);
- f.setParent(this);
+ dl.add(df);
}
- // we sort the inner ArrayList (the list of files not the list of file types)
- // for binarySearch to work (DocuDirent's natural sort order is by filename)
- Collections.sort(list.get(fileClass.ordinal()));
+ /*
+ * we sort the inner ArrayList (the list of files not the list
+ * of file types) for binarySearch to work (DocuDirent's natural
+ * sort order is by filename)
+ */
+ Collections.sort(dl);
}
}
// clear the scaled directories
- for (int j = 1; j < nb; j++) {
- if (dirs[j] != null) {
- dirs[j].clearFilenames();
+ for (Directory d: dirs) {
+ if (d != null) {
+ d.clearFilenames();
}
}
// update number of cached files if this was the first time
@@ -456,9 +428,8 @@
return -1;
}
- private boolean isBasenameInList(List fl, int idx, String fn) {
- String dfn = FileOps.basename((fl.get(idx))
- .getName());
+ private boolean isBasenameInList(List fileList, int idx, String fn) {
+ String dfn = FileOps.basename((fileList.get(idx)).getName());
return (dfn.equals(fn)||dfn.equals(FileOps.basename(fn)));
}
@@ -474,7 +445,12 @@
* @return DocuDirent
*/
public DocuDirent find(String fn) {
- return find(fn, defaultFileClass);
+ FileClass fc = FileOps.classForFilename(fn);
+ int i = indexOf(fn, fc);
+ if (i >= 0) {
+ return list.get(0).get(i);
+ }
+ return null;
}
/**
@@ -491,7 +467,7 @@
public DocuDirent find(String fn, FileClass fc) {
int i = indexOf(fn, fc);
if (i >= 0) {
- return (DocuDirent) list.get(fc.ordinal()).get(i);
+ return list.get(fc.ordinal()).get(i);
}
return null;
}
diff -r 60e8cca7ac81 -r e6d0cdaa7923 servlet/src/digilib/io/DocuDirent.java
--- a/servlet/src/digilib/io/DocuDirent.java Mon Feb 21 01:20:22 2011 +0100
+++ b/servlet/src/digilib/io/DocuDirent.java Mon Feb 21 10:15:09 2011 +0100
@@ -1,169 +1,81 @@
-/*
- * DocuDirent.java -- Abstract directory entry in a DocuDirectory
- *
- * 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 15.09.2003 by casties
- *
- */
package digilib.io;
import java.io.File;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import digilib.io.FileOps.FileClass;
-/**
- * Abstract directory entry in a DocuDirectory.
- *
- * @author casties
- *
- */
-public abstract class DocuDirent implements Comparable