changeset 1198:569b6a1ab1a6

working on IIIF api.
author robcast
date Wed, 17 Jul 2013 18:14:31 +0200
parents e7608a7205e1
children 22b8e36fcb89
files common/src/main/java/digilib/conf/DigilibRequest.java common/src/main/java/digilib/image/ImageJobDescription.java common/src/main/java/digilib/image/ImageWorker.java servlet/src/main/java/digilib/servlet/ServletOps.java servlet3/src/main/java/digilib/servlet/Scaler.java
diffstat 5 files changed, 110 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/common/src/main/java/digilib/conf/DigilibRequest.java	Wed Jul 17 12:58:03 2013 +0200
+++ b/common/src/main/java/digilib/conf/DigilibRequest.java	Wed Jul 17 18:14:31 2013 +0200
@@ -261,6 +261,8 @@
     /**
      * Populate a request from a string with an IIIF Image API path.
      * 
+     * path should have no leading slash.
+     * 
      * @param path
      *            String with IIIF Image API path.
      * 
@@ -271,7 +273,9 @@
         if (path == null) {
             return;
         }
-        // enable the passing of delimiter to get empty parameters
+        // alway set HTTP status code error reporting
+        options.setOption("errcode");
+        // enable passing of delimiter to get empty parameters
         StringTokenizer query = new StringTokenizer(path, "/", true);
         String token;
         // first parameter prefix
@@ -305,22 +309,26 @@
         if (query.hasMoreTokens()) {
             token = query.nextToken();
             if (!token.equals("/")) {
-                if (token.equals("full")) {
+                if (token.equals("info.json")) {
+                    // info request
+                    options.setOption("info");
+                    return;
+                } else if (token.equals("full")) {
                     // full region -- default
                 } else if (token.startsWith("pct:")){
                     // region in % of original image
-                    String[] params = token.substring(4).split(",");
+                    String[] parms = token.substring(4).split(",");
                     try {
-                        float x = Float.parseFloat(params[0]);
+                        float x = Float.parseFloat(parms[0]);
                         setValue("wx", x / 100f);
-                        float y = Float.parseFloat(params[1]);
+                        float y = Float.parseFloat(parms[1]);
                         setValue("wy", y / 100f);
-                        float w = Float.parseFloat(params[2]);
+                        float w = Float.parseFloat(parms[2]);
                         setValue("ww", w / 100f);
-                        float h = Float.parseFloat(params[3]);
+                        float h = Float.parseFloat(parms[3]);
                         setValue("wh", h / 100f);
                     } catch (Exception e) {
-                        logger.error("Error parsing range parameter in IIIF path!");
+                        logger.error("Error parsing range parameter in IIIF path!", e);
                     }
                 } else {
                     // region in pixel of original image :-(
@@ -331,23 +339,48 @@
                     query.nextToken();
                 }
             }
+        } else {
+            // region omitted -- assume info request
+            options.setOption("info");
+            return;
         }
         // fourth parameter size
         if (query.hasMoreTokens()) {
             token = query.nextToken();
             if (!token.equals("/")) {
                 if (token.equals("full")) {
-                    // full: size of original
+                    // full -- size of original
                     options.setOption("ascale");
                     setValue("scale", 1f);
                 } else if (token.startsWith("pct:")){
-                    // pct:n n% size of original
+                    // pct:n -- n% size of original
                     try {
                         float pct = Float.parseFloat(token.substring(4));
                         options.setOption("ascale");
                         setValue("scale", pct / 100);
                     } catch (NumberFormatException e) {
-                        logger.error("Error parsing size parameter in IIIF path!");
+                        logger.error("Error parsing size parameter in IIIF path!", e);
+                    }
+                } else {
+                    // w,h -- pixel size
+                    try {
+                        String[] parms = token.split(",");
+                        if (parms[0] != "") {
+                            // width param
+                            if (parms[0].startsWith("!")) {
+                                // width (in digilib-like bounding box)
+                                setValueFromString("dw", parms[0].substring(1));
+                            } else {
+                                // according to spec, we should distort the image to match ;-(
+                                setValueFromString("dw", parms[0]);                            
+                            }
+                        }
+                        if (parms[1] != "") {
+                            // height param (according to spec, we should distort the image to match ;-()
+                            setValueFromString("dh", parms[1]);
+                        }
+                    } catch (Exception e) {
+                        logger.error("Error parsing size parameter in IIIF path!", e);
                     }
                 }
                 // skip /
@@ -355,6 +388,11 @@
                     query.nextToken();
                 }
             }
+        } else {
+            // size omitted -- assume "full"
+            options.setOption("ascale");
+            setValue("scale", 1f);
+            return;
         }
         // fifth parameter rotation
         if (query.hasMoreTokens()) {
@@ -370,13 +408,23 @@
         // sixth parameter quality.format
         if (query.hasMoreTokens()) {
             token = query.nextToken();
-            if (!token.equals("/")) {
-                // TODO
-                setValueFromString("wx", token);
-                // skip /
-                if (query.hasMoreTokens()) {
-                    query.nextToken();
+            // quality.format -- color depth and output format
+            try {
+                String[] parms = token.split("\\.");
+                // quality param (native is default anyway)
+                if (parms[0].equals("grey")) {
+                    setValueFromString("colop", "grayscale");
                 }
+                // format param (we only support jpg and png)
+                if (parms[1].equals("jpg")) {
+                    // force jpg
+                    options.setOption("jpg");
+                } else if (parms[1].equals("png")) {
+                    // force png
+                    options.setOption("png");
+                }
+            } catch (Exception e) {
+                logger.error("Error parsing quality and format parameters in IIIF path!", e);
             }
         }
     }
--- a/common/src/main/java/digilib/image/ImageJobDescription.java	Wed Jul 17 12:58:03 2013 +0200
+++ b/common/src/main/java/digilib/image/ImageJobDescription.java	Wed Jul 17 18:14:31 2013 +0200
@@ -388,7 +388,13 @@
 					// currently only same scale -- mean value
 					scaleXY = (sx + sy) / 2f;
 				} else {
+				    // absolute scale factor
 					scaleXY = getAsFloat("scale");
+					// use original size if no destination size given
+					if (getDw() == 0 && getDh() == 0) {
+					    paramDW = (int) userImgArea.getWidth();
+                        paramDH = (int) userImgArea.getHeight();
+					}
 				}
 				// we need to correct the factor if we use a pre-scaled image
 				ImageSize hiresSize = getHiresSize();
@@ -585,7 +591,7 @@
                             || mimeType.equals("image/gif"))
                     && !(hasOption("hmir")
                     || hasOption("vmir") || (getAsFloat("rot") != 0.0)
-                    || (getRGBM() != null) || (getRGBA() != null)
+                    || (getRGBM() != null) || (getRGBA() != null) || (this.getColOp() != null)
                     || (getAsFloat("cont") != 0.0) || (getAsFloat("brgt") != 0.0)));
         }
         return imageSendable;
--- a/common/src/main/java/digilib/image/ImageWorker.java	Wed Jul 17 12:58:03 2013 +0200
+++ b/common/src/main/java/digilib/image/ImageWorker.java	Wed Jul 17 18:14:31 2013 +0200
@@ -63,7 +63,7 @@
         logger.debug("ImageWorker starting");
         long startTime = System.currentTimeMillis();
         if (stopNow) {
-            logger.debug("ImageWorker stopping (at the start)");
+            logger.debug("ImageWorker stopping (at the beginning)");
             return null;
         }
 
@@ -71,7 +71,7 @@
         if (docuImage == null) {
             docuImage = DocuImageFactory.getInstance();
             if (docuImage == null) {
-                throw new ImageOpException("Unable to load DocuImage class!");
+                throw new ImageOpException("Unable to get DocuImage instance!");
             }
         }
 
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java	Wed Jul 17 12:58:03 2013 +0200
+++ b/servlet/src/main/java/digilib/servlet/ServletOps.java	Wed Jul 17 18:14:31 2013 +0200
@@ -38,12 +38,17 @@
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpUtils;
 
 import org.apache.log4j.Logger;
 
+import digilib.conf.DigilibServletRequest;
 import digilib.image.DocuImage;
 import digilib.image.ImageOpException;
 import digilib.io.FileOps;
+import digilib.io.ImageInput;
+import digilib.io.ImageSet;
+import digilib.util.ImageSize;
 
 public class ServletOps {
 
@@ -343,6 +348,36 @@
         // TODO: should we: finally { img.dispose(); }
     }
 
+
+    public static void sendInfo(DigilibServletRequest dlReq, HttpServletResponse response, Logger logger) throws ImageOpException,
+            ServletException {
+        if (response == null) {
+            logger.error("No response!");
+            return;
+        }
+        try {
+            // get original image size
+            ImageInput img = dlReq.getJobDescription().getImageSet().getBiggest();
+            ImageSize size = img.getSize();
+            StringBuffer url = dlReq.getServletRequest().getRequestURL();
+            PrintWriter writer = response.getWriter();
+            response.setContentType("application/json");
+            writer.println("{");
+            writer.println("\"@context\" : \"http://library.stanford.edu/iiif/image-api/1.1/context.json\",");
+            writer.println("\"@id\" : \""+url+"\",");
+            writer.println("\"width\" : \""+size.width+"\",");
+            writer.println("\"height\" : \""+size.height+"\",");
+            writer.println("\"formats\" : [\"jpg\", \"png\"],");
+            writer.println("\"qualities\" : [\"native\", \"color\", \"grey\"],");
+            writer.println("\"profile\" : \"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2\",");
+            writer.println("}");
+        } catch (IOException e) {
+            throw new ServletException("Error sending image:", e);
+        }
+        // TODO: should we: finally { img.dispose(); }
+    }
+
+
     /** Returns text representation of headers for debuggging purposes.
      * @param req
      * @return
--- a/servlet3/src/main/java/digilib/servlet/Scaler.java	Wed Jul 17 12:58:03 2013 +0200
+++ b/servlet3/src/main/java/digilib/servlet/Scaler.java	Wed Jul 17 18:14:31 2013 +0200
@@ -274,8 +274,7 @@
                 return;
             }
 
-            // if possible, send the image without actually having to transform
-            // it
+            // if possible, send the image without actually having to transform it
             if (!jobTicket.isTransformRequired()) {
                 logger.debug("Sending File as is.");
                 ServletOps.sendFile(fileToLoad.getFile(), null, null, response, logger);