Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

240 wiersze
7.1 KiB

  1. /*
  2. * JavaScript Load Image IPTC Parser
  3. * https://github.com/blueimp/JavaScript-Load-Image
  4. *
  5. * Copyright 2013, Sebastian Tschan
  6. * Copyright 2018, Dave Bevan
  7. * https://blueimp.net
  8. *
  9. * Licensed under the MIT license:
  10. * https://opensource.org/licenses/MIT
  11. */
  12. /* global define, module, require, DataView */
  13. ;(function (factory) {
  14. 'use strict'
  15. if (typeof define === 'function' && define.amd) {
  16. // Register as an anonymous AMD module:
  17. define(['jquery/fileUploader/vendor/blueimp-load-image/js/load-image', 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)
  18. } else if (typeof module === 'object' && module.exports) {
  19. factory(require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image'), require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image-meta'))
  20. } else {
  21. // Browser globals:
  22. factory(window.loadImage)
  23. }
  24. })(function (loadImage) {
  25. 'use strict'
  26. /**
  27. * IPTC tag map
  28. *
  29. * @name IptcMap
  30. * @class
  31. */
  32. function IptcMap() {}
  33. IptcMap.prototype.map = {
  34. ObjectName: 5
  35. }
  36. IptcMap.prototype.types = {
  37. 0: 'Uint16', // ApplicationRecordVersion
  38. 200: 'Uint16', // ObjectPreviewFileFormat
  39. 201: 'Uint16', // ObjectPreviewFileVersion
  40. 202: 'binary' // ObjectPreviewData
  41. }
  42. /**
  43. * Retrieves IPTC tag value
  44. *
  45. * @param {number|string} id IPTC tag code or name
  46. * @returns {object} IPTC tag value
  47. */
  48. IptcMap.prototype.get = function (id) {
  49. return this[id] || this[this.map[id]]
  50. }
  51. /**
  52. * Retrieves string for the given DataView and range
  53. *
  54. * @param {DataView} dataView Data view interface
  55. * @param {number} offset Offset start
  56. * @param {number} length Offset length
  57. * @returns {string} String value
  58. */
  59. function getStringValue(dataView, offset, length) {
  60. var outstr = ''
  61. var end = offset + length
  62. for (var n = offset; n < end; n += 1) {
  63. outstr += String.fromCharCode(dataView.getUint8(n))
  64. }
  65. return outstr
  66. }
  67. /**
  68. * Retrieves tag value for the given DataView and range
  69. *
  70. * @param {number} tagCode tag code
  71. * @param {IptcMap} map IPTC tag map
  72. * @param {DataView} dataView Data view interface
  73. * @param {number} offset Range start
  74. * @param {number} length Range length
  75. * @returns {object} Tag value
  76. */
  77. function getTagValue(tagCode, map, dataView, offset, length) {
  78. if (map.types[tagCode] === 'binary') {
  79. return new Blob([dataView.buffer.slice(offset, offset + length)])
  80. }
  81. if (map.types[tagCode] === 'Uint16') {
  82. return dataView.getUint16(offset)
  83. }
  84. return getStringValue(dataView, offset, length)
  85. }
  86. /**
  87. * Combines IPTC value with existing ones.
  88. *
  89. * @param {object} value Existing IPTC field value
  90. * @param {object} newValue New IPTC field value
  91. * @returns {object} Resulting IPTC field value
  92. */
  93. function combineTagValues(value, newValue) {
  94. if (value === undefined) return newValue
  95. if (value instanceof Array) {
  96. value.push(newValue)
  97. return value
  98. }
  99. return [value, newValue]
  100. }
  101. /**
  102. * Parses IPTC tags.
  103. *
  104. * @param {DataView} dataView Data view interface
  105. * @param {number} segmentOffset Segment offset
  106. * @param {number} segmentLength Segment length
  107. * @param {object} data Data export object
  108. * @param {object} includeTags Map of tags to include
  109. * @param {object} excludeTags Map of tags to exclude
  110. */
  111. function parseIptcTags(
  112. dataView,
  113. segmentOffset,
  114. segmentLength,
  115. data,
  116. includeTags,
  117. excludeTags
  118. ) {
  119. var value, tagSize, tagCode
  120. var segmentEnd = segmentOffset + segmentLength
  121. var offset = segmentOffset
  122. while (offset < segmentEnd) {
  123. if (
  124. dataView.getUint8(offset) === 0x1c && // tag marker
  125. dataView.getUint8(offset + 1) === 0x02 // record number, only handles v2
  126. ) {
  127. tagCode = dataView.getUint8(offset + 2)
  128. if (
  129. (!includeTags || includeTags[tagCode]) &&
  130. (!excludeTags || !excludeTags[tagCode])
  131. ) {
  132. tagSize = dataView.getInt16(offset + 3)
  133. value = getTagValue(tagCode, data.iptc, dataView, offset + 5, tagSize)
  134. data.iptc[tagCode] = combineTagValues(data.iptc[tagCode], value)
  135. if (data.iptcOffsets) {
  136. data.iptcOffsets[tagCode] = offset
  137. }
  138. }
  139. }
  140. offset += 1
  141. }
  142. }
  143. /**
  144. * Tests if field segment starts at offset.
  145. *
  146. * @param {DataView} dataView Data view interface
  147. * @param {number} offset Segment offset
  148. * @returns {boolean} True if '8BIM<EOT><EOT>' exists at offset
  149. */
  150. function isSegmentStart(dataView, offset) {
  151. return (
  152. dataView.getUint32(offset) === 0x3842494d && // Photoshop segment start
  153. dataView.getUint16(offset + 4) === 0x0404 // IPTC segment start
  154. )
  155. }
  156. /**
  157. * Returns header length.
  158. *
  159. * @param {DataView} dataView Data view interface
  160. * @param {number} offset Segment offset
  161. * @returns {number} Header length
  162. */
  163. function getHeaderLength(dataView, offset) {
  164. var length = dataView.getUint8(offset + 7)
  165. if (length % 2 !== 0) length += 1
  166. // Check for pre photoshop 6 format
  167. if (length === 0) {
  168. // Always 4
  169. length = 4
  170. }
  171. return length
  172. }
  173. loadImage.parseIptcData = function (dataView, offset, length, data, options) {
  174. if (options.disableIptc) {
  175. return
  176. }
  177. var markerLength = offset + length
  178. while (offset + 8 < markerLength) {
  179. if (isSegmentStart(dataView, offset)) {
  180. var headerLength = getHeaderLength(dataView, offset)
  181. var segmentOffset = offset + 8 + headerLength
  182. if (segmentOffset > markerLength) {
  183. // eslint-disable-next-line no-console
  184. console.log('Invalid IPTC data: Invalid segment offset.')
  185. break
  186. }
  187. var segmentLength = dataView.getUint16(offset + 6 + headerLength)
  188. if (offset + segmentLength > markerLength) {
  189. // eslint-disable-next-line no-console
  190. console.log('Invalid IPTC data: Invalid segment size.')
  191. break
  192. }
  193. // Create the iptc object to store the tags:
  194. data.iptc = new IptcMap()
  195. if (!options.disableIptcOffsets) {
  196. data.iptcOffsets = new IptcMap()
  197. }
  198. parseIptcTags(
  199. dataView,
  200. segmentOffset,
  201. segmentLength,
  202. data,
  203. options.includeIptcTags,
  204. options.excludeIptcTags || { 202: true } // ObjectPreviewData
  205. )
  206. return
  207. }
  208. // eslint-disable-next-line no-param-reassign
  209. offset += 1
  210. }
  211. }
  212. // Registers this IPTC parser for the APP13 JPEG metadata segment:
  213. loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData)
  214. loadImage.IptcMap = IptcMap
  215. // Adds the following properties to the parseMetaData callback data:
  216. // - iptc: The iptc tags, parsed by the parseIptcData method
  217. // Adds the following options to the parseMetaData method:
  218. // - disableIptc: Disables IPTC parsing when true.
  219. // - disableIptcOffsets: Disables storing IPTC tag offsets when true.
  220. // - includeIptcTags: A map of IPTC tags to include for parsing.
  221. // - excludeIptcTags: A map of IPTC tags to exclude from parsing.
  222. })