1
- ; ( function ( factory ) {
2
- 'use strict'
3
- if ( typeof define === 'function' && define . amd ) {
4
- // Register as an anonymous AMD module:
5
- define ( [ './load-image' , './load-image-meta' ] , factory )
6
- } else if ( typeof module === 'object' && module . exports ) {
7
- factory ( require ( './load-image' ) , require ( './load-image-meta' ) )
8
- } else {
9
- // Browser globals:
10
- factory ( window . loadImage )
1
+ ; ( function ( factory ) {
2
+ 'use strict'
3
+ if ( typeof define === 'function' && define . amd ) {
4
+ // Register as an anonymous AMD module:
5
+ define ( [ './load-image' , './load-image-meta' ] , factory )
6
+ } else if ( typeof module === 'object' && module . exports ) {
7
+ factory ( require ( './load-image' ) , require ( './load-image-meta' ) )
8
+ } else {
9
+ // Browser globals:
10
+ factory ( window . loadImage )
11
+ }
12
+ } ( function ( loadImage ) {
13
+ 'use strict'
14
+
15
+ loadImage . XmpMap = function ( ) {
16
+ return this
17
+ } ;
18
+
19
+ loadImage . XmpMap . prototype . get = function ( id ) {
20
+ return this [ id ]
21
+ }
22
+
23
+ loadImage . parseXmpData = function ( dataView , offset , length , data , options ) {
24
+ if ( options . disableExif ) {
25
+ return
11
26
}
12
- } ( function ( loadImage ) {
13
- 'use strict'
14
27
15
- loadImage . XmpMap = function ( ) {
16
- return this
17
- } ;
28
+ // Check for the ASCII code for 'http' (0x68747470). Note that the actual
29
+ // XMP identifier is quite long: 'http://ns.adobe.com/xap/1.0/\x00'
30
+ var offsetNamespace = 4 ;
31
+ var lengthNamespace = 29 ;
32
+ var arrNamespace = [ ] ;
33
+ for ( var i = 0 ; i < lengthNamespace ; i ++ ) {
34
+ arrNamespace . push ( String . fromCharCode ( dataView . getUint8 ( offset + offsetNamespace + i ) ) ) ;
35
+ }
18
36
19
- loadImage . XmpMap . prototype . get = function ( id ) {
20
- return this [ id ] ;
37
+ var namespace = arrNamespace . join ( '' ) ;
38
+ if ( namespace !== 'http://ns.adobe.com/xap/1.0/\0' ) {
39
+ // No XMP data.
40
+ return
21
41
}
22
42
23
- loadImage . parseXmpData = function ( dataView , offset , length , data , options ) {
24
- if ( options . disableExif ) {
25
- return ;
26
- }
43
+ var offsetLp = 2 ; // Offset to the packet length field.
44
+ var packetLength = dataView . getUint16 ( offset + offsetLp ) ;
27
45
28
- // 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"
29
- var offsetNamespace = 4 ;
30
- var lengthNamespace = 29 ;
31
- var arrNamespace = [ ] ;
32
- for ( var i = 0 ; i < lengthNamespace ; i ++ ) {
33
- arrNamespace . push ( String . fromCharCode ( dataView . getUint8 ( offset + offsetNamespace + i ) ) ) ;
34
- }
46
+ var lengthLp = 2 ;
47
+ 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.
35
48
36
- var namespace = arrNamespace . join ( "" ) ;
37
- if ( namespace !== "http://ns.adobe.com/xap/1.0/\0" ) {
38
- // No XMP data.
39
- return ;
40
- }
49
+ var maxPacketLength = 65503 ;
50
+ if ( maxPacketLength < packetLength ) {
51
+ // The length of the packet is not valid. Note that XMP does allow
52
+ // multiple packets but they are unlikely and NOT currently supported here.
53
+ return
54
+ }
41
55
42
- var offsetLp = 2 ; // Offset to the packet length field.
43
- var packetLength = dataView . getUint16 ( offset + offsetLp ) ;
56
+ // According to Adobe's document
57
+ // (http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf)
58
+ // an EXIF encoding of XMP will always be UTF-8. No need to check for
59
+ // bytes per character or endianness.
44
60
45
- var lengthLp = 2 ;
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.
61
+ // Find the start of packet data.
62
+ var offsetPacket = offsetNamespace + lengthNamespace ;
63
+ var arrPacketData = [ ] ;
64
+ for ( var j = 0 ; j < packetLength ; j ++ ) {
65
+ arrPacketData . push ( String . fromCharCode ( dataView . getUint8 ( offset + offsetPacket + j ) ) ) ;
66
+ }
67
+ var xml = arrPacketData . join ( '' ) ;
47
68
48
- var maxPacketLength = 65503 ;
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
- }
69
+ loadImage . XmpMap . prototype . getXml = function ( id ) {
70
+ return xml
71
+ }
53
72
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.
73
+ data . xmp = new loadImage . XmpMap ( ) ;
58
74
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 ( "" ) ;
75
+ // Create an XMLDocument and extract the attributes from the
76
+ // Description element.
77
+ var xmlDocument = new DOMParser ( ) . parseFromString ( xml , 'application/xml' ) ;
66
78
67
- loadImage . XmpMap . prototype . getXml = function ( id ) {
68
- return xml ;
69
- }
79
+ var document = xmlDocument . documentElement ;
80
+ if ( ! document ) {
81
+ return
82
+ }
70
83
71
- data . xmp = new loadImage . XmpMap ( ) ;
84
+ 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']" ;
85
+ var xpathResult ;
86
+ try {
87
+ xpathResult = xmlDocument . evaluate ( xpath , document , xmlDocument . createNSResolver ( document ) , XPathResult . ORDERED_NODE_ITERATOR_TYPE , null ) ;
88
+ } catch ( err ) {
89
+ console . log ( "Error selecting Description node: '" + err . message || JSON . stringify ( err ) + "'." ) ;
90
+ }
72
91
73
- // Create an XMLDocument and extract the attributes from the
74
- // Description element.
75
- var xmlDocument = new DOMParser ( ) . parseFromString ( xml , "application/xml" ) ;
92
+ if ( ! xpathResult ) {
93
+ return
94
+ }
76
95
77
- var document = xmlDocument . documentElement ;
78
- if ( ! document ) {
79
- return ;
80
- }
96
+ if ( xpathResult . resultType !== XPathResult . ORDERED_NODE_ITERATOR_TYPE ) {
97
+ console . log ( 'xpathResult type ' + xpathResult . resultType + ' is not supported.' ) ;
98
+ return
99
+ }
81
100
82
- 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']" ;
83
- var xpathResult ;
84
- try {
85
- xpathResult = xmlDocument . evaluate ( xpath , document , xmlDocument . createNSResolver ( document ) , XPathResult . FIRST_ORDERED_NODE_TYPE , null ) ;
86
- } catch ( err ) {
87
- console . log ( "Error selecting Description node: '" + err . message || JSON . stringify ( err ) + "'." ) ;
101
+ // There can be multiple Description nodes.
102
+ var node = xpathResult . iterateNext ( ) ;
103
+ var attr ;
104
+ while ( node ) {
105
+ // The description node can have the XMP information stored as attributes
106
+ // of the node (if they are "simple"") or as child nodes. Get the
107
+ // attributes.
108
+ // http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf
109
+ for ( var k = 0 ; k < node . attributes . length ; k ++ ) {
110
+ attr = node . attributes [ k ] ;
111
+
112
+ // Don't include namespace definitions.
113
+ if ( attr . prefix === 'xmlns' || attr . localName === "about" ) {
114
+ continue
88
115
}
89
116
90
- if ( ! xpathResult ) {
91
- return ;
92
- }
117
+ data . xmp [ attr . localName ] = attr . value ;
118
+ }
93
119
94
- if ( xpathResult . resultType !== XPathResult . FIRST_ORDERED_NODE_TYPE ) {
95
- console . log ( "xpathResult type " + xpathResult . resultType + " is not supported." ) ;
96
- return ;
97
- }
120
+ // Check for properties stored as child nodes.
121
+ var childNode ;
122
+ for ( var m = 0 ; m < node . children . length ; m ++ ) {
123
+ childNode = node . children [ m ] ;
98
124
99
- var node = xpathResult . singleNodeValue ;
100
- var attr ;
101
- for ( var k = 0 ; k < node . attributes . length ; k ++ ) {
102
- attr = node . attributes [ k ] ;
125
+ // If the Description child has its own children the child is a
126
+ // "complex" property and it will be ignored.
127
+ if ( childNode . children ) {
128
+ continue ;
129
+ }
103
130
104
- // Don't include namespace definitions.
105
- if ( attr . prefix === "xmlns" ) {
106
- continue ;
107
- }
131
+ data . xmp [ childNode . localName ] = childNode . textContent ;
132
+ }
108
133
109
- data . xmp [ attr . localName ] = attr . value ;
110
- }
134
+ node = xpathResult . iterateNext ( ) ;
111
135
}
136
+ }
112
137
113
- loadImage . metaDataParsers . jpeg [ 0xffe1 ] . push ( loadImage . parseXmpData ) ;
114
- } ) )
138
+ loadImage . metaDataParsers . jpeg [ 0xffe1 ] . push ( loadImage . parseXmpData ) ;
139
+ } ) )
0 commit comments