# HG changeset patch # User robcast # Date 1057096938 -7200 # Node ID c36944be0b58bddadc1cb868701b6e6449e541c5 # Parent ed7c1e4dd1773d7d2d441f150396b737e9ed3ea2 Servlet Version 1.11a1with original size(!) - new meta data file loader - new parameter ddpi, ddpix, ddpiy (client->servlet) - new parameter mo=osize - osize scales based on ddpi and original dpi (currently only equally for x and y) diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/io/DocuDirectory.java --- a/servlet/src/digilib/io/DocuDirectory.java Mon Jun 30 17:25:43 2003 +0200 +++ b/servlet/src/digilib/io/DocuDirectory.java Wed Jul 02 00:02:18 2003 +0200 @@ -22,17 +22,20 @@ package digilib.io; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; +import org.xml.sax.SAXException; + /** * @author casties */ public class DocuDirectory { - // list of files + // list of files (DocuFileSet) private ArrayList list = null; // directory object is valid (has been read) private boolean isValid = false; @@ -85,7 +88,7 @@ /** Read the directory and fill this object. * - * Clears the Vector and (re)reads all files. + * Clears the List and (re)reads all files. * * @return boolean the directory exists */ @@ -172,6 +175,8 @@ } dirMTime = dir.lastModified(); isValid = true; + // read metadata as well + readMeta(); } return isValid; @@ -197,6 +202,38 @@ */ public void readMeta() { // check for directory metadata... + File mf = new File(dir, "index.meta"); + if (mf.canRead()) { + XMLMetaLoader ml = new XMLMetaLoader(); + try { + // read directory meta file + HashMap fileMeta = ml.loadURL(mf.getAbsolutePath()); + if (fileMeta == null) { + return; + } + // meta for the directory itself is in the "" bin + dirMeta = (HashMap)fileMeta.remove(""); + // is there meta for other files? + if (fileMeta.size() > 0) { + // iterate through the list of files + for (Iterator i = list.iterator(); i.hasNext();) { + DocuFileset df = (DocuFileset)i.next(); + // look up meta for this file + HashMap meta = (HashMap)fileMeta.get(df.getName()); + if (meta != null) { + df.setFileMeta(meta); + } + } + } + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } } /** Update access time. diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/io/DocuFile.java --- a/servlet/src/digilib/io/DocuFile.java Mon Jun 30 17:25:43 2003 +0200 +++ b/servlet/src/digilib/io/DocuFile.java Wed Jul 02 00:02:18 2003 +0200 @@ -47,6 +47,10 @@ file = f; } + /** Returns the file name (without path). + * + * @return + */ public String getName() { if (file != null) { return file.getName(); @@ -55,6 +59,10 @@ } + /** Checks the file using the provided DocuInfo instance. + * + * @param info + */ public void check(DocuInfo info) { try { info.checkFile(this); diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/io/DocuFileset.java --- a/servlet/src/digilib/io/DocuFileset.java Mon Jun 30 17:25:43 2003 +0200 +++ b/servlet/src/digilib/io/DocuFileset.java Wed Jul 02 00:02:18 2003 +0200 @@ -20,6 +20,7 @@ package digilib.io; import java.awt.Dimension; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -32,13 +33,19 @@ */ public class DocuFileset { - // list of files + // list of files (DocuFile) private ArrayList list = null; // metadata private HashMap fileMeta = null; + // metadata has been checked + private boolean metaChecked = false; + // resolution (DPI) + private double resX = 0; + private double resY = 0; // parent directory private DocuDirectory parent = null; + /* * constructors */ @@ -153,13 +160,97 @@ } /** Reads meta-data for this Fileset if there is any. - * (not yet implemented) + * + */ + public void readMeta() { + if ((fileMeta != null) || list.isEmpty()) { + // there is already metadata or there's no file + return; + } + // metadata is in the file {filename}.meta + String fn = ((DocuFile) list.get(0)).getFile().getAbsolutePath(); + File mf = new File(fn + ".meta"); + if (mf.canRead()) { + XMLMetaLoader ml = new XMLMetaLoader(); + try { + // read meta file + HashMap meta = ml.loadURL(mf.getAbsolutePath()); + if (meta == null) { + return; + } + fileMeta = (HashMap) meta.get(getName()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /** Checks metadata and sets resolution in resX and resY. + * */ public void checkMeta() { - // check for file metadata... + if (metaChecked) { + return; + } + if (fileMeta == null) { + // try to read meta-data file + readMeta(); + if (fileMeta == null) { + // there is no meta data + metaChecked = true; + return; + } + } + metaChecked = true; + double dpi = 0; + double dpix = 0; + double dpiy = 0; + double sizex = 0; + double sizey = 0; + double pixx = 0; + double pixy = 0; + // DPI is valid for X and Y + try { + dpi = Double.parseDouble((String) fileMeta.get("dpi")); + } catch (NumberFormatException e) { + } + if (dpi != 0) { + resX = dpi; + resY = dpi; + return; + } + // DPI-X and DPI-Y + try { + dpix = Double.parseDouble((String) fileMeta.get("dpi-x")); + dpiy = Double.parseDouble((String) fileMeta.get("dpi-y")); + } catch (NumberFormatException e) { + } + if ((dpix != 0) && (dpiy != 0)) { + resX = dpix; + resY = dpiy; + return; + } + // SIZE-X and SIZE-Y and PIXEL-X and PIXEL-Y + try { + sizex = + Double.parseDouble((String) fileMeta.get("original-size-x")); + sizey = + Double.parseDouble((String) fileMeta.get("original-size-y")); + pixx = + Double.parseDouble((String) fileMeta.get("original-pixel-x")); + pixy = + Double.parseDouble((String) fileMeta.get("original-pixel-y")); + } catch (NumberFormatException e) { + } + if ((sizex != 0) && (sizey != 0) && (pixx != 0) && (pixy != 0)) { + resX = pixx / (sizex * 100 / 2.54); + resY = pixy / (sizey * 100 / 2.54); + return; + } } - /** The name of the (original) image file. + /** The name of the (hires) image file. * * @return */ @@ -171,6 +262,7 @@ } /** Returns the parent DocuDirectory. + * * @return DocuDirectory */ public DocuDirectory getParent() { @@ -201,4 +293,25 @@ this.fileMeta = fileMeta; } + /** + * @return + */ + public boolean isMetaChecked() { + return metaChecked; + } + + /** + * @return + */ + public double getResX() { + return resX; + } + + /** + * @return + */ + public double getResY() { + return resY; + } + } diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/io/XMLMetaLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/io/XMLMetaLoader.java Wed Jul 02 00:02:18 2003 +0200 @@ -0,0 +1,198 @@ +/* XMLMetaLoader -- Load an XML format metadata into a Hashtable + + Digital Image Library servlet components + + Copyright (C) 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 + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + Please read license.txt for the full details. A copy of the GPL + may be found at http://www.gnu.org/copyleft/lgpl.html + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +package digilib.io; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public class XMLMetaLoader { + + private String outerTag = "resource"; + private String metaTag = "meta"; + private String fileTag = "file"; + private String fileNameTag = "name"; + private String filePathTag = "path"; + private String infoTag = "img"; + + public XMLMetaLoader() { + } + + /** + * inner class XMLMetaParser to be called by the parser + */ + private class XMLMetaParser extends DefaultHandler { + + private LinkedList tags; + private HashMap files; + private HashMap meta; + private StringBuffer content; + private String fileName; + private String filePath; + + // public HashMap getData() { + // return meta; + // } + + // Parser calls this once at the beginning of a document + public void startDocument() throws SAXException { + tags = new LinkedList(); + files = new HashMap(); + } + + // Parser calls this for each element in a document + public void startElement( + String namespaceURI, + String localName, + String qName, + Attributes atts) + throws SAXException { + + String name = (localName != null) ? localName : qName; + // open a new tag + tags.addLast(name); + // start new content (no nesting of tags and content) + content = new StringBuffer(); + + if (name.equals(metaTag)) { + // new meta tag + meta = new HashMap(); + } else if (name.equals(fileTag)) { + // new file tag + fileName = null; + filePath = null; + } + } + + // parser calls this for all tag content (possibly more than once) + public void characters(char[] ch, int start, int length) + throws SAXException { + // append data to current string buffer + content.append(ch, start, length); + } + + // parser calls this at the end of each element + public void endElement( + String namespaceURI, + String localName, + String qName) + throws SAXException { + + String name = (localName != null) ? localName : qName; + // exit the tag + tags.removeLast(); + + // was it a file.name tag? + if (name.equals(fileNameTag) && tags.contains(fileTag)) { + // save name as filename + if ((content != null)&&(content.length() > 0)) { + fileName = content.toString(); + } + return; + } + + // was it a file.path tag? + if (name.equals(filePathTag) && tags.contains(fileTag)) { + // save path as filepath + if ((content != null)&&(content.length() > 0)) { + filePath = content.toString(); + } + return; + } + + // was it a file tag? + if (name.equals(fileTag)) { + // is there meta to save? + if ((meta != null)&&(meta.size() > 0)) { + // file name is either file.path or file.name + String fn = null; + if (filePath != null) { + fn = filePath; + } else if (fileName != null) { + fn = fileName; + } else { + // no file name, no file + return; + } + // save meta in file list + files.put(fn, meta); + } + return; + } + + // was it a meta tag outside a file tag? + if (name.equals(metaTag) && !tags.contains(fileTag)) { + // save meta as dir meta + if ((meta != null)&&(meta.size() > 0)) { + files.put("", meta); + } + return; + } + + // is this inside an info tag? + if (tags.contains(infoTag)) { + // then add whatever this is + if ((content != null)&&(content.length() > 0)) { + meta.put(name, content.toString()); + } + } + + } + + } + + /** + * load and parse a file (as URL) + * returns HashMap with list data + */ + public HashMap loadURL(String path) throws SAXException, IOException { + //System.out.println("loadurl ("+path+")"); + // Create a JAXP SAXParserFactory and configure it + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + + SAXParser parser = null; + try { + // Create a JAXP SAXParser + parser = spf.newSAXParser(); + + } catch (ParserConfigurationException e) { + throw new SAXException(e); + } + + // create a list parser (keeps the data!) + XMLMetaParser listParser = new XMLMetaParser(); + + // Tell the SAXParser to parse the XML document + parser.parse(path, listParser); + + return listParser.files; + } + +} diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/servlet/DigilibRequest.java --- a/servlet/src/digilib/servlet/DigilibRequest.java Mon Jun 30 17:25:43 2003 +0200 +++ b/servlet/src/digilib/servlet/DigilibRequest.java Wed Jul 02 00:02:18 2003 +0200 @@ -26,15 +26,17 @@ package digilib.servlet; -import java.io.*; -import java.util.*; +import java.io.File; +import java.io.StringReader; +import java.util.Hashtable; +import java.util.StringTokenizer; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; +import com.hp.hpl.mesa.rdf.jena.common.SelectorImpl; import com.hp.hpl.mesa.rdf.jena.mem.ModelMem; import com.hp.hpl.mesa.rdf.jena.model.*; -import com.hp.hpl.mesa.rdf.jena.common.*; import digilib.image.DocuImage; @@ -91,6 +93,18 @@ // 2 = in frameset, 3 = XUL-'frameset' // 4 = XUL-Sidebar ) private String lv_s; + private float odpi; // resolution of original image + private String odpi_s; + private float ddpi; // resolution of original image + private String ddpi_s; + private float odpix; // x resolution of original image + private String odpix_s; + private float odpiy; // y resolution of original image + private String odpiy_s; + private float ddpix; // x resolution of destination image + private String ddpix_s; + private float ddpiy; // y resolution of destination image + private String ddpiy_s; private DocuImage image; // internal DocuImage instance for this request private ServletRequest servletRequest; // internal ServletRequest @@ -344,6 +358,15 @@ if (lv_s != null) { s += "&lv=" + lv_s; } + if (ddpi_s != null) { + s += "&ddpi=" + ddpi; + } + if (ddpix_s != null) { + s += "&ddpix=" + ddpix; + } + if (ddpiy_s != null) { + s += "&ddpiy=" + ddpiy; + } return s; } @@ -446,6 +469,18 @@ if (s != null) { setLv(s); } + s = request.getParameter("ddpi"); + if (s != null) { + setDdpi(s); + } + s = request.getParameter("ddpix"); + if (s != null) { + setDdpix(s); + } + s = request.getParameter("ddpiy"); + if (s != null) { + setDdpiy(s); + } s = ((HttpServletRequest) request).getPathInfo(); if (s != null) { setRequestPath(s); @@ -532,10 +567,22 @@ if (s != null) { setPt(s); } - s = (String)hashRDF.get("lv"); - if (s != null) { + s = (String)hashRDF.get("lv"); + if (s != null) { setLv(s); - } + } + s = (String)hashRDF.get("ddpi"); + if (s != null) { + setDdpi(s); + } + s = (String)hashRDF.get("ddpix"); + if (s != null) { + setDdpix(s); + } + s = (String)hashRDF.get("ddpiy"); + if (s != null) { + setDdpiy(s); + } s = ((HttpServletRequest) request).getPathInfo(); if (s != null) { setRequestPath(s); @@ -629,6 +676,18 @@ rgbm_s = null; rgba = null; rgba_s = null; + ddpi = 0; + ddpi_s = null; + ddpix = 0; + ddpix_s = null; + ddpiy = 0; + ddpiy_s = null; + odpi = 0; + odpi_s = null; + odpix = 0; + odpix_s = null; + odpiy = 0; + odpiy_s = null; baseURL = null; image = null; servletRequest = null; @@ -707,8 +766,6 @@ /* Property getter and setter */ -// lugi - begin - /** Getter for property lv. * @return Value of property lv. * @@ -735,8 +792,6 @@ } } -// lugi - end - /** Getter for property dh. * @return Value of property dh. * @@ -1258,6 +1313,163 @@ } } + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getDdpi() { + return ddpi; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setDdpi(float ddpi) { + this.ddpi = ddpi; + ddpi_s = Float.toString(ddpi); + } + public void setDdpi(String ddpi) { + try { + float f = Float.parseFloat(ddpi); + this.ddpi = f; + this.ddpi_s = ddpi; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getDdpix() { + return ddpix; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setDdpix(float ddpix) { + this.ddpix = ddpix; + ddpix_s = Float.toString(ddpix); + } + public void setDdpix(String s) { + try { + float f = Float.parseFloat(s); + this.ddpix = f; + this.ddpix_s = s; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getDdpiy() { + return ddpiy; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setDdpiy(float f) { + this.ddpiy = f; + ddpiy_s = Float.toString(f); + } + public void setDdpiy(String s) { + try { + float f = Float.parseFloat(s); + this.ddpiy = f; + this.ddpiy_s = s; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getOdpi() { + return odpi; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setOdpi(float f) { + this.odpi = f; + odpi_s = Float.toString(f); + } + public void setOdpi(String s) { + try { + float f = Float.parseFloat(s); + this.odpi = f; + this.odpi_s = s; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getOdpix() { + return odpix; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setOdpix(float f) { + this.odpix = f; + odpix_s = Float.toString(f); + } + public void setOdpix(String s) { + try { + float f = Float.parseFloat(s); + this.odpix = f; + this.odpix_s = s; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + /** Getter for property ddpi. + * @return Value of property ddpi. + * + */ + public float getOdpiy() { + return odpiy; + } + + /** Setter for property ddpi. + * @param ddpi New value of property ddpi. + * + */ + public void setOdpiy(float f) { + this.odpiy = f; + odpiy_s = Float.toString(f); + } + public void setOdpiy(String s) { + try { + float f = Float.parseFloat(s); + this.odpiy = f; + this.odpiy_s = s; + } catch (Exception e) { + //util.dprintln(4, "trytoGetParam(int) failed on param "+s); + } + } + + public boolean isRDF(){ return boolRDF; } diff -r ed7c1e4dd177 -r c36944be0b58 servlet/src/digilib/servlet/Scaler.java --- a/servlet/src/digilib/servlet/Scaler.java Mon Jun 30 17:25:43 2003 +0200 +++ b/servlet/src/digilib/servlet/Scaler.java Wed Jul 02 00:02:18 2003 +0200 @@ -58,7 +58,7 @@ public class Scaler extends HttpServlet { // digilib servlet version (for all components) - public static final String dlVersion = "1.10b2"; + public static final String dlVersion = "1.11a1"; // Utils instance with debuglevel Utils util; @@ -184,6 +184,9 @@ boolean doMirror = false; // angle of mirror axis double mirrorAngle = 0; + // original (hires) image resolution + double origResX = 0; + double origResY = 0; /* * request parameters @@ -222,6 +225,14 @@ // color modification float[] paramRGBM = dlRequest.getRgbm(); float[] paramRGBA = dlRequest.getRgba(); + // destination resolution (DPI) + float paramDDPIX = dlRequest.getDdpix(); + float paramDDPIY = dlRequest.getDdpiy(); + if ((paramDDPIX == 0) || (paramDDPIY == 0)) { + // if X or Y resolution isn't set, use DDPI + paramDDPIX = dlRequest.getDdpi(); + paramDDPIY = dlRequest.getDdpi(); + } /* operation mode: "fit": always fit to page, * "clip": send original resolution cropped, "file": send whole file (if @@ -237,7 +248,7 @@ absoluteScale = false; cropToFit = false; autoRes = true; - } else if (dlRequest.isOption("scale")) { + } else if (dlRequest.isOption("osize")) { scaleToFit = false; absoluteScale = true; cropToFit = false; @@ -361,11 +372,11 @@ * select a resolution */ if (autoRes) { - // autores: use next bigger resolution + // autores: use next higher resolution fileToLoad = fileset.getNextBigger(expectedSourceSize, docuInfo); if (fileToLoad == null) { - // this is the biggest we have + // this is the highest we have fileToLoad = fileset.get(0); } } else { @@ -385,16 +396,33 @@ } util.dprintln(1, "Loading: " + fileToLoad.getFile()); + if (absoluteScale) { + // get original resolution from metadata + fileset.checkMeta(); + origResX = fileset.getResX(); + origResY = fileset.getResY(); + } + // check the source image if (!fileToLoad.isChecked()) { fileToLoad.check(docuInfo); } // get the source image type mimeType = fileToLoad.getMimetype(); - boolean imageSendable = + // decide if the image can be sent as is + boolean mimetypeSendable = mimeType.equals("image/jpeg") || mimeType.equals("image/png") || mimeType.equals("image/gif"); + boolean imagoOptions = + dlRequest.isOption("hmir") + || dlRequest.isOption("vmir") + || (paramROT != 0) + || (paramRGBM != null) + || (paramRGBA != null) + || (paramCONT != 0) + || (paramBRGT != 0); + boolean imageSendable = mimetypeSendable && ! imagoOptions; /* if not autoRes and image smaller than requested * size then send as is. @@ -405,7 +433,7 @@ && imageSendable && (fileToLoad.getSize().width <= expectedSourceSize.width) && (fileToLoad.getSize().height <= expectedSourceSize.height)) - || (!autoRes && !scaleToFit && !cropToFit)) { + || (!autoRes && !scaleToFit && !cropToFit && !absoluteScale)) { util.dprintln(1, "Sending File as is."); @@ -474,17 +502,18 @@ scaleXY = (scaleX > scaleY) ? scaleY : scaleX; } else if (absoluteScale) { // absolute scale - areaWidth = paramDW * paramWS; - areaHeight = paramDH * paramWS; + scaleX = paramDDPIX / origResX; + scaleY = paramDDPIY / origResY; + // currently only same scale :-( + scaleXY = scaleX; + areaWidth = paramDW / scaleXY * paramWS; + areaHeight = paramDH / scaleXY * 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;