# HG changeset patch
# User robcast
# Date 1447336816 -3600
# Node ID f0947c6190e6eac837580eda36fcb10bb54b0de7
# Parent fa63f437d5c5d8c92a0a3df575cc63b71039f6d7
IIIF Image API 2.0 support.
diff -r fa63f437d5c5 -r f0947c6190e6 common/src/main/java/digilib/conf/DigilibConfiguration.java
--- a/common/src/main/java/digilib/conf/DigilibConfiguration.java Thu Nov 12 12:02:14 2015 +0100
+++ b/common/src/main/java/digilib/conf/DigilibConfiguration.java Thu Nov 12 15:00:16 2015 +0100
@@ -57,7 +57,7 @@
/** digilib version */
public static String getClassVersion() {
- return "2.3.5a";
+ return "2.3.6a";
}
/* non-static getVersion for Java inheritance */
@@ -94,6 +94,8 @@
newParameter("default-errmsg-type", "image", null, 'f');
// prefix for IIIF image API paths (used by DigilibRequest)
newParameter("iiif-prefix", "IIIF", null, 'f');
+ // IIIF Image API version to support (mostly relevant for info.json)
+ newParameter("iiif-api-version", "2.0", null, 'f');
// character to use as slash-replacement in IIIF identifier part
newParameter("iiif-slash-replacement", "!", null, 'f');
}
diff -r fa63f437d5c5 -r f0947c6190e6 common/src/main/java/digilib/conf/DigilibRequest.java
--- a/common/src/main/java/digilib/conf/DigilibRequest.java Thu Nov 12 12:02:14 2015 +0100
+++ b/common/src/main/java/digilib/conf/DigilibRequest.java Thu Nov 12 15:00:16 2015 +0100
@@ -278,11 +278,13 @@
*
* path should be non-URL-decoded and have no leading slash.
*
+ * URI template:
+ * {scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
+ *
* @param path
* String with IIIF Image API path.
*
- * @see IIIF Image
- * API
+ * @see IIIF Image API
*/
public boolean setWithIiifPath(String path) {
if (path == null) {
@@ -315,7 +317,7 @@
}
}
/*
- * second parameter FN (encoded)
+ * second parameter identifier (encoded)
*/
if (query.hasMoreTokens()) {
token = getNextDecodedToken(query);
@@ -404,11 +406,16 @@
/**
* Populate a request from IIIF image API parameters.
- *
- * {scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}{.format}
+ *
+ * @see IIIF Image API
*
- * @see IIIF Image
- * API
+ * @param identifier
+ * @param region
+ * @param size
+ * @param rotation
+ * @param quality
+ * @param format
+ * @return
*/
public boolean setWithIiifParams(String identifier, String region, String size,
String rotation, String quality, String format) {
@@ -449,7 +456,7 @@
options.setOption("info");
return true;
} else if (region.equals("full")) {
- // full region -- default
+ // full image -- default
} else if (region.startsWith("pct:")) {
// pct:x,y,w,h -- region in % of original image
String[] parms = region.substring(4).split(",");
@@ -483,8 +490,8 @@
}
}
} else {
- // region omitted -- assume info request
- options.setOption("info");
+ // region omitted -- redirect to info request
+ options.setOption("redirect-info");
return true;
}
@@ -493,11 +500,16 @@
*/
if (size != null) {
if (size.equals("full")) {
- // full -- size of original
+ /*
+ * full -- size of original
+ */
options.setOption("ascale");
setValue("scale", 1f);
+
} else if (size.startsWith("pct:")) {
- // pct:n -- n% size of original
+ /*
+ * pct:n -- n% size of original
+ */
try {
float pct = Float.parseFloat(size.substring(4));
options.setOption("ascale");
@@ -507,17 +519,20 @@
logger.error(errorMessage+e);
return false;
}
+
} else {
- // w,h -- pixel size
+ /*
+ * w,h -- pixel size
+ */
try {
String[] parms = size.split(",", 2);
if (parms[0].length() > 0) {
// width param
if (parms[0].startsWith("!")) {
- // width (in digilib-like bounding box)
+ // !w,h width (in digilib-like bounding box)
setValueFromString("dw", parms[0].substring(1));
} else if (parms[1].length() == 0) {
- // width only
+ // w, width only
setValueFromString("dw", parms[0]);
} else {
// w,h -- according to spec, we should distort the image to match ;-(
@@ -546,6 +561,11 @@
* parameter rotation
*/
if (rotation != null) {
+ if (rotation.startsWith("!")) {
+ // !n -- mirror and rotate
+ options.setOption("hmir");
+ rotation = rotation.substring(1);
+ }
try {
float rot = Float.parseFloat(rotation);
setValue("rot", rot);
@@ -561,9 +581,9 @@
*/
if (quality != null) {
// quality param
- if (quality.equals("native") || quality.equals("color")) {
- // native is default anyway
- } else if (quality.equals("grey")) {
+ if (quality.equals("default") || quality.equals("native") || quality.equals("color")) {
+ // color is default anyway
+ } else if (quality.equals("gray") || quality.equals("grey")) {
setValueFromString("colop", "grayscale");
} else {
errorMessage = "Invalid quality parameter in IIIF path!";
diff -r fa63f437d5c5 -r f0947c6190e6 servlet/src/main/java/digilib/servlet/ServletOps.java
--- a/servlet/src/main/java/digilib/servlet/ServletOps.java Thu Nov 12 12:02:14 2015 +0100
+++ b/servlet/src/main/java/digilib/servlet/ServletOps.java Thu Nov 12 15:00:16 2015 +0100
@@ -412,20 +412,53 @@
* send response
*/
response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json,application/ld+json");
- PrintWriter writer;
logger.debug("sending info.json");
try {
- writer = response.getWriter();
- 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("}");
+ PrintWriter writer;
+ if (dlReq.getDigilibConfig().getAsString("iiif-api-version").startsWith("2.")) {
+ /*
+ * IIIF Image API version 2 image information
+ */
+ // use JSON-LD content type only when asked
+ String accept = dlReq.getServletRequest().getHeader("Accept");
+ if (accept != null && accept.contains("application/ld+json")) {
+ response.setContentType("application/ld+json");
+ } else {
+ response.setContentType("application/json");
+ response.setHeader("Link", ""
+ +"; rel=\"http://www.w3.org/ns/json-ld#context\""
+ +"; type=\"application/ld+json\"");
+ }
+ writer = response.getWriter();
+ writer.println("{");
+ writer.println("\"@context\" : \"http://iiif.io/api/image/2/context.json\",");
+ writer.println("\"@id\" : \"" + url + "\",");
+ writer.println("\"@protocol\" : \"http://iiif.io/api/image\",");
+ writer.println("\"width\" : " + size.width + ",");
+ writer.println("\"height\" : " + size.height + ",");
+ writer.println("\"profile\" : [");
+ writer.println("\"http://iiif.io/api/image/2/level2.json\",");
+ writer.println("{");
+ writer.println("\"formats\" : [\"jpg\", \"png\"],");
+ writer.println("\"qualities\" : [\"color\", \"grey\"],");
+ writer.println("\"supports\" : [\"mirroring\", \"rotationArbitrary\", \"sizeAboveFull\"],");
+ writer.println("}]");
+ } else {
+ /*
+ * IIIF Image API version 1 image information
+ */
+ response.setContentType("application/json,application/ld+json");
+ writer = response.getWriter();
+ 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("Unable to write response!", e);
}
diff -r fa63f437d5c5 -r f0947c6190e6 servlet3/src/main/java/digilib/servlet/Scaler.java
--- a/servlet3/src/main/java/digilib/servlet/Scaler.java Thu Nov 12 12:02:14 2015 +0100
+++ b/servlet3/src/main/java/digilib/servlet/Scaler.java Thu Nov 12 15:00:16 2015 +0100
@@ -252,11 +252,16 @@
// extract the job information
final ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig);
- // handle the info-request
+ // handle the IIIF info-request
if (dlRequest.hasOption("info")) {
ServletOps.sendIiifInfo(dlRequest, response, logger);
return;
}
+ if (dlRequest.hasOption("redirect-info")) {
+ // TODO: the redirect should have code 303
+ response.sendRedirect("info.json");
+ return;
+ }
// error out if request was bad
if (dlRequest.errorMessage != null) {