diff servlet/src/digilib/servlet/Scaler.java @ 73:3b8797fc3e90

New servlet version 1.5b. Mostly cleanup. Global parameters for digilib now in DigilibConfiguration, per request parameters are now all in DigilibRequest. The DocuImage implementation can be selected by the configuration docuimage-class. Pixel-by-pixel view implemented with "mo=clip".
author robcast
date Fri, 24 Jan 2003 21:40:59 +0100
parents 4ef2a86fc1bc
children 63c8186455c1
line wrap: on
line diff
--- a/servlet/src/digilib/servlet/Scaler.java	Fri Jan 24 21:40:59 2003 +0100
+++ b/servlet/src/digilib/servlet/Scaler.java	Fri Jan 24 21:40:59 2003 +0100
@@ -2,7 +2,7 @@
 
   Digital Image Library servlet components
 
-  Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de)
+  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
@@ -32,353 +32,470 @@
 
 //import tilecachetool.*;
 
+/**
+ * @author casties
+ *
+ */
 //public class Scaler extends HttpServlet implements SingleThreadModel {
 public class Scaler extends HttpServlet {
 
-  // Utils instance with debuglevel
-  Utils util;
-  // ServletOpss instance
-  ServletOps servletOp;
-  // FileOps instance
-  FileOps fileOp;
-  // AuthOps instance
-  AuthOps authOp;
-  // global DocuImage instance (don't reuse inside a request!)
-  DocuImage globalImage;
+	// digilib servlet version (for all components)
+	public static final String dlVersion = "1.5b";
+	
+	// Utils instance with debuglevel
+	Utils util;
+	// FileOps instance
+	FileOps fileOp;
+	// AuthOps instance
+	AuthOps authOp;
+	// ServletOps instance
+	ServletOps servletOp;
 
-  // use authorization database
-  boolean useAuthentication = true;
-  // image file to send in case of error
-  File errorImgFile = new File("/docuserver/images/icons/scalerror.gif");
-  // image file to send if access is denied
-  File denyImgFile = new File("/docuserver/images/icons/denied.gif");
-  // base directories in order of preference (prescaled versions first)
-  String[] baseDirs = {"/docuserver/scaled/small", "/docuserver/images", "/docuserver/scans/quellen"};
+	// DigilibParameters instance
+	DigilibConfiguration dlConfig;
 
+	// use authorization database
+	boolean useAuthentication = true;
 
-  /*********************************************************
-   *             Initialize global variables
-   *********************************************************/
-  public void init(ServletConfig config) throws ServletException {
-    super.init(config);
+	/** Initialisation on first run.
+	 * 
+	 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
+	 */
+	public void init(ServletConfig config) throws ServletException {
+		super.init(config);
 
-    // Debuggin!
-    //TCTool tctool = new TCTool();
-    
-    // first we need an Utils to setup ServletOps UGLY!!
-    util = new Utils(5);
-    // servletOps takes a ServletConfig to get the config file name
-    servletOp = new ServletOps(util, config);
-    // then we can start reading parameters UGLY!!
+		// Debuggin!
+		//TCTool tctool = new TCTool();
 
-    // Utils with new debuglevel
-    int debugLevel = servletOp.tryToGetInitParam("debug-level", 10);
-    util.setDebugLevel(debugLevel);
-    // image file to send in case of error
-    String errorImgFileName = servletOp.tryToGetInitParam("error-image", "/docuserver/images/icons/scalerror.gif");
-    errorImgFile = new File(errorImgFileName);
-    // image file to send if access is denied
-    String denyImgFileName = servletOp.tryToGetInitParam("denied-image", "/docuserver/images/icons/denied.gif");
-    denyImgFile = new File(denyImgFileName);
-    // base directories in order of preference (prescaled versions first)
-    String baseDirList = servletOp.tryToGetInitParam("basedir-list", "/docuserver/scaled/small:/docuserver/images:/docuserver/scans/quellen");
-    // split list into directories
-    baseDirs = servletOp.tryToGetPathArray(baseDirList, baseDirs);
-    // use authentication information
-    String useAuth = servletOp.tryToGetInitParam("use-authorization", "true");
-    if ((useAuth.indexOf("false") > -1)||(useAuth.indexOf("FALSE") > -1)) {
-      useAuthentication = false;
-    } else {
-      useAuthentication = true;
-      try {
-        // DB version
-        //authOp = new DBAuthOpsImpl(util);
-        // XML version
-        String cnfPath = servletOp.tryToGetInitParam("auth-file", "/docuserver/www/digitallibrary/WEB-INF/digilib-auth.xml");
-        authOp = new XMLAuthOps(util, cnfPath);
-      } catch (AuthOpException e) {
-        throw new ServletException(e);
-      }
-    }
-    // FileOps instance
-    fileOp = new FileOps(util);
-    // global DocuImage instance (don't reuse inside a request!)
-    globalImage = new JAIDocuImage(util);
-    // globalImage = new JIMIDocuImage(util);
-    //globalImage = new ImageLoaderDocuImage(util);
-    //globalImage = new JAIImageLoaderDocuImage(util);
-  }
+		// get our ServletContext
+		ServletContext context = config.getServletContext();
+		// see if there is a Configuration instance
+		dlConfig =
+			(DigilibConfiguration) context.getAttribute(
+				"digilib.servlet.parameters");
+		if (dlConfig == null) {
+			// create new Configuration
+			try {
+				dlConfig = new DigilibConfiguration(config);
+			} catch (Exception e) {
+				throw new ServletException(e);
+			}
+		}
+		// set the servlet version
+		dlConfig.setServletVersion(dlVersion);
+		// first we need an Utils
+		util = dlConfig.getUtil();
+		// set our AuthOps
+		useAuthentication = dlConfig.isUseAuthentication();
+		authOp = dlConfig.getAuthOp();
+		// FileOps instance
+		fileOp = new FileOps(util);
+		// AuthOps instance
+		servletOp = new ServletOps(util);
+	}
 
-  /**Process the HTTP Get request*/
-  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-    util.dprintln(1, "The servlet has received a GET!");
-    processRequest(request, response);
-  }
+	/** Process the HTTP Get request*/
+	public void doGet(HttpServletRequest request, HttpServletResponse response)
+		throws ServletException, IOException {
+		util.dprintln(1, "The servlet has received a GET!");
+		// create new request with defaults
+		DigilibRequest dlReq = new DigilibRequest();
+		// set with request parameters
+		dlReq.setWithRequest(request);
+		// add DigilibRequest to ServletRequest
+		request.setAttribute(
+			"digilib.servlet.request",
+			dlReq);
+		// do the processing
+		processRequest(request, response);
+	}
 
