changeset 960:b2d97b842612

moved DocuImage implementations with non-standard toolkits (JAI, ImgeJ) into separate Maven modules. default build uses jai-imageio (now only one additional JAR in webapp!).
author robcast
date Wed, 25 Jan 2012 15:13:06 +0100
parents f197e7760154
children 6d5f0c39a37f
files .hgignore common-imagej/pom.xml common-imagej/src/main/java/digilib/image/ImageJ1DocuImage.java common-jai/pom.xml common-jai/src/main/java/digilib/image/JAIDocuImage.java common-jai/src/main/java/digilib/image/JAIImageLoaderDocuImage.java common/pom.xml pdf/pom.xml pom.xml servlet2/src/main/java/digilib/servlet/DigilibServletConfiguration.java servlet2/src/main/java/digilib/servlet/Scaler.java servlet3/pom.xml servlet3/src/main/java/digilib/servlet/DigilibServletConfiguration.java servlet3/src/main/java/digilib/servlet/Initialiser.java servlet3/src/main/java/digilib/servlet/Scaler.java webapp/pom.xml webapp/src/main/webapp/WEB-INF/digilib-config.xml
diffstat 17 files changed, 1046 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Jan 24 21:12:13 2012 +0100
+++ b/.hgignore	Wed Jan 25 15:13:06 2012 +0100
@@ -65,4 +65,20 @@
 syntax: regexp
 ^webapp/digilib-log\.txt$
 syntax: regexp
