- From: Monaghan, Fergal <fergal.monaghan@deri.org>
- Date: Mon, 31 Mar 2008 15:48:35 +0100
- To: <www-jigsaw@w3.org>
- Message-ID: <316ADBDBFE4F4D4AA4FEEF7496ECAEF9D71CC6@EVS1.ac.nuigalway.ie>
Hi guys, After receiving no response from anyone else who may have encountered/solved this problem (please see below), I revisited it, had a look at Jigsaw's source and found fixes to a few problems so that now I can HTTP Get and Put XMP into/out of JPEGs remotely. I'd like to share my finds/fixes with you guys so that they can be added to the next distribution (fixes made to Jigsaw 2.2.6): please find attached the fixed source files (4 of them) and a short readme of what changes I made and why. I've also included the readme inline for completeness in the mailing list archive: my fixes can be entirely replicated from Jigsaw 2.2.6 by following its steps. I hope this helps, BEGIN INLINE README ================= JPEG XMP fix for Jigsaw These are fixes to some of Jigsaw's source to properly enable the HTTP Get and Put of XMP into/out of JPEG files remotely. The fixes were made on top of Jigsaw version 2.2.6. Motivational problems with Jigsaw: 1. org.w3c.tools.jpeg package a. No writer for XMP data in JPGs b. No handler for XMP data in JPGs 2. org.w3c.jigsaw.resources.JpegFileResource class a. Hard-coded to use COM (comment) chunk instead of APP1 chunk (required by XMP specification) 3. org.w3c.jigsaw.frames.JpegXMPFrame class a. Does not update cache when XMP in JPG is changed New files included here: 1. org.w3c.tools.jpeg.JpegXMPWriter class (to fix problem 1.a) Writer for XMP data in JPEGs a. Copied JpegCommentWriter class b. Replaced all references to JpegCommentWriter class with JpegXMPWriter class (to fix problem 2.a) c. Replaced all references to Jpeg.M_COM field with Jpeg.M_APP1 field (to fix problem 2.a) 2. org.w3c.tools.jpeg.JpegXMPHandler class (to fix problem 1.b) Handler for XMP data in JPEGs a. Copied JpegCommentHandler class b. Replaced getComment method with getXMP method: public String getXMP() throws IOException,JpegException { JpegHeaders jpeghead = new JpegHeaders(in); // get the XMP out of the jpeg file return jpeghead.getXMP(); } c. Replaced all references to JpegCommentWriter class with JpegXMPwriter Changes to existing files included here: 1. org.w3c.jigsaw.resources.JpegFileResource class a. Imported JpegXMPHandler: import org.w3c.tools.jpeg.JpegXMPHandler; b. Added newXMPMetadataContent method (similar to newMetadataContent method: to fix problem 2.a): /** * Save the given stream as the underlying file content. * This method preserve the old file version in a <code>~</code> file. * @param in The input stream to use as the resource entity. * @return A boolean, <strong>true</strong> if the resource was just * created, <strong>false</strong> otherwise. * @exception IOException If dumping the content failed. */ public synchronized boolean newXMPMetadataContent(InputStream in) throws IOException { File file = getFile() ; boolean created = (!file.exists() || (file.length() == 0)); String name = file.getName(); File temp = new File(file.getParent(), "#"+name+"#") ; String iomsg = null ; JpegXMPHandler jpegHandler = new JpegXMPHandler(file); // We are not catching IO exceptions here, except to remove temp: try { FileOutputStream fout = new FileOutputStream(temp) ; char buf[] = new char[4096] ; Writer writer = jpegHandler.getOutputStreamWriter(fout); InputStreamReader reader = new InputStreamReader(in); for(int got = 0; (got = reader.read(buf)) > 0 ; ) writer.write(buf, 0, got) ; writer.close() ; // Fix to ensure Windows releases lock on file... // Close and mark for garbage collection the following: // All streams, reader/writers & the JpegHandler reader.close(); in.close(); fout.close(); reader = null; in = null; writer = null; fout = null; jpegHandler = null; // Explicitly call the Garbage Collector System.gc(); // End fix for Windows } catch (IOException ex) { iomsg = ex.getMessage() ; } finally { if(iomsg != null) { temp.delete(); throw new IOException(iomsg); } else { if(getBackupFlag()) { File backup = getBackupFile(); if(backup.exists()) backup.delete(); file.renameTo(getBackupFile()) ; } // with some OSes, rename doesn't overwrite so... if (file.exists()) file.delete(); temp.renameTo(file) ; // update our attributes for this new content: updateFileAttributes() ; } } return created; } 2. org.w3c.jigsaw.frames.JpegXMPFrame class a. Replaced all references to ImageFileResource class with JpegFileResource (so that can use newXMPMetadataContent method below) b. Replaced reference to ImageFileResource.newMetadataContent method with JpegFileResource.newXMPMetadataContent method (to fix problem 2.a) c. Added attributeChanged method (similar to JpegComFrame.attributeChanged method: to fix problem 3.a): /** * Listen its resource. */ public void attributeChanged(AttributeChangedEvent evt) { super.attributeChanged(evt); String name = evt.getAttribute().getName(); if((name.equals("file-stamp")) || (name.equals("file-stamp"))) xmpinfo = null; } ================= END INLINE README Fergal Monaghan Digital Enterprise Research Institute, Galway, Ireland. ________________________________ From: Monaghan, Fergal Sent: 01 February 2008 16:11 To: www-jigsaw@w3.org Subject: Using JpegXMPFrame to remotely access XMP inside JPGs over HTTP Hi guys, I've been using JpegComFrame to access the comment block inside JPGs remotely by asking for e.g. http://sw.deri.org:8001/Photos/20071009162628.jpg;application%2frdf%2bxm l Now I want to switch over to using XMP and JpegXMPFrame: but when I run JigAdmin there isn't the same dual MIME type options like with JpegComFrame. The only documentation I can find online on using JpegXMPFrame are single sentences like "This class will read the XMP marker from a jpeg file and return it depending on the Accept: header" [1] or "Used to extract XMP from Jpeg images." [2] From this I can only guess that it is not possible to simply append the desired MIME type to the end of the URL, but to create an Accept header in the HTTP request. I've tried the following Java in an attempt to do this programmatically, with no luck: URL modelURL = new URL("http://sw.deri.org:8001/Photos/20080201141047.jpg"); HttpURLConnection huc = (HttpURLConnection)modelURL.openConnection(); huc.addRequestProperty("accept", "xmp"); How exactly do I use the Accept: header to retrieve just the XMP metadata over HTTP? What MIME type do I need to specify? Is there any documentation anywhere that could be useful? Help! Fergal Monaghan, PhD Candidate, Digital Enterprise Research Institute, National University of Ireland, Galway, IDA Business Park, Lower Dangan, Galway, IRELAND. [1] http://jigsaw.w3.org/Doc/Programmer/api/org/w3c/jigsaw/frames/JpegXMPFra me.html [2] http://jigsaw.basemirror.de/Doc/Reference/frames.html
Attachments
- application/octet-stream attachment: JigsawJpegXMPSource.rar
Received on Monday, 31 March 2008 14:48:39 UTC