-  /**Process the HTTP Post request*/
-  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-    util.dprintln(1, "The servlet has received a POST!");
-    processRequest(request, response);
-  }
+	/**Process the HTTP Post request*/
+	public void doPost(
+		HttpServletRequest request,
+		HttpServletResponse response)
+		throws ServletException, IOException {
+		util.dprintln(1, "The servlet has received a POST!");
+		// create new request with defaults
+		DigilibRequest dlReq = new DigilibRequest();
+		// set with request parameters
+		dlReq.setWithRequest(request);
+		// add DigilibRequest to ServletRequest
+		request.setAttribute(
+			"digilib.servlet.request",
+			dlReq);
+		// do the processing
+		processRequest(request, response);
+	}
+
+	/** main request handler. */
+	void processRequest(
+		HttpServletRequest request,
+		HttpServletResponse response)
+		throws ServletException, IOException {
 
-  /**Clean up resources*/
-  public void destroy() {
-  }
+		// time for benchmarking
+		long startTime = System.currentTimeMillis();
+		// output mime/type
+		String mimeType = "image/png";
 
-/**********************************************************************
- *                       main request handler
- **********************************************************************/
+		/*
+		 * parameters for a session
+		 */
 
-  void processRequest(HttpServletRequest request, HttpServletResponse response)
-    throws ServletException, IOException {
-
-    // time for benchmarking
-    long startTime = System.currentTimeMillis();
-    // output mime/type
-    String mimeType = "image/png";
+		// scale the image file to fit window size i.e. respect dw,dh
+		boolean scaleToFit = true;
+		// crop the image if needed
+		boolean cropToFit = true;
+		// use heuristics (GIF?) to scale or send as is
+		boolean autoScale = true;
+		// try prescaled images first
+		boolean preScaledFirst = true;
+		// interpolation to use for scaling
+		int scaleQual = 0;
+		// send html error message (or image file)
+		boolean errorMsgHtml = false;
 
-    /**
-     * parameters for a session
-     */
+		/*
+		 *  request parameters
+		 */
+
+		DigilibRequest dlRequest =
+			(DigilibRequest) request.getAttribute("digilib.servlet.request");
 
-    // scale the image file to fit window size
-    boolean scaleToFit = true;
-    // use heuristics (GIF?) to scale or not
-    boolean forcedScale = false;
-    // try prescaled images first
-    boolean preScaledFirst = true;
-    // interpolation to use for scaling
-    int scaleQual = 0;
-    // send html error message (or image file)
-    boolean errorMsgHtml = false;
-
-    /**
-     *  request parameter
-     */
+		// destination image width
+		int paramDW = dlRequest.getDw();
+		// destination image height
+		int paramDH = dlRequest.getDh();
+		// relative area x_offset (0..1)
+		float paramWX = dlRequest.getWx();
+		// relative area y_offset
+		float paramWY = dlRequest.getWy();
+		// relative area width (0..1)
+		float paramWW = dlRequest.getWw();
+		// relative area height
+		float paramWH = dlRequest.getWh();
+		// scale factor (additional to dw/width, dh/height)
+		float paramWS = dlRequest.getWs();
 
-    // file/dir to load
-    String param_fn = servletOp.tryToGetParam("fn", "", request);
-    // page number
-    int param_pn = servletOp.tryToGetParam("pn", 1, request);
-    // destination image width
-    int param_dw = servletOp.tryToGetParam("dw", 300, request);
-    // destination image height
-    int param_dh = servletOp.tryToGetParam("dh", 400, request);
-    // relative area x_offset (0..1)
-    float param_wx = servletOp.tryToGetParam("wx", 0f, request);
-    // relative area y_offset
-    float param_wy = servletOp.tryToGetParam("wy", 0f, request);
-    // relative area width (0..1)
-    float param_ww = servletOp.tryToGetParam("ww", 1f, request);
-    // relative area height
-    float param_wh = servletOp.tryToGetParam("wh", 1f, request);
-    // scale factor (additional to dw/width, dh/height)
-    float param_ws = servletOp.tryToGetParam("ws", 1f, request);
-    // operation mode: flags separated by "+"
-    String param_mo = servletOp.tryToGetParam("mo", "", request);
-    // operation mode: "fit": always fit to page, "file": send as-is
-    if (param_mo.indexOf("fit") >= 0) {
-      scaleToFit = true;
-      forcedScale = true;
-    } else if (param_mo.indexOf("file") >= 0) {
-      scaleToFit = false;
-      forcedScale = true;
-    }
-    // operation mode: "errtxt": error message in html, "errimg": error image
-    if (param_mo.indexOf("errtxt") >= 0) {
-      errorMsgHtml = true;
-    } else if (param_mo.indexOf("errimg") >= 0) {
-      errorMsgHtml = false;
-    }
-    // operation mode: "q0" - "q2": interpolation quality
-    if (param_mo.indexOf("q0") >= 0) {
-      scaleQual = 0;
-    } else if (param_mo.indexOf("q1") >= 0) {
-      scaleQual = 1;
-    } else if (param_mo.indexOf("q2") >= 0) {
-      scaleQual = 2;
-    }
-    // operation mode: "lores": try to use scaled image, "hires": unscaled image
-    if (param_mo.indexOf("lores") >= 0) {
-      preScaledFirst = true;
-    } else if (param_mo.indexOf("hires") >= 0) {
-      preScaledFirst = false;
-    }
+		/* operation mode: "fit": always fit to page, 
+		 * "clip": send original resolution cropped, "file": send whole file (if
+		 * allowed)
+		 */
+		if (dlRequest.isOption("clip")) {
+			scaleToFit = false;
+			cropToFit = true;
+			autoScale = false;
+		} else if (dlRequest.isOption("fit")) {
+			scaleToFit = true;
+			cropToFit = true;
+			autoScale = false;
+		} else if (dlRequest.isOption("file")) {
+			scaleToFit = false;
+			if (dlConfig.isSendFileAllowed()) {
+				cropToFit = false;
+			} else {
+				cropToFit = true;
+			}
+			autoScale = false;
+		}
+		// operation mode: "errtxt": error message in html, "errimg": error image
+		if (dlRequest.isOption("errtxt")) {
+			errorMsgHtml = true;
+		} else if (dlRequest.isOption("errimg")) {
+			errorMsgHtml = false;
+		}
+		// operation mode: "q0" - "q2": interpolation quality
+		if (dlRequest.isOption("q0")) {
+			scaleQual = 0;
+		} else if (dlRequest.isOption("q1")) {
+			scaleQual = 1;
+		} else if (dlRequest.isOption("q2")) {
+			scaleQual = 2;
+		}
+		// operation mode: "lores": try to use scaled image, "hires": use unscaled image
+		if (dlRequest.isOption("lores")) {
+			preScaledFirst = true;
+		} else if (dlRequest.isOption("hires")) {
+			preScaledFirst = false;
+		}
 
-    Utils.dprintln(1, "Parameter values: fn:"+param_fn+" pn:"+param_pn+" dw:"+param_dw+" dh:"+param_dh+" wx:"+param_wx+" wy:"+param_wy+" ww:"+param_ww+" wh:"+param_wh+" ws:"+param_ws+" mo:"+param_mo);
+		//"big" try for all file/image actions
+		try {
+
+			// DocuImage instance
+			DocuImage docuImage = dlConfig.getDocuImageInstance();
+			if (docuImage == null) {
+				throw new ImageOpException("Unable to load DocuImage class!");
+			}
+			//DocuImage docuImage = new JAIDocuImage(util);
+			//DocuImage docuImage = new JIMIDocuImage(util);
+			//DocuImage docuImage = new ImageLoaderDocuImage(util);
+			//DocuImage docuImage = new JAIImageLoaderDocuImage(util);
+
+			/*
+			 *  find the file to load/send
+			 */
 
-    //"big" try for all file/image actions
-    try {
-
-    // DocuImage instance
-    DocuImage docuImage = new JAIDocuImage(util);
-    //DocuImage docuImage = new JIMIDocuImage(util);
-    //DocuImage docuImage = new ImageLoaderDocuImage(util);
-    //DocuImage docuImage = new JAIImageLoaderDocuImage(util);
-
-    /**
-     *  find the file to load/send
-     */
+			// get PathInfo
+			String loadPathName = dlRequest.getFilePath();
+			// if it's zoomed, try hires version (to be optimized...)
+			if ((paramWW < 1f) || (paramWH < 1f)) {
+				preScaledFirst = false;
+			}
+			
+			/*
+			 * check permissions
+			 */
+			if (useAuthentication) {
+				// get a list of required roles (empty if no restrictions)
+				List rolesRequired = authOp.rolesForPath(loadPathName, request);
+				if (rolesRequired != null) {
+					util.dprintln(1, "Role required: " + rolesRequired);
+					util.dprintln(2, "User: " + request.getRemoteUser());
+					// is the current request/user authorized?
+					if (!authOp.isRoleAuthorized(rolesRequired, request)) {
+						// send deny answer and abort
+						util.dprintln(1, "ERROR: access denied!");
+						if (errorMsgHtml) {
+							ServletOps.htmlMessage(
+								"ERROR: Unauthorized access!",
+								response);
+						} else {
+							servletOp.sendFile(
+								new File(dlConfig.getDenyImgFileName()),
+								response);
+						}
+						return;
+					}
+				}
+			}
 
-    String loadPathName = "";
-    // if there's PathInfo, append
-    if (request.getPathInfo() != null) {
-      loadPathName += request.getPathInfo();
-    }
-    // append fn parameter
-    loadPathName += param_fn;
-    // if it's zoomed, try hires version (to be optimized...)
-    if ((param_ww < 1f) || (param_wh < 1f)) {
-      preScaledFirst = false;
-    }
+			// find the file
+			File fileToLoad =
+				fileOp.getFileVariant(
+					dlConfig.getBaseDirs(),
+					loadPathName,
+					dlRequest.getPn(),
+					preScaledFirst);
+
+			util.dprintln(1, "Loading: " + fileToLoad);
 
-    if (useAuthentication) {
-      // check permissions
-      List rolesRequired = authOp.rolesForPath(loadPathName, request);
-      if (rolesRequired != null) {
-        Utils.dprintln(1, "Role required: "+rolesRequired);
-        Utils.dprintln(2, "User: "+request.getRemoteUser());
-        if (! authOp.isRoleAuthorized(rolesRequired, request)) {
-          Utils.dprintln(1, "ERROR: access denied!");
-          if (errorMsgHtml) {
-            servletOp.htmlMessage("ERROR: Unauthorized access!", response);
-          } else {
-            docuImage.sendFile(denyImgFile, response);
-          }
-          return;
-        }
-      }
-    }
+			// get the source image type (if it's known)
+			mimeType = FileOps.mimeForFile(fileToLoad);
+
+			/* if autoScale and not zoomed and source is GIF/PNG 
+			 * then send as is.
+			 */
+			if ((autoScale
+				&& (mimeType == "image/gif" || mimeType == "image/png")
+				&& (paramWW == 1f)
+				&& (paramWH == 1f))
+				|| (autoScale && !(scaleToFit || cropToFit))) {
+
+				util.dprintln(1, "Sending File as is.");
 
-    // find the file
-    File fileToLoad = fileOp.getFileVariant(baseDirs, loadPathName, param_pn, preScaledFirst);
+				servletOp.sendFile(fileToLoad, response);
 
-    Utils.dprintln(1, "Loading: "+fileToLoad);
+				util.dprintln(
+					1,
+					"Done in "
+						+ (System.currentTimeMillis() - startTime)
+						+ "ms");
+				return;
+			}
 
-    // get the source image type (if it's known)
-    mimeType = fileOp.mimeForFile(fileToLoad);
+			// finally load the file
+			docuImage.loadImage(fileToLoad);
 
-    // if not forced and source is GIF/PNG then send-as-is if not zoomed
-    if((!forcedScale && (mimeType == "image/gif" || mimeType == "image/png")
-        && (param_ww == 1f) && (param_wh == 1f)) || (forcedScale && !scaleToFit)) {
-
-      Utils.dprintln(1, "Sending File as is.");
+			/*
+			 *  crop and scale the image
+			 */
 
-      docuImage.sendFile(fileToLoad, response);
+			// get size
+			int imgWidth = docuImage.getWidth();
+			int imgHeight = docuImage.getHeight();
 
-      Utils.dprintln(1, "Done in "+(System.currentTimeMillis()-startTime)+"ms");
-      return;
-    }
+			util.dprintln(2, "IMG: " + imgWidth + "x" + imgHeight);
+			util.dprintln(
+				2,
+				"time " + (System.currentTimeMillis() - startTime) + "ms");
 
-    // load file
-    docuImage.loadImage(fileToLoad);
-
-    /**
-     *  crop and scale the image
-     */
-
-    // get size
-    int imgWidth = docuImage.getWidth();
-    int imgHeight = docuImage.getHeight();
+			// coordinates and scaling
+			float areaXoff;
+			float areaYoff;
+			float areaWidth;
+			float areaHeight;
+			float scaleX;
+			float scaleY;
+			float scaleXY;
 
-    util.dprintln(2, "IMG: "+imgWidth+"x"+imgHeight);
-    util.dprintln(2, "time "+(System.currentTimeMillis()-startTime)+"ms");
-
-    // calculate absolute from relative coordinates
-    float areaXoff = param_wx * imgWidth;
-    float areaYoff = param_wy * imgHeight;
-    float areaWidth = param_ww * imgWidth;
-    float areaHeight = param_wh * imgHeight;
-    // calculate scaling factors
-    float scaleX = param_dw / areaWidth * param_ws;
-    float scaleY = param_dh / areaHeight * param_ws;
-    float scaleXY = (scaleX > scaleY) ? scaleY : scaleX;
+			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);
-
-    // fit area to image
-    areaWidth = (areaXoff + areaWidth > imgWidth) ? imgWidth - areaXoff : areaWidth;
-    areaHeight = (areaYoff + areaHeight > imgHeight) ? imgHeight - areaYoff : areaHeight;
-
-    util.dprintln(2, "cropped: "+areaXoff+","+areaYoff+" "+areaWidth+"x"+areaHeight);
+			util.dprintln(
+				1,
+				"Scale "
+					+ scaleXY
+					+ "("
+					+ scaleX
+					+ ","
+					+ scaleY
+					+ ") on "
+					+ areaXoff
+					+ ","
+					+ areaYoff
+					+ " "
+					+ areaWidth
+					+ "x"
+					+ areaHeight);
 
-    // check image parameters
-    if ((areaWidth < 1)||(areaHeight < 1)
-       ||(scaleXY * areaWidth < 2)||(scaleXY * areaHeight < 2)) {
-      Utils.dprintln(1, "ERROR: invalid scale parameter set!");
-      throw new ImageOpException("Invalid scale parameter set!");
-    }
-
-    // crop and scale image
-    docuImage.cropAndScale((int)areaXoff, (int)areaYoff, (int)areaWidth, (int)areaHeight,
-                            scaleXY, scaleQual);
+			// clip area at the image border
+			areaWidth =
+				(areaXoff + areaWidth > imgWidth)
+					? imgWidth - areaXoff
+					: areaWidth;
+			areaHeight =
+				(areaYoff + areaHeight > imgHeight)
+					? imgHeight - areaYoff
+					: areaHeight;
 
-    util.dprintln(2, "time "+(System.currentTimeMillis()-startTime)+"ms");
+			util.dprintln(
+				2,
+				"cropped: "
+					+ areaXoff
+					+ ","
+					+ areaYoff
+					+ " "
+					+ areaWidth
+					+ "x"
+					+ areaHeight);
 
-    /**
-     *  write the resulting image
-     */
+			// check image parameters sanity
+			if ((areaWidth < 1)
+				|| (areaHeight < 1)
+				|| (scaleXY * areaWidth < 2)
+				|| (scaleXY * areaHeight < 2)) {
+				util.dprintln(1, "ERROR: invalid scale parameter set!");
+				throw new ImageOpException("Invalid scale parameter set!");
+			}
 
-    // setup output -- if source is JPG then dest will be JPG else it's PNG
-    if (mimeType != "image/jpeg") {
-      mimeType="image/png";
-    }
+			// crop and scale image
+			docuImage.cropAndScale(
+				(int) areaXoff,
+				(int) areaYoff,
+				(int) areaWidth,
+				(int) areaHeight,
+				scaleXY,
+				scaleQual);
 
-    // write the image
-    docuImage.writeImage(mimeType, response);
+			util.dprintln(
+				2,
+				"time " + (System.currentTimeMillis() - startTime) + "ms");
+
+			/*
+			 *  write the resulting image
+			 */
 
-    util.dprintln(1, "Done in "+(System.currentTimeMillis()-startTime)+"ms");
+			// setup output -- if source is JPG then dest will be JPG else it's PNG
+			if (mimeType != "image/jpeg") {
+				mimeType = "image/png";
+			}
 
-    /**
-     *  error handling
-     */
+			// write the image
+			docuImage.writeImage(mimeType, response);
 
-    }//"big" try
-    catch (FileOpException e) {
-      util.dprintln(1, "ERROR: File IO Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: File IO Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (AuthOpException e) {
-      Utils.dprintln(1, "ERROR: Authorization error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Authorization error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (ImageOpException e) {
-      Utils.dprintln(1, "ERROR: Image Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Image Operation Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
-    catch (RuntimeException e) {
-      Utils.dprintln(1, "ERROR: Any other Error: "+e);
-      try {
-        if (errorMsgHtml) {
-          servletOp.htmlMessage("ERROR: Other Error: "+e, response);
-        } else {
-          globalImage.sendFile(errorImgFile, response);
-        }
-      } catch (FileOpException ex) {} // so we don't get a loop
-      return;
-    }
+			util.dprintln(
+				1,
+				"Done in " + (System.currentTimeMillis() - startTime) + "ms");
+
+			/*
+			 *  error handling
+			 */
 
-  }
+		} // end of "big" try
+		catch (FileOpException e) {
+			util.dprintln(1, "ERROR: File IO Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: File IO Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (AuthOpException e) {
+			util.dprintln(1, "ERROR: Authorization error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Authorization error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (ImageOpException e) {
+			util.dprintln(1, "ERROR: Image Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Image Operation Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		} catch (RuntimeException e) {
+			// JAI likes to throw RuntimeExceptions ;-(
+			util.dprintln(1, "ERROR: Other Image Error: " + e);
+			try {
+				if (errorMsgHtml) {
+					ServletOps.htmlMessage(
+						"ERROR: Other Image Operation Error: " + e,
+						response);
+				} else {
+					servletOp.sendFile(
+						new File(dlConfig.getErrorImgFileName()),
+						response);
+				}
+			} catch (FileOpException ex) {
+			} // so we don't get a loop
+			return;
+		}
+	}
 
-}//Scaler class
+} //Scaler class