png-dpi-reader-writer
Version:
Reader/Writer for png chunk pHYs on browsers
85 lines (67 loc) • 3.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.writePngDpi = writePngDpi;
var _crc = require("./crc32");
var _share = require("./share");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function bytes(num, byteLength) {
var binStr = num.toString(2).padStart(byteLength * 8, '0');
var binArr = binStr.match(/\d{8}/g);
return binArr.map(function (v) {
return parseInt(v, 2);
});
}
function insertChunkPhys(byteArray, ptr) {
var dpi = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 72;
var type = 'pHYs'.split('').map(function (c) {
return c.charCodeAt(0);
}); // Number of pixels per unit when DPI is 72
// Number of pixels per unit when devicePixelRatio is 1
var PX_PER_METER = 2835;
var dpr = dpi / 72;
var pixelsPerMeter = Math.floor(PX_PER_METER * dpr);
var data = [].concat(_toConsumableArray(bytes(pixelsPerMeter, 4)), _toConsumableArray(bytes(pixelsPerMeter, 4)), [1]);
var pHYsChunk = [0, 0, 0, 9].concat(_toConsumableArray(type), _toConsumableArray(data), _toConsumableArray(bytes((0, _crc.crc)([].concat(_toConsumableArray(type), _toConsumableArray(data))), 4)));
var pos = ptr.pos - 8;
var newByteArray = new Uint8Array([].concat(_toConsumableArray(Array.from(byteArray.slice(0, pos))), _toConsumableArray(pHYsChunk), _toConsumableArray(Array.from(byteArray.slice(pos)))));
ptr.pos += pHYsChunk.length;
return newByteArray;
}
function writePngDpi(arrayBuffer) {
var dpi = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 72;
var ptr = {
pos: 0
};
var byteArray = new Uint8Array(arrayBuffer);
if (!(0, _share.isPng)(byteArray, ptr)) return byteArray;
(0, _share.readIHDR)(byteArray, ptr);
var hasChunkPhys = false;
var newByteArray;
while (true) {
if (ptr.pos >= byteArray.length) break;
var chunkLength = (0, _share.readBytes)(byteArray, ptr, 4).map(function (v) {
return (0, _share.toBin)(v, 8);
});
chunkLength = parseInt(chunkLength.join(''), 2);
var chunkType = (0, _share.readBytes)(byteArray, ptr, 4).join(' ');
if (chunkType === (0, _share.getCharCodes)('IDAT')) {
if (!hasChunkPhys) {
newByteArray = insertChunkPhys(byteArray, ptr, dpi);
hasChunkPhys = true;
}
break;
}
if (chunkType === (0, _share.getCharCodes)('IEND')) break;
switch (chunkType) {
case (0, _share.getCharCodes)('pHYs'):
hasChunkPhys = true;
}
ptr.pos += chunkLength + 4; // CRC
}
return newByteArray || byteArray;
}