« Return to Thread: RE: Using JpegXMPFrame to remotely access XMP inside JPGs over HTTP
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,
From: Monaghan, Fergal
Sent: 01 February 2008 16:11
To:
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%2bxml
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
[1] http://jigsaw.w3.org/Doc/Programmer/api/org/w3c/jigsaw/frames/JpegXMPFrame.html
[2] http://jigsaw.basemirror.de/Doc/Reference/frames.html
« Return to Thread: RE: Using JpegXMPFrame to remotely access XMP inside JPGs over HTTP
| Free embeddable forum powered by Nabble | Forum Help |