UNPKG

inkjet

Version:

JPEG-image decoding, encoding & EXIF reading library for browser and node.js

1,556 lines (1,199 loc) 219 kB
"use strict"; function _typeof2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); } (function webpackUniversalModuleDefinition(root, factory) { if ((typeof exports === "undefined" ? "undefined" : _typeof2(exports)) === 'object' && (typeof module === "undefined" ? "undefined" : _typeof2(module)) === 'object') module.exports = factory();else if (typeof define === 'function' && define.amd) define([], factory);else if ((typeof exports === "undefined" ? "undefined" : _typeof2(exports)) === 'object') exports["ExifReader"] = factory();else root["ExifReader"] = factory(); })(typeof self !== 'undefined' ? self : void 0, function () { return ( /******/ function (modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if (installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function (exports, name, getter) { /******/ if (!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function (exports) { /******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function (value, mode) { /******/ if (mode & 1) value = __webpack_require__(value); /******/ if (mode & 8) return value; /******/ if (mode & 4 && _typeof2(value) === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if (mode & 2 && typeof value != 'string') for (var key in value) { __webpack_require__.d(ns, key, function (key) { return value[key]; }.bind(null, key)); } /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function (module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/exif-reader.js"); /******/ }( /************************************************************************/ /******/ { /***/ "./src/byte-order.js": /*!***************************!*\ !*** ./src/byte-order.js ***! \***************************/ /*! exports provided: default */ /***/ function srcByteOrderJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ var LITTLE_ENDIAN = 0x4949; var BIG_ENDIAN = 0x4d4d; /* harmony default export */ __webpack_exports__["default"] = { BIG_ENDIAN: BIG_ENDIAN, LITTLE_ENDIAN: LITTLE_ENDIAN, getByteOrder: getByteOrder }; function getByteOrder(dataView, tiffHeaderOffset) { if (dataView.getUint16(tiffHeaderOffset) === LITTLE_ENDIAN) { return LITTLE_ENDIAN; } else if (dataView.getUint16(tiffHeaderOffset) === BIG_ENDIAN) { return BIG_ENDIAN; } throw new Error('Illegal byte order value. Faulty image.'); } /***/ }, /***/ "./src/constants.js": /*!**************************!*\ !*** ./src/constants.js ***! \**************************/ /*! exports provided: default */ /***/ function srcConstantsJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* harmony default export */ __webpack_exports__["default"] = { USE_FILE: true, USE_PNG_FILE: true, USE_EXIF: true, USE_IPTC: true, USE_XMP: true, USE_ICC: true, USE_THUMBNAIL: true, USE_TIFF: true, USE_JPEG: true, USE_PNG: true, USE_HEIC: true, USE_WEBP: true }; /***/ }, /***/ "./src/dataview.js": /*!*************************!*\ !*** ./src/dataview.js ***! \*************************/ /*! exports provided: default */ /***/ function srcDataviewJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function () { return DataView; }); function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var DataView = /*#__PURE__*/function () { function DataView(buffer) { _classCallCheck(this, DataView); if (bufferTypeIsUnsupported(buffer)) { throw new Error('DataView: Passed buffer type is unsupported.'); } this.buffer = buffer; this.byteLength = this.buffer.length; } _createClass(DataView, [{ key: "getUint8", value: function getUint8(offset) { return this.buffer.readUInt8(offset); } }, { key: "getUint16", value: function getUint16(offset, littleEndian) { if (littleEndian) { return this.buffer.readUInt16LE(offset); } return this.buffer.readUInt16BE(offset); } }, { key: "getUint32", value: function getUint32(offset, littleEndian) { if (littleEndian) { return this.buffer.readUInt32LE(offset); } return this.buffer.readUInt32BE(offset); } }, { key: "getInt32", value: function getInt32(offset, littleEndian) { if (littleEndian) { return this.buffer.readInt32LE(offset); } return this.buffer.readInt32BE(offset); } }]); return DataView; }(); function bufferTypeIsUnsupported(buffer) { return _typeof(buffer) !== 'object' || buffer.length === undefined || buffer.readUInt8 === undefined || buffer.readUInt16LE === undefined || buffer.readUInt16BE === undefined || buffer.readUInt32LE === undefined || buffer.readUInt32BE === undefined || buffer.readInt32LE === undefined || buffer.readInt32BE === undefined; } /***/ }, /***/ "./src/dom-parser.js": /*!***************************!*\ !*** ./src/dom-parser.js ***! \***************************/ /*! exports provided: default */ /***/ function srcDomParserJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* harmony default export */ __webpack_exports__["default"] = { get: get }; function get() { if (typeof DOMParser !== 'undefined') { return DOMParser; } try { return eval('require')('xmldom').DOMParser; // This stops Webpack from replacing the require with a generic import and bundling the module. } catch (error) { return undefined; } } /***/ }, /***/ "./src/errors.js": /*!***********************!*\ !*** ./src/errors.js ***! \***********************/ /*! exports provided: default */ /***/ function srcErrorsJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Thrown when no Exif metadata was found for the given image. * * @param {string} message The error message. */ function MetadataMissingError(message) { this.name = 'MetadataMissingError'; this.message = message || 'No Exif data'; this.stack = new Error().stack; } MetadataMissingError.prototype = new Error(); /* harmony default export */ __webpack_exports__["default"] = { MetadataMissingError: MetadataMissingError }; /***/ }, /***/ "./src/exif-reader.js": /*!****************************!*\ !*** ./src/exif-reader.js ***! \****************************/ /*! exports provided: default, errors, load, loadView */ /***/ function srcExifReaderJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "errors", function () { return errors; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "load", function () { return load; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadView", function () { return loadView; }); /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./utils.js */ "./src/utils.js"); /* harmony import */ var _dataview_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__( /*! ./dataview.js */ "./src/dataview.js"); /* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__( /*! ./constants.js */ "./src/constants.js"); /* harmony import */ var _tag_names_utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__( /*! ./tag-names-utils.js */ "./src/tag-names-utils.js"); /* harmony import */ var _image_header_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__( /*! ./image-header.js */ "./src/image-header.js"); /* harmony import */ var _tags_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__( /*! ./tags.js */ "./src/tags.js"); /* harmony import */ var _file_tags_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__( /*! ./file-tags.js */ "./src/file-tags.js"); /* harmony import */ var _iptc_tags_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__( /*! ./iptc-tags.js */ "./src/iptc-tags.js"); /* harmony import */ var _xmp_tags_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__( /*! ./xmp-tags.js */ "./src/xmp-tags.js"); /* harmony import */ var _icc_tags_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__( /*! ./icc-tags.js */ "./src/icc-tags.js"); /* harmony import */ var _png_file_tags_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__( /*! ./png-file-tags.js */ "./src/png-file-tags.js"); /* harmony import */ var _thumbnail_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__( /*! ./thumbnail.js */ "./src/thumbnail.js"); /* harmony import */ var _errors_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__( /*! ./errors.js */ "./src/errors.js"); /** * ExifReader * http://github.com/mattiasw/exifreader * Copyright (C) 2011-2020 Mattias Wallander <mattias@wallander.eu> * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* harmony default export */ __webpack_exports__["default"] = { load: load, loadView: loadView, errors: _errors_js__WEBPACK_IMPORTED_MODULE_12__["default"] }; var errors = _errors_js__WEBPACK_IMPORTED_MODULE_12__["default"]; function load(data) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { expanded: false }; if (isNodeBuffer(data)) { // File data read in Node can share the underlying buffer with other // data. Therefore it's safest to get a new one to avoid weird bugs. data = new Uint8Array(data).buffer; } return loadView(getDataView(data), options); } function isNodeBuffer(data) { try { return Buffer.isBuffer(data); // eslint-disable-line no-undef } catch (error) { return false; } } function getDataView(data) { try { return new DataView(data); } catch (error) { return new _dataview_js__WEBPACK_IMPORTED_MODULE_1__["default"](data); } } function loadView(dataView) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { expanded: false }; var foundMetaData = false; var tags = {}; var _ImageHeader$parseApp = _image_header_js__WEBPACK_IMPORTED_MODULE_4__["default"].parseAppMarkers(dataView), fileDataOffset = _ImageHeader$parseApp.fileDataOffset, tiffHeaderOffset = _ImageHeader$parseApp.tiffHeaderOffset, iptcDataOffset = _ImageHeader$parseApp.iptcDataOffset, xmpChunks = _ImageHeader$parseApp.xmpChunks, iccChunks = _ImageHeader$parseApp.iccChunks, pngHeaderOffset = _ImageHeader$parseApp.pngHeaderOffset; if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_JPEG && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_FILE && hasFileData(fileDataOffset)) { foundMetaData = true; var readTags = _file_tags_js__WEBPACK_IMPORTED_MODULE_6__["default"].read(dataView, fileDataOffset); if (options.expanded) { tags.file = readTags; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, readTags); } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_EXIF && hasExifData(tiffHeaderOffset)) { foundMetaData = true; var _readTags = _tags_js__WEBPACK_IMPORTED_MODULE_5__["default"].read(dataView, tiffHeaderOffset); if (_readTags.Thumbnail) { tags.Thumbnail = _readTags.Thumbnail; delete _readTags.Thumbnail; } if (options.expanded) { tags.exif = _readTags; addGpsGroup(tags); } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, _readTags); } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_TIFF && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_IPTC && _readTags['IPTC-NAA'] && !hasIptcData(iptcDataOffset)) { var readIptcTags = _iptc_tags_js__WEBPACK_IMPORTED_MODULE_7__["default"].read(_readTags['IPTC-NAA'].value, 0); if (options.expanded) { tags.iptc = readIptcTags; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, readIptcTags); } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_TIFF && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_XMP && _readTags['ApplicationNotes'] && !hasXmpData(xmpChunks)) { var readXmpTags = _xmp_tags_js__WEBPACK_IMPORTED_MODULE_8__["default"].read(Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringValueFromArray"])(_readTags['ApplicationNotes'].value)); if (options.expanded) { tags.xmp = readXmpTags; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, readXmpTags); } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_TIFF && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_ICC && _readTags['ICC_Profile'] && !hasIccData(iccChunks)) { var readIccTags = _icc_tags_js__WEBPACK_IMPORTED_MODULE_9__["default"].read(_readTags['ICC_Profile'].value, [{ offset: 0, length: _readTags['ICC_Profile'].value.length, chunkNumber: 1, chunksTotal: 1 }]); if (options.expanded) { tags.icc = readIccTags; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, readIccTags); } } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_JPEG && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_IPTC && hasIptcData(iptcDataOffset)) { foundMetaData = true; var _readTags2 = _iptc_tags_js__WEBPACK_IMPORTED_MODULE_7__["default"].read(dataView, iptcDataOffset); if (options.expanded) { tags.iptc = _readTags2; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, _readTags2); } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_XMP && hasXmpData(xmpChunks)) { foundMetaData = true; var _readTags3 = _xmp_tags_js__WEBPACK_IMPORTED_MODULE_8__["default"].read(dataView, xmpChunks); if (options.expanded) { tags.xmp = _readTags3; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, _readTags3); } } if ((_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_JPEG || _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_WEBP) && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_ICC && hasIccData(iccChunks)) { foundMetaData = true; var _readTags4 = _icc_tags_js__WEBPACK_IMPORTED_MODULE_9__["default"].read(dataView, iccChunks); if (options.expanded) { tags.icc = _readTags4; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, _readTags4); } } if (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_PNG && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_PNG_FILE && hasPngFileData(pngHeaderOffset)) { foundMetaData = true; var _readTags5 = _png_file_tags_js__WEBPACK_IMPORTED_MODULE_10__["default"].read(dataView, pngHeaderOffset); if (options.expanded) { tags.pngFile = _readTags5; } else { tags = Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["objectAssign"])({}, tags, _readTags5); } } var thumbnail = (_constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_JPEG || _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_WEBP) && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_EXIF && _constants_js__WEBPACK_IMPORTED_MODULE_2__["default"].USE_THUMBNAIL && _thumbnail_js__WEBPACK_IMPORTED_MODULE_11__["default"].get(dataView, tags.Thumbnail, tiffHeaderOffset); if (thumbnail) { foundMetaData = true; tags.Thumbnail = thumbnail; } else { delete tags.Thumbnail; } if (!foundMetaData) { throw new _errors_js__WEBPACK_IMPORTED_MODULE_12__["default"].MetadataMissingError(); } return tags; } function hasFileData(fileDataOffset) { return fileDataOffset !== undefined; } function hasExifData(tiffHeaderOffset) { return tiffHeaderOffset !== undefined; } function addGpsGroup(tags) { if (tags.exif) { if (tags.exif.GPSLatitude && tags.exif.GPSLatitudeRef) { tags.gps = tags.gps || {}; tags.gps.Latitude = Object(_tag_names_utils_js__WEBPACK_IMPORTED_MODULE_3__["getCalculatedGpsValue"])(tags.exif.GPSLatitude.value); if (tags.exif.GPSLatitudeRef.value.join('') === 'S') { tags.gps.Latitude = -tags.gps.Latitude; } } if (tags.exif.GPSLongitude && tags.exif.GPSLongitudeRef) { tags.gps = tags.gps || {}; tags.gps.Longitude = Object(_tag_names_utils_js__WEBPACK_IMPORTED_MODULE_3__["getCalculatedGpsValue"])(tags.exif.GPSLongitude.value); if (tags.exif.GPSLongitudeRef.value.join('') === 'W') { tags.gps.Longitude = -tags.gps.Longitude; } } if (tags.exif.GPSAltitude && tags.exif.GPSAltitudeRef) { tags.gps = tags.gps || {}; tags.gps.Altitude = tags.exif.GPSAltitude.value[0] / tags.exif.GPSAltitude.value[1]; if (tags.exif.GPSAltitudeRef.value === 1) { tags.gps.Altitude = -tags.gps.Altitude; } } } } function hasIptcData(iptcDataOffset) { return iptcDataOffset !== undefined; } function hasXmpData(xmpChunks) { return Array.isArray(xmpChunks) && xmpChunks.length > 0; } function hasIccData(iccDataOffsets) { return Array.isArray(iccDataOffsets) && iccDataOffsets.length > 0; } function hasPngFileData(pngFileDataOffset) { return pngFileDataOffset !== undefined; } /***/ }, /***/ "./src/file-tags.js": /*!**************************!*\ !*** ./src/file-tags.js ***! \**************************/ /*! exports provided: default */ /***/ function srcFileTagsJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _types_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./types.js */ "./src/types.js"); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* harmony default export */ __webpack_exports__["default"] = { read: read }; function read(dataView, fileDataOffset) { var length = getLength(dataView, fileDataOffset); var numberOfColorComponents = getNumberOfColorComponents(dataView, fileDataOffset, length); return { 'Bits Per Sample': getDataPrecision(dataView, fileDataOffset, length), 'Image Height': getImageHeight(dataView, fileDataOffset, length), 'Image Width': getImageWidth(dataView, fileDataOffset, length), 'Color Components': numberOfColorComponents, 'Subsampling': numberOfColorComponents && getSubsampling(dataView, fileDataOffset, numberOfColorComponents.value, length) }; } function getLength(dataView, fileDataOffset) { return _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getShortAt(dataView, fileDataOffset); } function getDataPrecision(dataView, fileDataOffset, length) { var OFFSET = 2; var SIZE = 1; if (OFFSET + SIZE > length) { return undefined; } var value = _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getByteAt(dataView, fileDataOffset + OFFSET); return { value: value, description: '' + value }; } function getImageHeight(dataView, fileDataOffset, length) { var OFFSET = 3; var SIZE = 2; if (OFFSET + SIZE > length) { return undefined; } var value = _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getShortAt(dataView, fileDataOffset + OFFSET); return { value: value, description: "".concat(value, "px") }; } function getImageWidth(dataView, fileDataOffset, length) { var OFFSET = 5; var SIZE = 2; if (OFFSET + SIZE > length) { return undefined; } var value = _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getShortAt(dataView, fileDataOffset + OFFSET); return { value: value, description: "".concat(value, "px") }; } function getNumberOfColorComponents(dataView, fileDataOffset, length) { var OFFSET = 7; var SIZE = 1; if (OFFSET + SIZE > length) { return undefined; } var value = _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getByteAt(dataView, fileDataOffset + OFFSET); return { value: value, description: '' + value }; } function getSubsampling(dataView, fileDataOffset, numberOfColorComponents, length) { var OFFSET = 8; var SIZE = 3 * numberOfColorComponents; if (OFFSET + SIZE > length) { return undefined; } var components = []; for (var i = 0; i < numberOfColorComponents; i++) { var componentOffset = fileDataOffset + OFFSET + i * 3; components.push([_types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getByteAt(dataView, componentOffset), _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getByteAt(dataView, componentOffset + 1), _types_js__WEBPACK_IMPORTED_MODULE_0__["default"].getByteAt(dataView, componentOffset + 2)]); } return { value: components, description: components.length > 1 ? getComponentIds(components) + getSamplingType(components) : '' }; } function getComponentIds(components) { var ids = { 0x01: 'Y', 0x02: 'Cb', 0x03: 'Cr', 0x04: 'I', 0x05: 'Q' }; return components.map(function (compontent) { return ids[compontent[0]]; }).join(''); } function getSamplingType(components) { var types = { 0x11: '4:4:4 (1 1)', 0x12: '4:4:0 (1 2)', 0x14: '4:4:1 (1 4)', 0x21: '4:2:2 (2 1)', 0x22: '4:2:0 (2 2)', 0x24: '4:2:1 (2 4)', 0x41: '4:1:1 (4 1)', 0x42: '4:1:0 (4 2)' }; if (components.length === 0 || components[0][1] === undefined || types[components[0][1]] === undefined) { return ''; } return types[components[0][1]]; } /***/ }, /***/ "./src/icc-tag-names.js": /*!******************************!*\ !*** ./src/icc-tag-names.js ***! \******************************/ /*! exports provided: iccTags, iccProfile */ /***/ function srcIccTagNamesJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iccTags", function () { return iccTags; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iccProfile", function () { return iccProfile; }); /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./utils.js */ "./src/utils.js"); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ var iccTags = { 'desc': { 'name': 'ICC Description' }, 'cprt': { 'name': 'ICC Copyright' }, 'dmdd': { 'name': 'ICC Device Model Description' }, 'vued': { 'name': 'ICC Viewing Conditions Description' }, 'dmnd': { 'name': 'ICC Device Manufacturer for Display' }, 'tech': { 'name': 'Technology' } }; var iccProfile = { 4: { 'name': 'Preferred CMM type', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); }, 'description': function description(value) { return value !== null ? toCompany(value) : ''; } }, 8: { 'name': 'Profile Version', 'value': function value(dataView, offset) { return dataView.getUint8(offset).toString(10) + '.' + (dataView.getUint8(offset + 1) >> 4).toString(10) + '.' + (dataView.getUint8(offset + 1) % 16).toString(10); } }, 12: { 'name': 'Profile/Device class', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); }, 'description': function description(value) { switch (value.toLowerCase()) { case 'scnr': return 'Input Device profile'; case 'mntr': return 'Display Device profile'; case 'prtr': return 'Output Device profile'; case 'link': return 'DeviceLink profile'; case 'abst': return 'Abstract profile'; case 'spac': return 'ColorSpace profile'; case 'nmcl': return 'NamedColor profile'; case 'cenc': return 'ColorEncodingSpace profile'; case 'mid ': return 'MultiplexIdentification profile'; case 'mlnk': return 'MultiplexLink profile'; case 'mvis': return 'MultiplexVisualization profile'; default: return value; } } }, 16: { 'name': 'Color Space', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); } }, 20: { 'name': 'Connection Space', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); } }, 24: { 'name': 'ICC Profile Date', 'value': function value(dataView, offset) { return parseDate(dataView, offset).toISOString(); } }, 36: { 'name': 'ICC Signature', 'value': function value(dataView, offset) { return sliceToString(dataView.buffer.slice(offset, offset + 4)); } }, 40: { 'name': 'Primary Platform', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); }, 'description': function description(value) { return toCompany(value); } }, 48: { 'name': 'Device Manufacturer', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); }, 'description': function description(value) { return toCompany(value); } }, 52: { 'name': 'Device Model Number', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); } }, 64: { 'name': 'Rendering Intent', 'value': function value(dataView, offset) { return dataView.getUint32(offset); }, 'description': function description(value) { switch (value) { case 0: return 'Perceptual'; case 1: return 'Relative Colorimetric'; case 2: return 'Saturation'; case 3: return 'Absolute Colorimetric'; default: return value; } } }, 80: { 'name': 'Profile Creator', 'value': function value(dataView, offset) { return Object(_utils_js__WEBPACK_IMPORTED_MODULE_0__["getStringFromDataView"])(dataView, offset, 4); } } }; function parseDate(dataView, offset) { var year = dataView.getUint16(offset); var month = dataView.getUint16(offset + 2) - 1; var day = dataView.getUint16(offset + 4); var hours = dataView.getUint16(offset + 6); var minutes = dataView.getUint16(offset + 8); var seconds = dataView.getUint16(offset + 10); return new Date(Date.UTC(year, month, day, hours, minutes, seconds)); } function sliceToString(slice) { return String.fromCharCode.apply(null, new Uint8Array(slice)); } function toCompany(value) { switch (value.toLowerCase()) { case 'appl': return 'Apple'; case 'adbe': return 'Adobe'; case 'msft': return 'Microsoft'; case 'sunw': return 'Sun Microsystems'; case 'sgi': return 'Silicon Graphics'; case 'tgnt': return 'Taligent'; default: return value; } } /***/ }, /***/ "./src/icc-tags.js": /*!*************************!*\ !*** ./src/icc-tags.js ***! \*************************/ /*! exports provided: default, parseTags */ /***/ function srcIccTagsJs(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseTags", function () { return parseTags; }); /* harmony import */ var _icc_tag_names_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./icc-tag-names.js */ "./src/icc-tag-names.js"); /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__( /*! ./utils.js */ "./src/utils.js"); /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* harmony default export */ __webpack_exports__["default"] = { read: read }; var PROFILE_HEADER_LENGTH = 84; var ICC_TAG_COUNT_OFFSET = 128; var ICC_SIGNATURE = 'acsp'; var TAG_TYPE_DESC = 'desc'; var TAG_TYPE_MULTI_LOCALIZED_UNICODE_TYPE = 'mluc'; var TAG_TYPE_TEXT = 'text'; var TAG_TYPE_SIGNATURE = 'sig '; var TAG_TABLE_SINGLE_TAG_DATA = 12; // ICC profile data can be longer than application segment max length of ~64k. // so it can be split into multiple APP2 segments. Each segment includes // total chunk count and chunk number. // Here we read all chunks into single continious array of bytes. function read(dataView, iccData) { try { var totalIccProfileLength = iccData.reduce(function (sum, icc) { return sum + icc.length; }, 0); var iccBinaryData = new Uint8Array(totalIccProfileLength); var offset = 0; var buffer = getBuffer(dataView); var _loop = function _loop(chunkNumber) { var iccDataChunk = iccData.find(function (x) { return x.chunkNumber === chunkNumber; }); if (!iccDataChunk) { throw new Error("ICC chunk ".concat(chunkNumber, " not found")); } var data = buffer.slice(iccDataChunk.offset, iccDataChunk.offset + iccDataChunk.length); var chunkData = new Uint8Array(data); iccBinaryData.set(chunkData, offset); offset += chunkData.length; }; for (var chunkNumber = 1; chunkNumber <= iccData.length; chunkNumber++) { _loop(chunkNumber); } return parseTags(new DataView(iccBinaryData.buffer)); } catch (error) { return {}; } } function getBuffer(dataView) { if (Array.isArray(dataView)) { return new DataView(Uint8Array.from(dataView).buffer).buffer; } return dataView.buffer; } function iccDoesNotHaveTagCount(buffer) { return buffer.length < ICC_TAG_COUNT_OFFSET + 4; } function hasTagsData(buffer, tagHeaderOffset) { return buffer.length < tagHeaderOffset + TAG_TABLE_SINGLE_TAG_DATA; } function parseTags(dataView) { var buffer = dataView.buffer; var length = dataView.getUint32(); if (dataView.byteLength !== length) { throw new Error('ICC profile length not matching'); } if (dataView.length < PROFILE_HEADER_LENGTH) { throw new Error('ICC profile too short'); } var tags = {}; var iccProfileKeys = Object.keys(_icc_tag_names_js__WEBPACK_IMPORTED_MODULE_0__["iccProfile"]); for (var i = 0; i < iccProfileKeys.length; i++) { var offset = iccProfileKeys[i]; var profileEntry = _icc_tag_names_js__WEBPACK_IMPORTED_MODULE_0__["iccProfile"][offset]; var value = profileEntry.value(dataView, parseInt(offset, 10)); var description = value; if (profileEntry.description) { description = profileEntry.description(value); } tags[profileEntry.name] = { value: value, description: description }; } var signature = sliceToString(buffer.slice(36, 40)); if (signature !== ICC_SIGNATURE) { throw new Error('ICC profile: missing signature'); } /* ICC data is incomplete but we have header parsed so lets return it */ if (iccDoesNotHaveTagCount(buffer)) { return tags; } var tagCount = dataView.getUint32(128); var tagHeaderOffset = 132; for (var _i = 0; _i < tagCount; _i++) { if (hasTagsData(buffer, tagHeaderOffset)) { // Tags are corrupted (offset too far), return what we parsed until now return tags; } var tagSignature = Object(_utils_js__WEBPACK_IMPORTED_MODULE_1__["getStringFromDataView"])(dataView, tagHeaderOffset, 4); var tagOffset = dataView.getUint32(tagHeaderOffset + 4); var tagSize = dataView.getUint32(tagHeaderOffset + 8); if (tagOffset > buffer.length) { // Tag data is invalid, lets return what we managed to parse return tags; } var tagType = Object(_utils_js__WEBPACK_IMPORTED_MODULE_1__["getStringFromDataView"])(dataView, tagOffset, 4); if (tagType === TAG_TYPE_DESC) { var tagValueSize = dataView.getUint32(tagOffset + 8); if (tagValueSize > tagSize) { // Tag data is invalid, lets return what we managed to parse return tags; } var val = sliceToString(buffer.slice(tagOffset + 12, tagOffset + tagValueSize + 11)); addTag(tags, tagSignature, val); } else if (tagType === TAG_TYPE_MULTI_LOCALIZED_UNICODE_TYPE) { var numRecords = dataView.getUint32(tagOffset + 8); var recordSize = dataView.getUint32(tagOffset + 12); var _offset = tagOffset + 16; var _val = []; for (var recordNum = 0; recordNum < numRecords; recordNum++) { var languageCode = Object(_utils_js__WEBPACK_IMPORTED_MODULE_1__["getStringFromDataView"])(dataView, _offset + 0, 2); var countryCode = Object(_utils_js__WEBPACK_IMPORTED_MODULE_1__["getStringFromDataView"])(dataView, _offset + 2, 2); var textLength = dataView.getUint32(_offset + 4); var textOffset = dataView.getUint32(_offset + 8); var text = Object(_utils_js__WEBPACK_IMPORTED_MODULE_1__["getUnicodeStringFromDataView"])(dataView, tagOffset + textOffset, textLength); _val.push({ languageCode: languageCode, countryCode: countryCode, text: text }); _offset += recordSize; } if (numRecords === 1) { addTag(tags, tagSignature, _val[0].text); } else { var valObj = {}; for (var valIndex = 0; valIndex < _val.length; valIndex++) { valObj["".concat(_val[valIndex].languageCode, "-").concat(_val[valIndex].countryCode)] = _val[valIndex].text; } addTag(tags, tagSignature, valObj); } } else if (tagType === TAG_TYPE_TEXT) { var _val2 = sliceToString(buffer.slice(tagOffset + 8, tagOffset + tagSize - 7)); addTag(tags, tagSignature, _val2); } else if (tagType === TAG_TYPE_SIGNATURE) { var _val3 = sliceToString(buffer.slice(tagOffset + 8, tagOffset + 12)); addTag(tags, tagSignature, _val3); } tagHeaderOffset = tagHeaderOffset + 12; } return tags; } function sliceToString(slice) { return String.fromCharCode.apply(null, new Uint8Array(slice)); } function addTag(tags, tagSignature, value) { if (_icc_tag_names_js__WEBPACK_IMPORTED_MODULE_0__["iccTags"][tagSignature]) { tags[_icc_tag_names_js__WEBPACK_IMPORTED_MODULE_0__["iccTags"][tagSignature].name] = { value: value, description: value }; } else { tags[tagSignature] = { value: value, description: value }; } } /***/ }, /***/ "./src/image-header-heic.js": /*!**********************************!*\ !*** ./src/image-header-heic.js ***! \**********************************/ /*! exports provided: default */ /***/ function srcImageHeaderHeicJs(module, __webpack_exports__, __webpack_require__) { "use strict