# HG changeset patch # User robcast # Date 1052165917 -7200 # Node ID cc6a0b9ac78ee2f01f1980bb12206ccc2e2406a2 # Parent 226624784fe3fd4f95f7ec66bfd39524c370f565 digilib V1.9b1 - bugfixes with parameters - ongoing work with rotation (still doesn't work as I want) - ongoing work with absolute scale function diff -r 226624784fe3 -r cc6a0b9ac78e servlet/src/digilib/servlet/DigilibRequest.java --- a/servlet/src/digilib/servlet/DigilibRequest.java Mon May 05 22:16:21 2003 +0200 +++ b/servlet/src/digilib/servlet/DigilibRequest.java Mon May 05 22:18:37 2003 +0200 @@ -83,18 +83,14 @@ private String rgbm_s; private float[] rgba; // color additive factors private String rgba_s; - - private DocuImage image; // internal DocuImage instance for this request - private ServletRequest servletRequest; // internal ServletRequest - -// lugi - begin - private int lv; // level of digilib (0 = just image, 1 = one HTML page // 2 = in frameset, 3 = XUL-'frameset' // 4 = XUL-Sidebar ) private String lv_s; -// lugi - end + private DocuImage image; // internal DocuImage instance for this request + private ServletRequest servletRequest; // internal ServletRequest + /** Creates a new instance of DigilibRequest and sets default values. */ @@ -139,15 +135,6 @@ */ public void setWithOldString(String queryString) { -// lugi - begin - - // default level ( might be initialized - // in the reset method - robert? ) - lv = 2; - lv_s = "2"; - -// lugi - end - if (queryString == null) { return; } @@ -322,10 +309,10 @@ if (ws_s != null) { s += "&ws=" + ws_s; } - if (mo != null) { + if ((mo != null)&&(mo.length() > 0)) { s += "&mo=" + mo; } - if (mk != null) { + if ((mk != null)&&(mk.length() > 0)) { s += "&mk=" + mk; } if (rot_s != null) { @@ -341,20 +328,15 @@ s += "&rgbm=" + rgbm_s; } if (rgba_s != null) { - s += "&reda=" + rgba_s; + s += "&rgba=" + rgba_s; } if (pt_s != null) { s += "&pt=" + pt_s; } - -// lugi - begin - if (lv_s != null) { s += "&lv=" + lv_s; } -// lugi - end - return s; } @@ -452,19 +434,10 @@ if (s != null) { setPt(s); } - -// lugi - begin - s = request.getParameter("lv"); if (s != null) { setLv(s); - } else { - setLv(2); // default level ( might be initialized - // in the reset method - robert? ) } - -// lugi - end - s = ((HttpServletRequest) request).getPathInfo(); if (s != null) { setRequestPath(s); @@ -475,13 +448,8 @@ public void reset() { request_path = null; // url of the page/document -// lugi -begin - - lv = 0; // level of digilib cf. variable declatation + lv = 0; // level of digilib cf. variable declaration lv_s = null; - -// lugi - end - fn = null; // url of the page/document pn = 0; // page number pn_s = null; @@ -520,6 +488,8 @@ /** Reset all request parameters to default values. */ public void setToDefault() { + lv = 2; // default level + lv_s = "2"; request_path = ""; // url of the page/document fn = ""; // url of the page/document pn = 1; // page number @@ -981,7 +951,7 @@ * @return float */ public float getRot() { - return rot; + return rot; } /** diff -r 226624784fe3 -r cc6a0b9ac78e servlet/src/digilib/servlet/DocumentBean.java --- a/servlet/src/digilib/servlet/DocumentBean.java Mon May 05 22:16:21 2003 +0200 +++ b/servlet/src/digilib/servlet/DocumentBean.java Mon May 05 22:18:37 2003 +0200 @@ -172,7 +172,7 @@ */ public int getNumPages(DigilibRequest request) throws Exception { util.dprintln(10, "getNumPages"); - DocuDirectory dd = dirCache.getDirectory(request.getFilePath()); + DocuDirectory dd = (dirCache != null) ? dirCache.getDirectory(request.getFilePath()) : null; if (dd != null) { return dd.size(); } diff -r 226624784fe3 -r cc6a0b9ac78e servlet/src/digilib/servlet/Scaler.java --- a/servlet/src/digilib/servlet/Scaler.java Mon May 05 22:16:21 2003 +0200 +++ b/servlet/src/digilib/servlet/Scaler.java Mon May 05 22:18:37 2003 +0200 @@ -22,7 +22,7 @@ import java.awt.Dimension; import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; +import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.IOException; @@ -56,7 +56,7 @@ public class Scaler extends HttpServlet { // digilib servlet version (for all components) - public static final String dlVersion = "1.8b4"; + public static final String dlVersion = "1.9b1"; // Utils instance with debuglevel Utils util; @@ -75,6 +75,10 @@ // use authorization database boolean useAuthentication = true; + // EXPRIMENTAL + // try to enlarge cropping area for "oblique" angles + boolean wholeRotArea = false; + /** Initialisation on first run. * * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) @@ -162,6 +166,8 @@ // scale the image file to fit window size i.e. respect dw,dh boolean scaleToFit = true; + // scale the image by a fixed factor only + boolean absoluteScale = false; // crop the image if needed boolean cropToFit = true; // use heuristics (GIF?) to scale or send as is @@ -214,20 +220,31 @@ */ if (dlRequest.isOption("clip")) { scaleToFit = false; + absoluteScale = false; cropToFit = true; autoScale = false; + preScaledFirst = false; } else if (dlRequest.isOption("fit")) { scaleToFit = true; + absoluteScale = false; cropToFit = true; autoScale = false; + } else if (dlRequest.isOption("scale")) { + scaleToFit = false; + absoluteScale = true; + cropToFit = true; + autoScale = false; + preScaledFirst = false; } else if (dlRequest.isOption("file")) { scaleToFit = false; + absoluteScale = false; if (dlConfig.isSendFileAllowed()) { cropToFit = false; } else { cropToFit = true; } autoScale = false; + preScaledFirst = false; } // operation mode: "errtxt": error message in html, "errimg": error image if (dlRequest.isOption("errtxt")) { @@ -249,14 +266,6 @@ } else if (dlRequest.isOption("hires")) { preScaledFirst = false; } - // operation mode: "hmir": mirror horizontally, "vmir": mirror vertically - if (dlRequest.isOption("hmir")) { - doMirror = true; - mirrorAngle = 0; - } else if (dlRequest.isOption("vmir")) { - doMirror = true; - mirrorAngle = 90; - } //"big" try for all file/image actions try { @@ -304,11 +313,6 @@ } } - // if it's zoomed, try hires version (to be optimized...) - if ((paramWW < 1f) || (paramWH < 1f)) { - preScaledFirst = false; - } - // find the file DocuFile fileToLoad; DocuFileset fileset = @@ -322,6 +326,11 @@ + ") not found."); } + // if it's zoomed, try hires version (to be optimized...) + if ((paramWW < 1f) || (paramWH < 1f)) { + preScaledFirst = false; + } + // simplistic selection of resolution if (preScaledFirst) { // get last element @@ -339,12 +348,14 @@ /* if autoScale and not zoomed and source is GIF/PNG * then send as is. + * if not autoScale and not scaleToFit nor cropToFit + * then send as is */ if ((autoScale && (mimeType == "image/gif" || mimeType == "image/png") && (paramWW == 1f) && (paramWH == 1f)) - || (autoScale && !(scaleToFit || cropToFit))) { + || (!autoScale && !scaleToFit && !cropToFit)) { util.dprintln(1, "Sending File as is."); @@ -381,23 +392,6 @@ 2, "time " + (System.currentTimeMillis() - startTime) + "ms"); - // coordinates using Java2D - // image size - Rectangle2D imgBounds = - new Rectangle2D.Double(0, 0, imgWidth, imgHeight); - // user window area in 4-point form (ul, ur, ll, lr) - Point2D[] userAreaC = - { - new Point2D.Double(paramWX, paramWY), - new Point2D.Double(paramWX + paramWW, paramWY), - new Point2D.Double(paramWX, paramWY + paramWH), - new Point2D.Double(paramWX + paramWW, paramWY + paramWH)}; - // transformation from relative [0,1] to image coordinates. - AffineTransform imgTrafo = new AffineTransform(); - imgTrafo.scale(imgWidth, imgHeight); - // rotate coordinates - //imgTrafo.rotate(Math.toRadians(-paramROT)); - // coordinates and scaling double areaXoff; double areaYoff; @@ -407,68 +401,83 @@ double scaleY; double scaleXY; - /* if (scaleToFit) { - // calculate absolute from relative coordinates - areaXoff = paramWX * imgWidth; - areaYoff = paramWY * imgHeight; - areaWidth = paramWW * imgWidth; - areaHeight = paramWH * imgHeight; - // calculate scaling factors - scaleX = paramDW / areaWidth * paramWS; - scaleY = paramDH / areaHeight * paramWS; - scaleXY = (scaleX > scaleY) ? scaleY : scaleX; - } else { - // crop to fit - // calculate absolute from relative coordinates - areaXoff = paramWX * imgWidth; - areaYoff = paramWY * imgHeight; - areaWidth = paramDW; - areaHeight = paramDH; - // calculate scaling factors - scaleX = 1f; - scaleY = 1f; - scaleXY = 1f; - } - - util.dprintln( - 1, - "Scale " - + scaleXY - + "(" - + scaleX - + "," - + scaleY - + ") on " - + areaXoff - + "," - + areaYoff - + " " - + areaWidth - + "x" - + areaHeight); - */ - // Java2D - // area in image pixel coordinates - Point2D[] imgAreaC = { null, null, null, null }; + // coordinates using Java2D + // image size in pixels + Rectangle2D imgBounds = + new Rectangle2D.Double(0, 0, imgWidth, imgHeight); + // user window area in [0,1] coordinates + Rectangle2D relUserArea = + new Rectangle2D.Double(paramWX, paramWY, paramWW, paramWH); + // transform from relative [0,1] to image coordinates. + AffineTransform imgTrafo = + AffineTransform.getScaleInstance(imgWidth, imgHeight); // transform user coordinate area to image coordinate area - imgTrafo.transform(userAreaC, 0, imgAreaC, 0, 4); - areaXoff = imgAreaC[0].getX(); - areaYoff = imgAreaC[0].getY(); - // calculate scaling factors + Rectangle2D userImgArea = + imgTrafo.createTransformedShape(relUserArea).getBounds2D(); + + // calculate scaling factors based on inner user area if (scaleToFit) { - areaWidth = imgAreaC[0].distance(imgAreaC[1]); - areaHeight = imgAreaC[0].distance(imgAreaC[2]); + areaWidth = userImgArea.getWidth(); + areaHeight = userImgArea.getHeight(); scaleX = paramDW / areaWidth * paramWS; scaleY = paramDH / areaHeight * paramWS; scaleXY = (scaleX > scaleY) ? scaleY : scaleX; + } else if (absoluteScale) { + // absolute scale + areaWidth = paramDW * paramWS; + areaHeight = paramDH * paramWS; + // reset user area size + userImgArea.setRect( + userImgArea.getX(), + userImgArea.getY(), + areaWidth, + areaHeight); + scaleX = 1f; + scaleY = 1f; + scaleXY = 1f; } else { // crop to fit areaWidth = paramDW * paramWS; areaHeight = paramDH * paramWS; + // reset user area size + userImgArea.setRect( + userImgArea.getX(), + userImgArea.getY(), + areaWidth, + areaHeight); scaleX = 1f; scaleY = 1f; scaleXY = 1f; + } + // enlarge image area for rotations to cover additional pixels + Rectangle2D outerUserImgArea = userImgArea; + Rectangle2D innerUserImgArea = userImgArea; + if (wholeRotArea) { + if (paramROT != 0) { + try { + // rotate user area coordinates around center of user area + AffineTransform rotTrafo = + AffineTransform.getRotateInstance( + Math.toRadians(paramROT), + userImgArea.getCenterX(), + userImgArea.getCenterY()); + // get bounds from rotated end position + innerUserImgArea = + rotTrafo + .createTransformedShape(userImgArea) + .getBounds2D(); + // get bounds from back-rotated bounds + outerUserImgArea = + rotTrafo + .createInverse() + .createTransformedShape(innerUserImgArea) + .getBounds2D(); + } catch (NoninvertibleTransformException e1) { + // this shouldn't happen anyway + e1.printStackTrace(); + } + } } util.dprintln( @@ -480,36 +489,15 @@ + "," + scaleY + ") on " - + areaXoff - + "," - + areaYoff - + " " - + areaWidth - + "x" - + areaHeight); + + outerUserImgArea); // clip area at the image border - /* areaWidth = - (areaXoff + areaWidth > imgWidth) - ? imgWidth - areaXoff - : areaWidth; - areaHeight = - (areaYoff + areaHeight > imgHeight) - ? imgHeight - areaYoff - : areaHeight; - */ + outerUserImgArea = outerUserImgArea.createIntersection(imgBounds); - // create new rectangle from coordinates - Rectangle2D imgArea = - new Rectangle2D.Double( - areaXoff, - areaYoff, - areaWidth, - areaHeight); - // clip area at the image border - imgArea = imgArea.createIntersection(imgBounds); - areaWidth = imgArea.getWidth(); - areaHeight = imgArea.getHeight(); + areaWidth = outerUserImgArea.getWidth(); + areaHeight = outerUserImgArea.getHeight(); + areaXoff = outerUserImgArea.getX(); + areaYoff = outerUserImgArea.getY(); util.dprintln( 2, @@ -551,7 +539,7 @@ docuImage.loadSubimage( fileToLoad.getFile(), - imgArea.getBounds(), + outerUserImgArea.getBounds(), (int) subsamp); System.out.println( @@ -565,7 +553,7 @@ docuImage.scale(scaleXY); } else { - // else load the whole file + // else load and crop the whole file docuImage.loadImage(fileToLoad.getFile()); docuImage.crop( (int) areaXoff, @@ -577,19 +565,38 @@ } // mirror image - if (doMirror) { - docuImage.mirror(mirrorAngle); + // operation mode: "hmir": mirror horizontally, "vmir": mirror vertically + if (dlRequest.isOption("hmir")) { + docuImage.mirror(0); + } + if (dlRequest.isOption("vmir")) { + docuImage.mirror(90); } - // rotate image (first shot :-) + // rotate image if (paramROT != 0) { docuImage.rotate(paramROT); - } + if (wholeRotArea) { + // crop to the inner bounding box + double xcrop = + docuImage.getWidth() + - innerUserImgArea.getWidth() * scaleXY; + double ycrop = + docuImage.getHeight() + - innerUserImgArea.getHeight() * scaleXY; + if ((xcrop > 0) || (ycrop > 0)) { + // only crop smaller + xcrop = (xcrop > 0) ? xcrop : 0; + ycrop = (ycrop > 0) ? ycrop : 0; + // crop image + docuImage.crop( + (int) (xcrop / 2), + (int) (ycrop / 2), + (int) (docuImage.getWidth() - xcrop), + (int) (docuImage.getHeight() - ycrop)); + } + } - // contrast and brightness enhancement - if ((paramCONT != 0) || (paramBRGT != 0)) { - double mult = Math.pow(2, paramCONT); - docuImage.enhance((float) mult, (float) paramBRGT); } // color modification @@ -601,7 +608,7 @@ if (paramRGBA == null) { paramRGBA = new float[3]; } - // calculate "contrast" values + // calculate "contrast" values (c=2^x) float[] mult = new float[3]; for (int i = 0; i < 3; i++) { mult[i] = (float) Math.pow(2, (double) paramRGBM[i]); @@ -609,6 +616,12 @@ docuImage.enhanceRGB(mult, paramRGBA); } + // contrast and brightness enhancement + if ((paramCONT != 0) || (paramBRGT != 0)) { + double mult = Math.pow(2, paramCONT); + docuImage.enhance((float) mult, (float) paramBRGT); + } + util.dprintln( 2, "time " + (System.currentTimeMillis() - startTime) + "ms"); @@ -618,7 +631,10 @@ */ // setup output -- if source is JPG then dest will be JPG else it's PNG - if (mimeType != "image/jpeg") { + if (mimeType.equals("image/jpeg") + || mimeType.equals("image/jp2")) { + mimeType = "image/jpeg"; + } else { mimeType = "image/png"; } response.setContentType(mimeType);