Skip to content

Commit c26dd62

Browse files
committed
Update to convert the XML into name value pairs.
1 parent 9b66f79 commit c26dd62

File tree

1 file changed

+64
-7
lines changed

1 file changed

+64
-7
lines changed

js/load-image-xmp.js

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,92 @@
1212
} (function (loadImage) {
1313
'use strict'
1414

15+
loadImage.XmpMap = function () {
16+
return this
17+
};
18+
19+
loadImage.XmpMap.prototype.get = function (id) {
20+
return this[id];
21+
}
22+
1523
loadImage.parseXmpData = function (dataView, offset, length, data, options) {
1624
if (options.disableExif) {
1725
return;
1826
}
1927

2028
// Check for the ASCII code for "http" (0x68747470). Note that the actual XMP identifier is quite long: "http://ns.adobe.com/xap/1.0/\x00"
21-
var arrIdentifier = [];
2229
var offsetNamespace = 4;
2330
var lengthNamespace = 29;
31+
var arrNamespace = [];
2432
for (var i = 0; i < lengthNamespace; i++) {
25-
arrIdentifier[i] = String.fromCharCode(dataView.getInt8(offset + offsetNamespace + i));
33+
arrNamespace.push(String.fromCharCode(dataView.getUint8(offset + offsetNamespace + i)));
2634
}
2735

28-
var identifier = arrIdentifier.join("");
29-
if (identifier !== "http://ns.adobe.com/xap/1.0//0") {
36+
var namespace = arrNamespace.join("");
37+
if (namespace !== "http://ns.adobe.com/xap/1.0//0") {
3038
// No XMP data.
3139
return;
3240
}
3341

3442
var offsetLp = 2; // Offset to the packet length field.
35-
var xmpLength = dataView.getUint16(offset + offsetLp);
43+
var packetLength = dataView.getUint16(offset + offsetLp);
3644

3745
var lengthLp = 2;
38-
xmpLength -= (lengthLp + lengthNamespace); // The packet length is a little misleading it includes the length of Lp and Namespace, remove those two to get the actual packet length.
46+
packetLength -= (lengthLp + lengthNamespace); // The packet length is a little misleading it includes the length of Lp and Namespace, remove those two to get the actual packet length.
3947

4048
var maxPacketLength = 65503;
41-
if (maxPacketLength < xmpLength){
49+
if (maxPacketLength < packetLength) {
50+
// The length of the packet is not valid. Note that XMP does allow multiple packets but they are unlikely and NOT currently supported
51+
return;
52+
}
53+
54+
// According to Adobe's document
55+
// (http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf)
56+
// an EXIF encoding of XMP will always be UTF-8. No need to check for
57+
// bytes per character or endianness.
58+
59+
// Find the start of packet data.
60+
var offsetPacket = offsetNamespace + lengthNamespace;
61+
var arrPacketData = [];
62+
for (var j = 0; j < packetLength; j++) {
63+
arrPacketData.push(String.fromCharCode(dataView.getUint8(offset + offsetPacket + j)));
64+
}
65+
var xml = arrPacketData.join("");
66+
67+
data.xmp = new loadImage.XmpMap();
68+
69+
// Create an XMLDocument and extract the attributes from the
70+
// Description element.
71+
var xmlDocument = new DOMParser().parseFromString(xml, "application/xml");
72+
73+
var document = xmlDocument.documentElement;
74+
if (!document) {
75+
return;
76+
}
77+
78+
var xpath = "/*[namespace-uri()='adobe:ns:meta/' and local-name()='xmpmeta']/*[namespace-uri()='http://www.w3.org/1999/02/22-rdf-syntax-ns#' and local-name()='RDF']/*[namespace-uri()='http://www.w3.org/1999/02/22-rdf-syntax-ns#' and local-name()='Description']";
79+
var xpathResult;
80+
try {
81+
xpathResult = xmlDocument.evaluate(xpath, document, xmlDocument.createNSResolver(document), XPathResult.FIRST_ORDERED_NODE_TYPE, null);
82+
} catch (err) {
83+
console.log("Error selecting Description node: '" + err.message || JSON.stringify(err) + "'.");
84+
}
85+
86+
if (!xpathResult) {
4287
return;
4388
}
89+
90+
if (xpathResult.resultType !== XPathResult.FIRST_ORDERED_NODE_TYPE) {
91+
console.log("xpathResult type " + xpathResult.resultType + " is not supported.");
92+
return;
93+
}
94+
95+
var node = xpathResult.singleNodeValue;
96+
var attr;
97+
for (var k = 0; k < node.attributes.length; k++) {
98+
attr = node.attributes[k];
99+
data.xmp[attr.localName] = attr.value;
100+
}
44101
}
45102

46103
loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseXmpData);

0 commit comments

Comments
 (0)