-^webapp/dl-access-log\.txt$
\ No newline at end of file
+^webapp/dl-access-log\.txt$
+syntax: regexp
+^common-jai/target$
+syntax: regexp
+^common-imagej/target$
+syntax: regexp
+^common-imagej/\.classpath$
+syntax: regexp
+^common-imagej/\.project$
+syntax: regexp
+^common-imagej/\.settings$
+syntax: regexp
+^common-jai/\.settings$
+syntax: regexp
+^common-jai/\.classpath$
+syntax: regexp
+^common-jai/\.project$
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-imagej/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -0,0 +1,49 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>digilib</artifactId>
+    <groupId>digilib</groupId>
+    <version>2.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>digilib-common-imagej</artifactId>
+  <name>digilib-common-imagej</name>
+  <description>digilib codec implementation using ImageJ toolkit</description>
+  <repositories>
+  	<!-- ImageJ-1 -->
+  	<repository>
+	    <id>imagej.thirdparty</id>
+	    <url>http://dev.imagejdev.org/maven2/thirdparty</url>
+  	</repository>
+    <!--  ImageJ-2 
+    <repository>
+      <id>imagej.releases</id>
+      <url>http://code.imagej.net/maven2/releases</url>
+    </repository>
+    <repository>
+      <id>imagej.snapshots</id>
+      <url>http://code.imagej.net/maven2/snapshots</url>
+    </repository> -->
+  </repositories>
+
+  <dependencies>
+    <!--  imageJ 1 -->
+	<dependency>
+   		<groupId>net.imagej</groupId>
+  		<artifactId>ij</artifactId>
+   		<version>1.45s</version>
+  		<type>jar</type>
+  		<scope>compile</scope>
+	</dependency>
+	<!--  imageJ2
+	<dependency>
+		<groupId>net.imglib2</groupId>
+		<artifactId>imglib2-io</artifactId>
+		<version>2.0-SNAPSHOT</version>
+	</dependency> -->
+	<dependency>
+		<groupId>digilib</groupId>
+		<artifactId>digilib-common</artifactId>
+	</dependency>
+  </dependencies>
+</project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-imagej/src/main/java/digilib/image/ImageJ1DocuImage.java	Wed Jan 25 15:13:06 2012 +0100
@@ -0,0 +1,148 @@
+/**
+ * 
+ */
+package digilib.image;
+
+import ij.IJ;
+import ij.ImagePlus;
+import ij.plugin.JpegWriter;
+import ij.plugin.PNG_Writer;
+import ij.process.ImageProcessor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import digilib.io.FileOpException;
+import digilib.io.FileOps;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
+
+/** Implementation of DocuImage using ImageJ version 1.
+ *  
+ * @author casties
+ *
+ */
+public class ImageJ1DocuImage extends ImageInfoDocuImage {
+
+	protected ImagePlus img;
+	protected ImageProcessor proc;
+
+	/* returns a list of supported image formats */
+	public Iterator<String> getSupportedFormats() {
+		String[] formats = new String[] {"JPG","PNG","TIFF"};
+		return Arrays.asList(formats).iterator();
+	}
+
+    /* Check image size and type and store in ImageInput */
+    public ImageInput identify(ImageInput input) throws IOException {
+        // try parent method first
+        ImageInput ii = super.identify(input);
+        if (ii != null) {
+        	return ii;
+        }
+        logger.debug("identifying (ImageJ1) " + input);
+        String path = input.getFile().getAbsolutePath();
+        img = IJ.openImage(path);
+        // set size
+        ImageSize d = new ImageSize(img.getWidth(), img.getHeight());
+        input.setSize(d);
+        // set mime type
+        if (input.getMimetype() == null) {
+        	String t = FileOps.mimeForFile(input.getFile());
+        	input.setMimetype(t);
+        }
+        return input;
+    }
+
+    /* (non-Javadoc)
+	 * @see digilib.image.DocuImageImpl#loadImage(digilib.io.ImageInput)
+	 */
+	@Override
+	public void loadImage(ImageInput ii) throws FileOpException {
+		this.input = ii;
+		String path = ii.getFile().getAbsolutePath();
+		img = IJ.openImage(path);
+		proc = img.getProcessor();
+	}
+
+	/* (non-Javadoc)
+	 * @see digilib.image.DocuImageImpl#crop(int, int, int, int)
+	 */
+	@Override
+	public void crop(int xoff, int yoff, int width, int height)
+			throws ImageOpException {
+		proc.setRoi(xoff, yoff, width, height);
+		ImageProcessor croppedProc = proc.crop();
+		proc = croppedProc;
+	}
+
+	/* (non-Javadoc)
+	 * @see digilib.image.DocuImageImpl#scale(double, double)
+	 */
+	@Override
+	public void scale(double scaleX, double scaleY) throws ImageOpException {
+		int newWidth = (int) Math.round(proc.getWidth() * scaleX); 
+		int newHeight = (int) Math.round(proc.getHeight() * scaleY);
+		ImageProcessor scaledProc = proc.resize(newWidth, newHeight, false);
+		proc = scaledProc;
+	}
+
+	/* (non-Javadoc)
+	 * @see digilib.image.DocuImageImpl#writeImage(java.lang.String, java.io.OutputStream)
+	 */
+	@Override
+	public void writeImage(String mt, OutputStream ostream)
+			throws ImageOpException, FileOpException {
+		File outFile;
+		String filext = ".jpg"; 
+		if (mt.equals("image/png")) {
+			filext = ".png";
+		}
+		try {
+			outFile = File.createTempFile("imgj_temp", filext);
+		} catch (IOException e) {
+			throw new FileOpException(e.toString());
+		}
+		// save image to file
+		logger.debug("writeImage: mt="+mt);
+		if (mt.equals("image/png")) {
+			PNG_Writer writer = new PNG_Writer();
+			try {
+				img = new ImagePlus("Image", proc);
+				writer.writeImage(img, outFile.getAbsolutePath(), 0);
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		} else {
+			img = new ImagePlus("Image", proc);
+			JpegWriter.save(img, outFile.getAbsolutePath(), 70);
+		}
+		// now send file
+        FileInputStream inFile = null;
+		try {
+            inFile = new FileInputStream(outFile);
+            byte dataBuffer[] = new byte[4096];
+            int len;
+            while ((len = inFile.read(dataBuffer)) != -1) {
+                // copy out file
+                ostream.write(dataBuffer, 0, len);
+            }
+        } catch (IOException e) {
+			throw new FileOpException(e.toString());
+		} finally {
+            try {
+                if (inFile != null) {
+                    inFile.close();
+                }
+            } catch (IOException e) {
+                // nothing to do
+            }
+        }
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-jai/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -0,0 +1,40 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>digilib</artifactId>
+    <groupId>digilib</groupId>
+    <version>2.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>digilib-common-jai</artifactId>
+  <name>digilib-common-jai</name>
+  <description>digilib codec implementation using JAI toolkit</description>
+  <repositories>
+  	<!-- This provides the required versions of JAI-ImageIO -->
+    <repository>
+        <id>geotools.osgeo.org</id>
+        <name>Geotools repository</name>
+        <url>http://download.osgeo.org/webdav/geotools/</url>
+    </repository>
+  </repositories>
+  <dependencies>
+    <dependency>
+      <groupId>javax.media</groupId>
+      <artifactId>jai_codec</artifactId>
+      <version>1.1.3</version>
+      <type>jar</type>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.media</groupId>
+      <artifactId>jai_core</artifactId>
+      <version>1.1.3</version>
+      <type>jar</type>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+    	<groupId>digilib</groupId>
+    	<artifactId>digilib-common</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-jai/src/main/java/digilib/image/JAIDocuImage.java	Wed Jan 25 15:13:06 2012 +0100
@@ -0,0 +1,481 @@
+/* JAIDocuImage -- Image class implementation using JAI (Java Advanced Imaging)
+
+ Digital Image Library servlet components
+
+ Copyright (C) 2001, 2002, 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.image;
+
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.media.jai.BorderExtender;
+import javax.media.jai.Interpolation;
+import javax.media.jai.JAI;
+import javax.media.jai.KernelJAI;
+import javax.media.jai.ParameterBlockJAI;
+import javax.media.jai.RenderedOp;
+import javax.media.jai.operator.TransposeDescriptor;
+import javax.media.jai.operator.TransposeType;
+
+import com.sun.media.jai.codec.ImageCodec;
+
+import digilib.io.FileOpException;
+import digilib.io.FileOps;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
+
+/** A DocuImage implementation using Java Advanced Imaging Library. */
+/**
+ * @author casties
+ *
+ */
+public class JAIDocuImage extends ImageInfoDocuImage {
+
+	protected RenderedImage img;
+
+	protected Interpolation interpol = null;
+
+	/*
+	 * static { // we could set our own tile cache size here TileCache tc =
+	 * JAI.createTileCache(100*1024*1024);
+	 * JAI.getDefaultInstance().setTileCache(tc); }
+	 */
+
+	public boolean isSubimageSupported() {
+		return true;
+	}
+
+	/*
+	 * Real setQuality implementation. Creates the correct Interpolation.
+	 */
+	public void setQuality(int qual) {
+		quality = qual;
+		// setup interpolation quality
+		if (qual > 1) {
+			logger.debug("quality q2");
+			interpol = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
+		} else if (qual == 1) {
+			logger.debug("quality q1");
+			interpol = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
+		} else {
+			logger.debug("quality q0");
+			interpol = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
+		}
+	}
+
+	/* returns a list of supported image formats */
+    @SuppressWarnings("unchecked") // ImageCodec.getCodecs() returns a naked Enumeration
+    public Iterator<String> getSupportedFormats() {
+        Enumeration<ImageCodec> codecs = ImageCodec.getCodecs();
+        List<String> formats = new ArrayList<String>();
+        for (ImageCodec codec = codecs.nextElement(); codecs.hasMoreElements(); codec = codecs
+                .nextElement()) {
+            logger.debug("known format:"+codec.getFormatName());
+            formats.add(codec.getFormatName());
+        }
+        logger.debug("tilecachesize:"
+                + JAI.getDefaultInstance().getTileCache().getMemoryCapacity());
+        return formats.iterator();
+    }
+
+	/* Check image size and type and store in ImageFile f */
+	public ImageInput identify(ImageInput input) throws IOException {
+        this.input = input;
+        // try parent method first
+	    ImageInput imf = super.identify(input);
+		if (imf != null) {
+			return imf;
+		}
+		/*
+		 * try JAI
+		 */
+		logger.debug("identifying (JAI) " + input);
+		try {
+		    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());
+			input.setSize(d);
+			logger.debug("image size: " + d);
+			return input;
+		} catch (Exception e) {
+			throw new FileOpException("ERROR: unable to identify image!");
+		}
+	}
+
+	/* Load an image file into the Object. */
+	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!");
+		}
+	}
+
+	/* Load an image file into the Object. */
+	public void loadSubimage(ImageInput ii, Rectangle region, int subsample) throws FileOpException {
+		logger.debug("loadSubimage");
+        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
+			ParameterBlock cp = new ParameterBlock();
+			cp.addSource(img);
+			cp.add((float) region.x);
+			cp.add((float) region.y);
+			cp.add((float) region.width);
+			cp.add((float) region.height);
+			logger.debug("loadSubimage: crop");
+			img = JAI.create("crop", cp);
+		}
+		if (subsample > 1) {
+			float sc = 1f / subsample;
+			ParameterBlockJAI sp = new ParameterBlockJAI("scale");
+			sp.addSource(img);
+			sp.setParameter("xScale", sc);
+			sp.setParameter("yScale", sc);
+			sp.setParameter("interpolation", Interpolation
+					.getInstance(Interpolation.INTERP_NEAREST));
+			// scale
+			logger.debug("loadSubimage: scale");
+			img = JAI.create("scale", sp);
+		}
+	}
+
+	/* Write the current image to an OutputStream. */
+	public void writeImage(String mt, OutputStream ostream) throws ImageOpException, FileOpException {
+		try {
+			// setup output
+			ParameterBlock pb3 = new ParameterBlock();
+			pb3.addSource(img);
+			pb3.add(ostream);
+			if (mt == "image/jpeg") {
+				pb3.add("JPEG");
+			} else if (mt == "image/png") {
+				pb3.add("PNG");
+			} else {
+				// unknown mime type
+				throw new ImageOpException("Unknown mime type: " + mt);
+			}
+			// render output
+			JAI.create("encode", pb3);
+
+		} catch (RuntimeException e) {
+		    // JAI likes to throw RuntimeExceptions
+			throw new FileOpException("Error writing image: "+e);
+		}
+	}
+
+    /* returns the current image size
+     * @see digilib.image.DocuImageImpl#getSize()
+     */
+    public ImageSize getSize() {
+        ImageSize is = null;
+        // TODO: do we want to cache imgSize?
+        int h = 0;
+        int w = 0;
+        if (img != null) {
+            // get size from image
+            h = img.getHeight();
+            w = img.getWidth();
+            is = new ImageSize(w, h);
+        }
+        return is;
+    }
+
+	/* scales the current image */
+	public void scale(double scale, double scaleY) throws ImageOpException {
+		logger.debug("scale");
+		if ((scale < 1) && (img.getColorModel().getPixelSize() == 1)
+				&& (quality > 0)) {
+			/*
+			 * "SubsampleBinaryToGray" for downscaling BW
+			 */
+			scaleBinary((float) scale);
+		} else if ((scale <= 0.5) && (quality > 1)) {
+			/*
+			 * blur and "Scale" for downscaling color images
+			 */
+			if ((scale <= 0.5) && (quality > 1)) {
+				int bl = (int) Math.floor(1 / scale);
+				// don't blur more than 3
+				blur(Math.min(bl, 3));
+			}
+			scaleAll((float) scale);
+		} else {
+			/*
+			 * "Scale" for the rest
+			 */
+			scaleAll((float) scale);
+		}
+
+		// DEBUG
+		logger.debug("SCALE: " + scale + " ->" + img.getWidth() + "x"
+				+ img.getHeight());
+
+	}
+
+	public void scaleAll(float scale) throws ImageOpException {
+		RenderedImage scaledImg;
+		// DEBUG
+		logger.debug("scaleAll: " + scale);
+		ParameterBlockJAI param = new ParameterBlockJAI("Scale");
+		param.addSource(img);
+		param.setParameter("xScale", scale);
+		param.setParameter("yScale", scale);
+		param.setParameter("interpolation", interpol);
+		// hint with border extender
+		RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER,
+				BorderExtender.createInstance(BorderExtender.BORDER_COPY));
+		// scale
+		scaledImg = JAI.create("Scale", param, hint);
+
+		if (scaledImg == null) {
+			throw new ImageOpException("Unable to scale");
+		}
+		img = scaledImg;
+	}
+
+	public void blur(int radius) throws ImageOpException {
+		RenderedImage blurredImg;
+		int klen = Math.max(radius, 2);
+		logger.debug("blur: " + klen);
+		int ksize = klen * klen;
+		float f = 1f / ksize;
+		float[] kern = new float[ksize];
+		for (int i = 0; i < ksize; i++) {
+			kern[i] = f;
+		}
+		KernelJAI blur = new KernelJAI(klen, klen, kern);
+		ParameterBlockJAI param = new ParameterBlockJAI("Convolve");
+		param.addSource(img);
+		param.setParameter("kernel", blur);
+		// hint with border extender
+		RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER,
+				BorderExtender.createInstance(BorderExtender.BORDER_COPY));
+		blurredImg = JAI.create("Convolve", param, hint);
+		if (blurredImg == null) {
+			throw new ImageOpException("Unable to scale");
+		}
+		img = blurredImg;
+	}
+
+	public void scaleBinary(float scale) throws ImageOpException {
+		RenderedImage scaledImg;
+		// DEBUG
+		logger.debug("scaleBinary: " + scale);
+		ParameterBlockJAI param = new ParameterBlockJAI("SubsampleBinaryToGray");
+		param.addSource(img);
+		param.setParameter("xScale", scale);
+		param.setParameter("yScale", scale);
+		// hint with border extender
+		RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER,
+				BorderExtender.createInstance(BorderExtender.BORDER_COPY));
+		// scale
+		scaledImg = JAI.create("SubsampleBinaryToGray", param, hint);
+		if (scaledImg == null) {
+			throw new ImageOpException("Unable to scale");
+		}
+		img = scaledImg;
+	}
+
+	/* crops the current image */
+	public void crop(int x_off, int y_off, int width, int height)
+			throws ImageOpException {
+		// setup Crop
+		ParameterBlock param = new ParameterBlock();
+		param.addSource(img);
+		param.add((float) x_off);
+		param.add((float) y_off);
+		param.add((float) width);
+		param.add((float) height);
+		RenderedImage croppedImg = JAI.create("crop", param);
+
+		logger.debug("CROP: " + x_off + "," + y_off + ", " + width + ","
+				+ height + " ->" + croppedImg.getWidth() + "x"
+				+ croppedImg.getHeight());
+		img = croppedImg;
+	}
+
+	/* rotates the current image */
+	public void rotate(double angle) throws ImageOpException {
+		RenderedImage rotImg;
+		// convert degrees to radians
+		double rangle = Math.toRadians(angle);
+		double x = img.getWidth() / 2;
+		double y = img.getHeight() / 2;
+
+		// optimize rotation by right angles
+		TransposeType rotOp = null;
+		if (Math.abs(angle - 0) < epsilon) {
+			// 0 degree
+			return;
+		} else if (Math.abs(angle - 90) < epsilon) {
+			// 90 degree
+			rotOp = TransposeDescriptor.ROTATE_90;
+		} else if (Math.abs(angle - 180) < epsilon) {
+			// 180 degree
+			rotOp = TransposeDescriptor.ROTATE_180;
+		} else if (Math.abs(angle - 270) < epsilon) {
+			// 270 degree
+			rotOp = TransposeDescriptor.ROTATE_270;
+		} else if (Math.abs(angle - 360) < epsilon) {
+			// 360 degree
+			return;
+		}
+		if (rotOp != null) {
+			// use Transpose operation
+			ParameterBlock pb = new ParameterBlock();
+			pb.addSource(img);
+			pb.add(rotOp);
+			rotImg = JAI.create("transpose", pb);
+		} else {
+			// setup "normal" rotation
+			ParameterBlock param = new ParameterBlock();
+			param.addSource(img);
+			param.add((float) x);
+			param.add((float) y);
+			param.add((float) rangle);
+			param.add(interpol);
+
+			rotImg = JAI.create("rotate", param);
+		}
+
+		logger.debug("ROTATE: " + x + "," + y + ", " + angle + " (" + rangle
+				+ ")" + " ->" + rotImg.getWidth() + "x" + rotImg.getHeight());
+		img = rotImg;
+	}
+
+	/*
+	 * mirrors the current image works only horizontal and vertical
+	 */
+	public void mirror(double angle) throws ImageOpException {
+		RenderedImage mirImg;
+		// only mirroring by right angles
+		TransposeType rotOp = null;
+		if (Math.abs(angle) < epsilon) {
+			// 0 degree
+			rotOp = TransposeDescriptor.FLIP_HORIZONTAL;
+		} else if (Math.abs(angle - 90) < epsilon) {
+			// 90 degree
+			rotOp = TransposeDescriptor.FLIP_VERTICAL;
+		} else if (Math.abs(angle - 180) < epsilon) {
+			// 180 degree
+			rotOp = TransposeDescriptor.FLIP_HORIZONTAL;
+		} else if (Math.abs(angle - 270) < epsilon) {
+			// 270 degree
+			rotOp = TransposeDescriptor.FLIP_VERTICAL;
+		} else if (Math.abs(angle - 360) < epsilon) {
+			// 360 degree
+			rotOp = TransposeDescriptor.FLIP_HORIZONTAL;
+		}
+		// use Transpose operation
+		ParameterBlock param = new ParameterBlock();
+		param.addSource(img);
+		param.add(rotOp);
+		mirImg = JAI.create("transpose", param);
+
+		if (mirImg == null) {
+			throw new ImageOpException("Unable to flip");
+		}
+		img = mirImg;
+	}
+
+	/* contrast and brightness enhancement */
+	public void enhance(float mult, float add) throws ImageOpException {
+		RenderedImage enhImg;
+		double[] ma = { mult };
+		double[] aa = { add };
+		// use Rescale operation
+		ParameterBlock param = new ParameterBlock();
+		param.addSource(img);
+		param.add(ma);
+		param.add(aa);
+		enhImg = JAI.create("rescale", param);
+
+		logger.debug("ENHANCE: *" + mult + ", +" + add + " ->"
+				+ enhImg.getWidth() + "x" + enhImg.getHeight());
+		// DEBUG
+		img = enhImg;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see digilib.image.DocuImage#enhanceRGB(float[], float[])
+	 */
+	public void enhanceRGB(float[] rgbm, float[] rgba) throws ImageOpException {
+		RenderedImage enhImg;
+		int nb = rgbm.length;
+		double[] ma = new double[nb];
+		double[] aa = new double[nb];
+		for (int i = 0; i < nb; i++) {
+			ma[i] = rgbm[i];
+			aa[i] = rgba[i];
+		}
+		// use Rescale operation
+		ParameterBlock param = new ParameterBlock();
+		param.addSource(img);
+		param.add(ma);
+		param.add(aa);
+		enhImg = JAI.create("rescale", param);
+
+		logger.debug("ENHANCE_RGB: *" + rgbm + ", +" + rgba + " ->"
+				+ enhImg.getWidth() + "x" + enhImg.getHeight());
+		img = enhImg;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see digilib.image.DocuImage#dispose()
+	 */
+	public void dispose() {
+		img = null;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-jai/src/main/java/digilib/image/JAIImageLoaderDocuImage.java	Wed Jan 25 15:13:06 2012 +0100
@@ -0,0 +1,218 @@
+/* JAIImageLoaderDocuImage -- Image class implementation using JAI's ImageLoader Plugin
+
+  Digital Image Library servlet components
+
+  Copyright (C) 2002, 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.image;
+
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.FileImageInputStream;
+import javax.imageio.stream.ImageInputStream;
+import javax.media.jai.JAI;
+
+import digilib.io.FileOpException;
+import digilib.io.ImageInput;
+import digilib.util.ImageSize;
+
+/** DocuImage implementation using the Java Advanced Imaging API and the ImageLoader
+ * API of Java 1.4.
+ */
+public class JAIImageLoaderDocuImage extends JAIDocuImage {
+
+	/** ImageIO image reader */
+	protected ImageReader reader;
+	/** current image file */
+	protected File imgFile;
+
+	/* loadSubimage is supported. */
+	public boolean isSubimageSupported() {
+		return true;
+	}
+
+    /* returns the size of the current image */
+    public ImageSize getSize() {
+        ImageSize is = null;
+        // TODO: can we cache imageSize?
+        int h = 0;
+        int w = 0;
+        try {
+            if (img == null) {
+                // get size from ImageReader
+                h = reader.getHeight(0);
+                w = reader.getWidth(0);
+            } else {
+                // get size from image
+                h = img.getHeight();
+                w = img.getWidth();
+            }
+            is = new ImageSize(w, h);
+        } catch (IOException e) {
+            logger.debug("error in getSize:", e);
+        }
+        return is;
+    }
+
+
+	/* Load an image file into the Object. */
+	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!");
+		}
+	}
+
+	/* Get an ImageReader for the image file. */
+	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<ImageReader> 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(ImageInput ii, Rectangle region, int prescale)
+		throws FileOpException {
+		logger.debug("loadSubimage: "+ii.getFile());
+		//System.gc();
+		try {
+			if ((reader == null) || (imgFile != ii.getFile())) {
+				getReader(ii);
+			}
+			ImageReadParam readParam = reader.getDefaultReadParam();
+			readParam.setSourceRegion(region);
+			readParam.setSourceSubsampling(prescale, prescale, 0, 0);
+			img = reader.read(0, readParam);
+			/* JAI imageread seems to ignore the readParam :-(
+			ImageInputStream istream = (ImageInputStream) reader.getInput();
+			ParameterBlockJAI pb = new ParameterBlockJAI("imageread");
+			pb.setParameter("Input", istream);
+			pb.setParameter("ReadParam", readParam);
+			pb.setParameter("Reader", reader);
+			img = JAI.create("imageread", pb);
+			*/
+		} catch (IOException e) {
+			throw new FileOpException("Unable to load File!");
+		}
+		if (img == null) {
+			throw new FileOpException("Unable to load File!");
+		}
+		imgFile = ii.getFile();
+	}
+
+
+	/* Write the current image to an OutputStream. */
+	public void writeImage(String mt, OutputStream ostream)
+		throws ImageOpException, FileOpException {
+		logger.debug("writeImage");
+		try {
+			// setup output
+			ParameterBlock pb3 = new ParameterBlock();
+			pb3.addSource(img);
+			pb3.add(ostream);
+			if (mt == "image/jpeg") {
+				pb3.add("JPEG");
+			} else if (mt == "image/png") {
+				pb3.add("PNG");
+			} else {
+				// unknown mime type
+				throw new ImageOpException("Unknown mime type: " + mt);
+			}
+			// render output
+			JAI.create("ImageWrite", pb3);
+		} catch (RuntimeException e) {
+			throw new FileOpException("Error writing image.");
+		}
+	}
+
+	@Override
+    public Image getAwtImage() {
+        // TODO Auto-generated method stub
+        return (Image) img;
+    }
+
+    /* (non-Javadoc)
+	 * @see java.lang.Object#finalize()
+	 */
+	protected void finalize() throws Throwable {
+		dispose();
+		super.finalize();
+	}
+
+	public void dispose() {
+		// we must dispose the ImageReader because it keeps the filehandle open!
+		reader.dispose();
+		reader = null;
+		img = null;
+	}
+
+}
--- a/common/pom.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/common/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -5,11 +5,9 @@
   <parent>
     <artifactId>digilib</artifactId>
     <groupId>digilib</groupId>
-    <version>2.0-SNAPSHOT</version>
+    <version>2.1-SNAPSHOT</version>
   </parent>
-  <groupId>digilib</groupId>
   <artifactId>digilib-common</artifactId>
-  <version>2.0-SNAPSHOT</version>
   <name>digilib-common</name>
   <description>The Digital Image Library - common library</description>
   <url>http://digilib.berlios.de</url>
@@ -19,28 +17,26 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
 
+  <repositories>
+  	<!-- This provides the required versions of JAI-ImageIO -->
+    <repository>
+        <id>geotools.osgeo.org</id>
+        <name>Geotools repository</name>
+        <url>http://download.osgeo.org/webdav/geotools/</url>
+    </repository>
+  </repositories>
   <dependencies>
     <dependency>
       <groupId>javax.media</groupId>
       <artifactId>jai_imageio</artifactId>
         <type>jar</type>
-        <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.media</groupId>
-      <artifactId>jai_codec</artifactId>
-        <type>jar</type>
-        <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.media</groupId>
-      <artifactId>jai_core</artifactId>
-        <type>jar</type>
+      	<version>1.1</version>
         <scope>compile</scope>
     </dependency>
   	<dependency>
   		<groupId>org.devlib.schmidt</groupId>
   		<artifactId>imageinfo</artifactId>
+        <version>1.9</version>
   		<type>jar</type>
   		<scope>compile</scope>
   	</dependency>
--- a/pdf/pom.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/pdf/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -12,6 +12,13 @@
 	<name>digilib-pdf</name>
 	<description>The Digital Image Library - PDF generation servlet</description>
 	<url>http://digilib.berlios.de</url>
+	<repositories>
+    <repository>
+      <id>itextpdf.com</id>
+      <name>Maven Repository for iText</name>
+      <url>http://maven.itextpdf.com/</url>
+    </repository>
+    </repositories>
 	<dependencies>
 		<dependency>
 			<groupId>digilib</groupId>
@@ -22,6 +29,7 @@
 		<dependency>
 			<groupId>com.itextpdf</groupId>
 			<artifactId>itextpdf</artifactId>
+	        <version>5.0.4</version>
 			<type>jar</type>
 			<scope>compile</scope>
 		</dependency>
--- a/pom.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -4,7 +4,7 @@
 
   <groupId>digilib</groupId>
   <artifactId>digilib</artifactId>
-  <version>2.0-SNAPSHOT</version>
+  <version>2.1-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>digilib</name>
@@ -12,6 +12,15 @@
   <url>http://digilib.berlios.de</url>
 
   <build>
+  	<pluginManagement>
+  		<plugins>
+  			<plugin>
+  			  <groupId>org.apache.maven.plugins</groupId>
+  			  <artifactId>maven-compiler-plugin</artifactId>
+  			  <version>2.3.2</version>
+  			</plugin>
+  		</plugins>
+  	</pluginManagement>
   	<plugins>
   		<plugin>
   			<groupId>org.apache.maven.plugins</groupId>
@@ -22,15 +31,6 @@
             </configuration>
   		</plugin>
   	</plugins>
-  	<pluginManagement>
-  		<plugins>
-  			<plugin>
-  				<groupId>org.apache.maven.plugins</groupId>
-  				<artifactId>maven-war-plugin</artifactId>
-  				<version>2.1.1</version>
-  			</plugin>
-  		</plugins>
-  	</pluginManagement>
   </build>
   <profiles>
   	<profile>
@@ -38,65 +38,14 @@
   		<activation>
   			<activeByDefault>true</activeByDefault>
   		</activation>
-  		<dependencyManagement>
-  			<dependencies>
-  			</dependencies>
-  		</dependencyManagement>
-  	</profile>
-  	<profile>
-  		<id>servlet3</id>
-  		<dependencyManagement>
-  			<dependencies>
-  				<dependency>
-  					<groupId>org.mortbay.jetty</groupId>
-  					<artifactId>servlet-api</artifactId>
-  					<version>3.0.20100224</version>
-  					<type>jar</type>
-  					<scope>provided</scope>
-  				</dependency>
-  			</dependencies>
-  		</dependencyManagement>
   	</profile>
   </profiles>
   <repositories>
-    <repository>
-      <id>itextpdf.com</id>
-      <name>Maven Repository for iText</name>
-      <url>http://maven.itextpdf.com/</url>
-    </repository>
-  <!-- This provides the required versions of JAI-ImageIO -->
-    <repository>
-        <id>geotools.osgeo.org</id>
-        <name>Geotools repository</name>
-        <url>http://download.osgeo.org/webdav/geotools/</url>
-    </repository>
   </repositories>
 
   <dependencyManagement>
   	<dependencies>
     <dependency>
-      <groupId>javax.media</groupId>
-      <artifactId>jai_imageio</artifactId>
-      <version>1.1</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.media</groupId>
-      <artifactId>jai_codec</artifactId>
-      <version>1.1.3</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.media</groupId>
-      <artifactId>jai_core</artifactId>
-      <version>1.1.3</version>
-    </dependency>
-    <dependency>
-        <groupId>org.devlib.schmidt</groupId>
-        <artifactId>imageinfo</artifactId>
-        <version>1.9</version>
-        <type>jar</type>
-        <scope>compile</scope>
-    </dependency>
-    <dependency>
         <groupId>org.jdom</groupId>
         <artifactId>jdom</artifactId>
         <version>1.1</version>
@@ -111,50 +60,58 @@
         <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>com.itextpdf</groupId>
-      <artifactId>itextpdf</artifactId>
-      <version>5.0.4</version>
-      <scope>compile</scope>
+    	<groupId>digilib</groupId>
+    	<artifactId>digilib-common</artifactId>
+    	<version>2.1-SNAPSHOT</version>
+    	<type>jar</type>
+    	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
-    	<artifactId>digilib-common</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<artifactId>digilib-common-jai</artifactId>
+    	<version>2.1-SNAPSHOT</version>
+    	<type>jar</type>
+    	<scope>compile</scope>
+    </dependency>
+    <dependency>
+    	<groupId>digilib</groupId>
+    	<artifactId>digilib-common-imagej</artifactId>
+    	<version>2.1-SNAPSHOT</version>
     	<type>jar</type>
     	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
     	<artifactId>digilib-pdf</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<version>2.1-SNAPSHOT</version>
     	<type>jar</type>
     	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
     	<artifactId>digilib-text</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<version>2.1-SNAPSHOT</version>
     	<type>jar</type>
     	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
     	<artifactId>digilib-servlet2</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<version>2.1-SNAPSHOT</version>
     	<type>jar</type>
     	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
     	<artifactId>digilib-servlet3</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<version>2.1-SNAPSHOT</version>
     	<type>jar</type>
     	<scope>compile</scope>
     </dependency>
     <dependency>
     	<groupId>digilib</groupId>
     	<artifactId>digilib-webapp</artifactId>
-    	<version>2.0-SNAPSHOT</version>
+    	<version>2.1-SNAPSHOT</version>
     	<type>war</type>
     	<scope>compile</scope>
     </dependency>
@@ -197,5 +154,7 @@
     <module>servlet3</module>
     <module>pdf</module>
     <module>text</module>
+    <module>common-jai</module>
+    <module>common-imagej</module>
   </modules>
 </project>
\ No newline at end of file
--- a/servlet2/src/main/java/digilib/servlet/DigilibServletConfiguration.java	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet2/src/main/java/digilib/servlet/DigilibServletConfiguration.java	Wed Jan 25 15:13:06 2012 +0100
@@ -69,7 +69,7 @@
 		// DocuImage class instance
 		newParameter(
 			"servlet.docuimage.class",
-			digilib.image.JAIDocuImage.class,
+			digilib.image.ImageLoaderDocuImage.class,
 			null,
 			's');
 		// AuthOps instance for authentication
@@ -115,7 +115,7 @@
 		// Type of DocuImage instance
 		newParameter(
 			"docuimage-class",
-			"digilib.image.JAIDocuImage",
+			"digilib.image.ImageLoaderDocuImage",
 			null,
 			'f');
 		// part of URL used to indicate authorized access
--- a/servlet2/src/main/java/digilib/servlet/Scaler.java	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet2/src/main/java/digilib/servlet/Scaler.java	Wed Jan 25 15:13:06 2012 +0100
@@ -34,7 +34,7 @@
     private static final long serialVersionUID = -5439198888139362735L;
 
     /** digilib servlet version (for all components) */
-    public static final String version = "2.0b1 noasync";
+    public static final String version = "2.1b1 noasync";
 
     /** servlet error codes */
     public static enum Error {UNKNOWN, AUTH, FILE, IMAGE};
--- a/servlet3/pom.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet3/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -3,11 +3,9 @@
   <parent>
     <artifactId>digilib</artifactId>
     <groupId>digilib</groupId>
-    <version>2.0-SNAPSHOT</version>
+    <version>2.1-SNAPSHOT</version>
   </parent>
-  <groupId>digilib</groupId>
   <artifactId>digilib-servlet3</artifactId>
-  <version>2.0-SNAPSHOT</version>
   <name>digilib-servlet3</name>
   <build>
   	<pluginManagement>
@@ -15,7 +13,6 @@
   			<plugin>
   				<groupId>org.apache.maven.plugins</groupId>
   				<artifactId>maven-compiler-plugin</artifactId>
-  				<version>2.3.2</version>
                 <configuration>
                     <source>1.6</source>
                     <target>1.6</target> 
--- a/servlet3/src/main/java/digilib/servlet/DigilibServletConfiguration.java	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet3/src/main/java/digilib/servlet/DigilibServletConfiguration.java	Wed Jan 25 15:13:06 2012 +0100
@@ -78,7 +78,7 @@
         newParameter("servlet.dir.cache", null, null, 's');
         // DocuImage class instance
         newParameter("servlet.docuimage.class",
-                digilib.image.JAIDocuImage.class, null, 's');
+                digilib.image.ImageLoaderDocuImage.class, null, 's');
         // AuthOps instance for authentication
         newParameter("servlet.auth.op", null, null, 's');
         // Executor for image operations
