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