inkjet
Version:
JPEG-image decoding, encoding & EXIF reading library for browser and node.js
1,556 lines (1,199 loc) • 219 kB
JavaScript
"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