@@ -111,7 +111,7 @@
         // sending image files as-is allowed
         newParameter("sendfile-allowed", Boolean.TRUE, null, 'f');
         // Type of DocuImage instance
-        newParameter("docuimage-class", "digilib.image.JAIDocuImage", null, 'f');
+        newParameter("docuimage-class", "digilib.image.ImageLoaderDocuImage", null, 'f');
         // part of URL used to indicate authorized access
         newParameter("auth-url-path", "authenticated/", null, 'f');
         // degree of subsampling on image load
--- a/servlet3/src/main/java/digilib/servlet/Initialiser.java	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet3/src/main/java/digilib/servlet/Initialiser.java	Wed Jan 25 15:13:06 2012 +0100
@@ -23,7 +23,6 @@
 import java.io.File;
 import java.io.OutputStream;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.imageio.ImageIO;
 import javax.servlet.ServletContext;
--- a/servlet3/src/main/java/digilib/servlet/Scaler.java	Tue Jan 24 21:12:13 2012 +0100
+++ b/servlet3/src/main/java/digilib/servlet/Scaler.java	Wed Jan 25 15:13:06 2012 +0100
@@ -31,7 +31,7 @@
     private static final long serialVersionUID = 5289386646192471549L;
 
     /** digilib servlet version (for all components) */
