changeset 100:cc6a0b9ac78e

digilib V1.9b1 - bugfixes with parameters - ongoing work with rotation (still doesn't work as I want) - ongoing work with absolute scale function
author robcast
date Mon, 05 May 2003 22:18:37 +0200
parents 226624784fe3
children 78f52a1876fe
files servlet/src/digilib/servlet/DigilibRequest.java servlet/src/digilib/servlet/DocumentBean.java servlet/src/digilib/servlet/Scaler.java
diffstat 3 files changed, 148 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- 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;
 	}
 
 	/**
--- 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();
 		}
--- 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);