-    public static final String version = "2.0b4 async";
+    public static final String version = "2.1b1 async";
 
     /** servlet error codes */
     public static enum Error {
--- a/webapp/pom.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/webapp/pom.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -6,10 +6,9 @@
   <parent>
     <artifactId>digilib</artifactId>
     <groupId>digilib</groupId>
-    <version>2.0-SNAPSHOT</version>
+    <version>2.1-SNAPSHOT</version>
   </parent>
   <artifactId>digilib-webapp</artifactId>
-  <version>2.0-SNAPSHOT</version>
   <name>digilib-webapp</name>
   <description>The Digital Image Library - web application server and HTML and JS clients</description>
   <url>http://digilib.berlios.de</url>
@@ -19,6 +18,18 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
 
+  <build>
+	<pluginManagement>
+	  <plugins>
+      	<plugin>
+	      <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+		  <version>2.1.1</version>
+	    </plugin>
+      </plugins>	
+	</pluginManagement>
+  </build>
+
   <profiles>
     <profile>
       <id>servlet2</id>
@@ -109,5 +120,27 @@
         </dependency>
       </dependencies>
     </profile>
+    <profile>
+      <id>codec-jai</id>
+      <dependencies>
+        <dependency>
+          <groupId>digilib</groupId>
+          <artifactId>digilib-common-jai</artifactId>
+          <type>jar</type>
+          <scope>compile</scope>
+        </dependency>
+      </dependencies>
+    </profile>
+    <profile>
+      <id>codec-imagej</id>
+      <dependencies>
+        <dependency>
+          <groupId>digilib</groupId>
+          <artifactId>digilib-common-imagej</artifactId>
+          <type>jar</type>
+          <scope>compile</scope>
+        </dependency>
+      </dependencies>
+    </profile>
   </profiles>
 </project>
--- a/webapp/src/main/webapp/WEB-INF/digilib-config.xml	Tue Jan 24 21:12:13 2012 +0100
+++ b/webapp/src/main/webapp/WEB-INF/digilib-config.xml	Wed Jan 25 15:13:06 2012 +0100
@@ -18,6 +18,7 @@
 
   <!-- Java class to use for image operations -->
   <parameter name="docuimage-class" value="digilib.image.ImageLoaderDocuImage" />
+  <!-- <parameter name="docuimage-class" value="digilib.image.ImageJ1DocuImage" /> -->
 
   <!-- mimimum amount of scaling done with antialiasing -->
   <parameter name="subsample-minimum" value="2"/>