image-size
Advanced tools
Comparing version 2.0.0-alpha.1 to 2.0.0-alpha.2
#!/usr/bin/env node | ||
'use strict' | ||
const fs = require('fs') | ||
const path = require('path') | ||
const { imageSize } = require('..') | ||
const fs = require('node:fs') | ||
const path = require('node:path') | ||
const { imageSize } = require('../dist/cjs/fromFile') | ||
@@ -16,3 +16,2 @@ const files = process.argv.slice(2) | ||
const red = ['\x1B[31m', '\x1B[39m'] | ||
// const bold = ['\x1B[1m', '\x1B[22m'] | ||
const grey = ['\x1B[90m', '\x1B[39m'] | ||
@@ -25,3 +24,3 @@ const green = ['\x1B[32m', '\x1B[39m'] | ||
files.forEach(function (image) { | ||
files.forEach(async (image) => { | ||
try { | ||
@@ -31,5 +30,5 @@ if (fs.existsSync(path.resolve(image))) { | ||
const greyImage = colorize(image, grey) | ||
const size = imageSize(image) | ||
const size = await imageSize(image) | ||
const sizes = size.images || [size] | ||
sizes.forEach(size => { | ||
sizes.forEach((size) => { | ||
let greyType = '' | ||
@@ -40,4 +39,8 @@ if (size.type) { | ||
console.info( | ||
colorize(size.width, green) + greyX + colorize(size.height, green) | ||
+ ' - ' + greyImage + greyType | ||
colorize(size.width, green) + | ||
greyX + | ||
colorize(size.height, green) + | ||
' - ' + | ||
greyImage + | ||
greyType | ||
) | ||
@@ -49,5 +52,4 @@ }) | ||
} catch (e) { | ||
// console.error(e.stack) | ||
console.error(colorize(e.message, red), '-', image) | ||
} | ||
}) |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.detector = void 0; | ||
const types_1 = require("./types"); | ||
const keys = Object.keys(types_1.typeHandlers); | ||
const index_1 = require("./types/index"); | ||
const keys = Object.keys(index_1.typeHandlers); | ||
// This map helps avoid validating for every single image type | ||
@@ -17,3 +17,3 @@ const firstBytes = { | ||
0x89: 'png', | ||
0xff: 'jpg' | ||
0xff: 'jpg', | ||
}; | ||
@@ -24,9 +24,9 @@ function detector(input) { | ||
const type = firstBytes[byte]; | ||
if (type && types_1.typeHandlers[type].validate(input)) { | ||
if (type && index_1.typeHandlers[type].validate(input)) { | ||
return type; | ||
} | ||
} | ||
const finder = (key) => types_1.typeHandlers[key].validate(input); | ||
const finder = (key) => index_1.typeHandlers[key].validate(input); | ||
return keys.find(finder); | ||
} | ||
exports.detector = detector; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.types = exports.setConcurrency = exports.disableTypes = exports.disableFS = exports.imageSize = void 0; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const queue_1 = require("queue"); | ||
const types_1 = require("./types"); | ||
const detector_1 = require("./detector"); | ||
// Maximum input size, with a default of 512 kilobytes. | ||
// TO-DO: make this adaptive based on the initial signature of the image | ||
const MaxInputSize = 512 * 1024; | ||
// This queue is for async `fs` operations, to avoid reaching file-descriptor limits | ||
const queue = new queue_1.default({ concurrency: 100, autostart: true }); | ||
const globalOptions = { | ||
disabledFS: false, | ||
disabledTypes: [] | ||
}; | ||
/** | ||
* Return size information based on an Uint8Array | ||
* | ||
* @param {Uint8Array} input | ||
* @param {String} filepath | ||
* @returns {Object} | ||
*/ | ||
function lookup(input, filepath) { | ||
// detect the file type.. don't rely on the extension | ||
const type = (0, detector_1.detector)(input); | ||
if (typeof type !== 'undefined') { | ||
if (globalOptions.disabledTypes.indexOf(type) > -1) { | ||
throw new TypeError('disabled file type: ' + type); | ||
} | ||
// find an appropriate handler for this file type | ||
if (type in types_1.typeHandlers) { | ||
const size = types_1.typeHandlers[type].calculate(input, filepath); | ||
if (size !== undefined) { | ||
size.type = type; | ||
return size; | ||
} | ||
} | ||
} | ||
// throw up, if we don't understand the file | ||
throw new TypeError('unsupported file type: ' + type + ' (file: ' + filepath + ')'); | ||
} | ||
/** | ||
* Reads a file into an Uint8Array. | ||
* @param {String} filepath | ||
* @returns {Promise<Uint8Array>} | ||
*/ | ||
async function readFileAsync(filepath) { | ||
const handle = await fs.promises.open(filepath, 'r'); | ||
try { | ||
const { size } = await handle.stat(); | ||
if (size <= 0) { | ||
throw new Error('Empty file'); | ||
} | ||
const inputSize = Math.min(size, MaxInputSize); | ||
const input = new Uint8Array(inputSize); | ||
await handle.read(input, 0, inputSize, 0); | ||
return input; | ||
} | ||
finally { | ||
await handle.close(); | ||
} | ||
} | ||
/** | ||
* Synchronously reads a file into an Uint8Array, blocking the nodejs process. | ||
* | ||
* @param {String} filepath | ||
* @returns {Uint8Array} | ||
*/ | ||
function readFileSync(filepath) { | ||
// read from the file, synchronously | ||
const descriptor = fs.openSync(filepath, 'r'); | ||
try { | ||
const { size } = fs.fstatSync(descriptor); | ||
if (size <= 0) { | ||
throw new Error('Empty file'); | ||
} | ||
const inputSize = Math.min(size, MaxInputSize); | ||
const input = new Uint8Array(inputSize); | ||
fs.readSync(descriptor, input, 0, inputSize, 0); | ||
return input; | ||
} | ||
finally { | ||
fs.closeSync(descriptor); | ||
} | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
module.exports = exports = imageSize; // backwards compatibility | ||
exports.default = imageSize; | ||
/** | ||
* @param {Uint8Array|string} input - Uint8Array or relative/absolute path of the image file | ||
* @param {Function=} [callback] - optional function for async detection | ||
*/ | ||
function imageSize(input, callback) { | ||
// Handle Uint8Array input | ||
if (input instanceof Uint8Array) { | ||
return lookup(input); | ||
} | ||
// input should be a string at this point | ||
if (typeof input !== 'string' || globalOptions.disabledFS) { | ||
throw new TypeError('invalid invocation. input should be a Uint8Array'); | ||
} | ||
// resolve the file path | ||
const filepath = path.resolve(input); | ||
if (typeof callback === 'function') { | ||
queue.push(() => readFileAsync(filepath) | ||
.then(input => process.nextTick(callback, null, lookup(input, filepath))) | ||
.catch(callback)); | ||
} | ||
else { | ||
const input = readFileSync(filepath); | ||
return lookup(input, filepath); | ||
} | ||
} | ||
exports.imageSize = imageSize; | ||
const disableFS = (v) => { globalOptions.disabledFS = v; }; | ||
exports.disableFS = disableFS; | ||
const disableTypes = (types) => { globalOptions.disabledTypes = types; }; | ||
exports.disableTypes = disableTypes; | ||
const setConcurrency = (c) => { queue.concurrency = c; }; | ||
exports.setConcurrency = setConcurrency; | ||
exports.types = Object.keys(types_1.typeHandlers); | ||
exports.types = exports.disableTypes = exports.imageSize = void 0; | ||
var lookup_1 = require("./lookup"); | ||
Object.defineProperty(exports, "imageSize", { enumerable: true, get: function () { return lookup_1.lookup; } }); | ||
Object.defineProperty(exports, "disableTypes", { enumerable: true, get: function () { return lookup_1.disableTypes; } }); | ||
Object.defineProperty(exports, "types", { enumerable: true, get: function () { return lookup_1.types; } }); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BMP = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.BMP = { | ||
validate: input => (0, interface_1.toUTF8String)(input, 0, 2) === 'BM', | ||
calculate: input => ({ | ||
height: Math.abs((0, interface_1.readInt32LE)(input, 22)), | ||
width: (0, interface_1.readUInt32LE)(input, 18) | ||
}) | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 2) === 'BM', | ||
calculate: (input) => ({ | ||
height: Math.abs((0, utils_1.readInt32LE)(input, 22)), | ||
width: (0, utils_1.readUInt32LE)(input, 18), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CUR = void 0; | ||
const interface_1 = require("./interface"); | ||
const ico_1 = require("./ico"); | ||
const utils_1 = require("./utils"); | ||
const TYPE_CURSOR = 2; | ||
exports.CUR = { | ||
validate(input) { | ||
const reserved = (0, interface_1.readUInt16LE)(input, 0); | ||
const imageCount = (0, interface_1.readUInt16LE)(input, 4); | ||
const reserved = (0, utils_1.readUInt16LE)(input, 0); | ||
const imageCount = (0, utils_1.readUInt16LE)(input, 4); | ||
if (reserved !== 0 || imageCount === 0) | ||
return false; | ||
const imageType = (0, interface_1.readUInt16LE)(input, 2); | ||
const imageType = (0, utils_1.readUInt16LE)(input, 2); | ||
return imageType === TYPE_CURSOR; | ||
}, | ||
calculate: (input) => ico_1.ICO.calculate(input) | ||
calculate: (input) => ico_1.ICO.calculate(input), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DDS = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.DDS = { | ||
validate: input => (0, interface_1.readUInt32LE)(input, 0) === 0x20534444, | ||
calculate: input => ({ | ||
height: (0, interface_1.readUInt32LE)(input, 12), | ||
width: (0, interface_1.readUInt32LE)(input, 16) | ||
}) | ||
validate: (input) => (0, utils_1.readUInt32LE)(input, 0) === 0x20534444, | ||
calculate: (input) => ({ | ||
height: (0, utils_1.readUInt32LE)(input, 12), | ||
width: (0, utils_1.readUInt32LE)(input, 16), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GIF = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const gifRegexp = /^GIF8[79]a/; | ||
exports.GIF = { | ||
validate: input => gifRegexp.test((0, interface_1.toUTF8String)(input, 0, 6)), | ||
calculate: input => ({ | ||
height: (0, interface_1.readUInt16LE)(input, 8), | ||
width: (0, interface_1.readUInt16LE)(input, 6) | ||
}) | ||
validate: (input) => gifRegexp.test((0, utils_1.toUTF8String)(input, 0, 6)), | ||
calculate: (input) => ({ | ||
height: (0, utils_1.readUInt16LE)(input, 8), | ||
width: (0, utils_1.readUInt16LE)(input, 6), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ICNS = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
/** | ||
@@ -69,4 +69,4 @@ * ICNS Header | ||
return [ | ||
(0, interface_1.toUTF8String)(input, imageOffset, imageLengthOffset), | ||
(0, interface_1.readUInt32BE)(input, imageLengthOffset) | ||
(0, utils_1.toUTF8String)(input, imageOffset, imageLengthOffset), | ||
(0, utils_1.readUInt32BE)(input, imageLengthOffset), | ||
]; | ||
@@ -79,6 +79,6 @@ } | ||
exports.ICNS = { | ||
validate: input => (0, interface_1.toUTF8String)(input, 0, 4) === 'icns', | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 4) === 'icns', | ||
calculate(input) { | ||
const inputLength = input.length; | ||
const fileLength = (0, interface_1.readUInt32BE)(input, FILE_LENGTH_OFFSET); | ||
const fileLength = (0, utils_1.readUInt32BE)(input, FILE_LENGTH_OFFSET); | ||
let imageOffset = SIZE_HEADER; | ||
@@ -93,3 +93,3 @@ let imageHeader = readImageHeader(input, imageOffset); | ||
images: [imageSize], | ||
width: imageSize.width | ||
width: imageSize.width, | ||
}; | ||
@@ -103,3 +103,3 @@ while (imageOffset < fileLength && imageOffset < inputLength) { | ||
return result; | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ICO = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const TYPE_ICON = 1; | ||
@@ -38,6 +38,6 @@ /** | ||
function getImageSize(input, imageIndex) { | ||
const offset = SIZE_HEADER + (imageIndex * SIZE_IMAGE_ENTRY); | ||
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY; | ||
return { | ||
height: getSizeFromOffset(input, offset + 1), | ||
width: getSizeFromOffset(input, offset) | ||
width: getSizeFromOffset(input, offset), | ||
}; | ||
@@ -47,11 +47,11 @@ } | ||
validate(input) { | ||
const reserved = (0, interface_1.readUInt16LE)(input, 0); | ||
const imageCount = (0, interface_1.readUInt16LE)(input, 4); | ||
const reserved = (0, utils_1.readUInt16LE)(input, 0); | ||
const imageCount = (0, utils_1.readUInt16LE)(input, 4); | ||
if (reserved !== 0 || imageCount === 0) | ||
return false; | ||
const imageType = (0, interface_1.readUInt16LE)(input, 2); | ||
const imageType = (0, utils_1.readUInt16LE)(input, 2); | ||
return imageType === TYPE_ICON; | ||
}, | ||
calculate(input) { | ||
const nbImages = (0, interface_1.readUInt16LE)(input, 4); | ||
const nbImages = (0, utils_1.readUInt16LE)(input, 4); | ||
const imageSize = getImageSize(input, 0); | ||
@@ -67,5 +67,5 @@ if (nbImages === 1) | ||
images: imgs, | ||
width: imageSize.width | ||
width: imageSize.width, | ||
}; | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.readUInt = exports.readUInt32LE = exports.readUInt32BE = exports.readInt32LE = exports.readUInt24LE = exports.readUInt16LE = exports.readUInt16BE = exports.readInt16LE = exports.toHexString = exports.toUTF8String = void 0; | ||
const decoder = new TextDecoder(); | ||
const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end)); | ||
exports.toUTF8String = toUTF8String; | ||
const toHexString = (input, start = 0, end = input.length) => input.slice(start, end) | ||
.reduce((memo, i) => memo + ('0' + i.toString(16)).slice(-2), ''); | ||
exports.toHexString = toHexString; | ||
const readInt16LE = (input, offset = 0) => { | ||
const val = input[offset] + input[offset + 1] * 2 ** 8; | ||
return val | (val & 2 ** 15) * 0x1fffe; | ||
}; | ||
exports.readInt16LE = readInt16LE; | ||
const readUInt16BE = (input, offset = 0) => input[offset] * 2 ** 8 + | ||
input[offset + 1]; | ||
exports.readUInt16BE = readUInt16BE; | ||
const readUInt16LE = (input, offset = 0) => input[offset] + | ||
input[offset + 1] * 2 ** 8; | ||
exports.readUInt16LE = readUInt16LE; | ||
const readUInt24LE = (input, offset = 0) => input[offset] + | ||
input[offset + 1] * 2 ** 8 + | ||
input[offset + 2] * 2 ** 16; | ||
exports.readUInt24LE = readUInt24LE; | ||
const readInt32LE = (input, offset = 0) => input[offset] + | ||
input[offset + 1] * 2 ** 8 + | ||
input[offset + 2] * 2 ** 16 + | ||
(input[offset + 3] << 24); | ||
exports.readInt32LE = readInt32LE; | ||
const readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + | ||
input[offset + 1] * 2 ** 16 + | ||
input[offset + 2] * 2 ** 8 + | ||
input[offset + 3]; | ||
exports.readUInt32BE = readUInt32BE; | ||
const readUInt32LE = (input, offset = 0) => input[offset] + | ||
input[offset + 1] * 2 ** 8 + | ||
input[offset + 2] * 2 ** 16 + | ||
input[offset + 3] * 2 ** 24; | ||
exports.readUInt32LE = readUInt32LE; | ||
// Abstract reading multi-byte unsigned integers | ||
const methods = { | ||
readUInt16BE: exports.readUInt16BE, readUInt16LE: exports.readUInt16LE, | ||
readUInt32BE: exports.readUInt32BE, readUInt32LE: exports.readUInt32LE | ||
}; | ||
function readUInt(input, bits, offset, isBigEndian) { | ||
offset = offset || 0; | ||
const endian = isBigEndian ? 'BE' : 'LE'; | ||
const methodName = ('readUInt' + bits + endian); | ||
return methods[methodName](input, offset); | ||
} | ||
exports.readUInt = readUInt; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.J2C = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.J2C = { | ||
// TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC | ||
validate: input => (0, interface_1.toHexString)(input, 0, 4) === 'ff4fff51', | ||
calculate: input => ({ | ||
height: (0, interface_1.readUInt32BE)(input, 12), | ||
width: (0, interface_1.readUInt32BE)(input, 8), | ||
}) | ||
validate: (input) => (0, utils_1.toHexString)(input, 0, 4) === 'ff4fff51', | ||
calculate: (input) => ({ | ||
height: (0, utils_1.readUInt32BE)(input, 12), | ||
width: (0, utils_1.readUInt32BE)(input, 8), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.JP2 = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const BoxTypes = { | ||
@@ -11,11 +11,11 @@ ftyp: '66747970', | ||
rreq: '72726571', | ||
xml_: '786d6c20' | ||
xml_: '786d6c20', | ||
}; | ||
const calculateRREQLength = (box) => { | ||
const unit = box[0]; | ||
let offset = 1 + (2 * unit); | ||
const numStdFlags = (0, interface_1.readUInt16BE)(box, offset); | ||
let offset = 1 + 2 * unit; | ||
const numStdFlags = (0, utils_1.readUInt16BE)(box, offset); | ||
const flagsLength = numStdFlags * (2 + unit); | ||
offset = offset + 2 + flagsLength; | ||
const numVendorFeatures = (0, interface_1.readUInt16BE)(box, offset); | ||
const numVendorFeatures = (0, utils_1.readUInt16BE)(box, offset); | ||
const featuresLength = numVendorFeatures * (16 + unit); | ||
@@ -26,4 +26,4 @@ return offset + 2 + featuresLength; | ||
return { | ||
height: (0, interface_1.readUInt32BE)(box, 4), | ||
width: (0, interface_1.readUInt32BE)(box, 8), | ||
height: (0, utils_1.readUInt32BE)(box, 4), | ||
width: (0, utils_1.readUInt32BE)(box, 8), | ||
}; | ||
@@ -33,4 +33,4 @@ }; | ||
validate(input) { | ||
const signature = (0, interface_1.toHexString)(input, 4, 8); | ||
const signatureLength = (0, interface_1.readUInt32BE)(input, 0); | ||
const signature = (0, utils_1.toHexString)(input, 4, 8); | ||
const signatureLength = (0, utils_1.readUInt32BE)(input, 0); | ||
if (signature !== BoxTypes.jp__ || signatureLength < 1) { | ||
@@ -40,11 +40,11 @@ return false; | ||
const ftypeBoxStart = signatureLength + 4; | ||
const ftypBoxLength = (0, interface_1.readUInt32BE)(input, signatureLength); | ||
const ftypBoxLength = (0, utils_1.readUInt32BE)(input, signatureLength); | ||
const ftypBox = input.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength); | ||
return (0, interface_1.toHexString)(ftypBox, 0, 4) === BoxTypes.ftyp; | ||
return (0, utils_1.toHexString)(ftypBox, 0, 4) === BoxTypes.ftyp; | ||
}, | ||
calculate(input) { | ||
const signatureLength = (0, interface_1.readUInt32BE)(input, 0); | ||
const ftypBoxLength = (0, interface_1.readUInt16BE)(input, signatureLength + 2); | ||
const signatureLength = (0, utils_1.readUInt32BE)(input, 0); | ||
const ftypBoxLength = (0, utils_1.readUInt16BE)(input, signatureLength + 2); | ||
let offset = signatureLength + 4 + ftypBoxLength; | ||
const nextBoxType = (0, interface_1.toHexString)(input, offset, offset + 4); | ||
const nextBoxType = (0, utils_1.toHexString)(input, offset, offset + 4); | ||
switch (nextBoxType) { | ||
@@ -55,3 +55,4 @@ case BoxTypes.rreq: | ||
const MAGIC = 4; | ||
offset = offset + 4 + MAGIC + calculateRREQLength(input.slice(offset + 4)); | ||
offset = | ||
offset + 4 + MAGIC + calculateRREQLength(input.slice(offset + 4)); | ||
return parseIHDR(input.slice(offset + 8, offset + 24)); | ||
@@ -61,5 +62,6 @@ case BoxTypes.jp2h: | ||
default: | ||
throw new TypeError('Unsupported header found: ' + (0, interface_1.toUTF8String)(input, offset, offset + 4)); | ||
throw new TypeError('Unsupported header found: ' + | ||
(0, utils_1.toUTF8String)(input, offset, offset + 4)); | ||
} | ||
} | ||
}, | ||
}; |
@@ -8,3 +8,3 @@ "use strict"; | ||
exports.JPG = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const EXIF_MARKER = '45786966'; | ||
@@ -20,8 +20,8 @@ const APP1_DATA_SIZE_BYTES = 2; | ||
function isEXIF(input) { | ||
return (0, interface_1.toHexString)(input, 2, 6) === EXIF_MARKER; | ||
return (0, utils_1.toHexString)(input, 2, 6) === EXIF_MARKER; | ||
} | ||
function extractSize(input, index) { | ||
return { | ||
height: (0, interface_1.readUInt16BE)(input, index), | ||
width: (0, interface_1.readUInt16BE)(input, index + 2) | ||
height: (0, utils_1.readUInt16BE)(input, index), | ||
width: (0, utils_1.readUInt16BE)(input, index + 2), | ||
}; | ||
@@ -38,5 +38,7 @@ } | ||
const offset = EXIF_HEADER_BYTES + idfOffset; | ||
const idfDirectoryEntries = (0, interface_1.readUInt)(exifBlock, 16, offset, isBigEndian); | ||
const idfDirectoryEntries = (0, utils_1.readUInt)(exifBlock, 16, offset, isBigEndian); | ||
for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { | ||
const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + (directoryEntryNumber * IDF_ENTRY_BYTES); | ||
const start = offset + | ||
NUM_DIRECTORY_ENTRIES_BYTES + | ||
directoryEntryNumber * IDF_ENTRY_BYTES; | ||
const end = start + IDF_ENTRY_BYTES; | ||
@@ -48,6 +50,6 @@ // Skip on corrupt EXIF blocks | ||
const block = exifBlock.slice(start, end); | ||
const tagNumber = (0, interface_1.readUInt)(block, 16, 0, isBigEndian); | ||
const tagNumber = (0, utils_1.readUInt)(block, 16, 0, isBigEndian); | ||
// 0x0112 (decimal: 274) is the `orientation` tag ID | ||
if (tagNumber === 274) { | ||
const dataFormat = (0, interface_1.readUInt)(block, 16, 2, isBigEndian); | ||
const dataFormat = (0, utils_1.readUInt)(block, 16, 2, isBigEndian); | ||
if (dataFormat !== 3) { | ||
@@ -58,7 +60,7 @@ return; | ||
// if there would more than 4 bytes in total it's a pointer | ||
const numberOfComponents = (0, interface_1.readUInt)(block, 32, 4, isBigEndian); | ||
const numberOfComponents = (0, utils_1.readUInt)(block, 32, 4, isBigEndian); | ||
if (numberOfComponents !== 1) { | ||
return; | ||
} | ||
return (0, interface_1.readUInt)(block, 16, 8, isBigEndian); | ||
return (0, utils_1.readUInt)(block, 16, 8, isBigEndian); | ||
} | ||
@@ -71,3 +73,3 @@ } | ||
// Consider byte alignment | ||
const byteAlign = (0, interface_1.toHexString)(exifBlock, EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES); | ||
const byteAlign = (0, utils_1.toHexString)(exifBlock, EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES); | ||
// Ignore Empty EXIF. Validate byte alignment | ||
@@ -86,3 +88,3 @@ const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; | ||
// Every JPEG block must begin with a 0xFF | ||
if (input[index] !== 0xFF) { | ||
if (input[index] !== 0xff) { | ||
throw new TypeError('Invalid JPG, marker table corrupted'); | ||
@@ -92,3 +94,3 @@ } | ||
exports.JPG = { | ||
validate: input => (0, interface_1.toHexString)(input, 0, 2) === 'ffd8', | ||
validate: (input) => (0, utils_1.toHexString)(input, 0, 2) === 'ffd8', | ||
calculate(input) { | ||
@@ -101,3 +103,3 @@ // Skip 4 chars, they are for signature | ||
// read length of the next block | ||
const i = (0, interface_1.readUInt16BE)(input, 0); | ||
const i = (0, utils_1.readUInt16BE)(input, 0); | ||
if (isEXIF(input)) { | ||
@@ -112,3 +114,3 @@ orientation = validateExifBlock(input, i); | ||
next = input[i + 1]; | ||
if (next === 0xC0 || next === 0xC1 || next === 0xC2) { | ||
if (next === 0xc0 || next === 0xc1 || next === 0xc2) { | ||
const size = extractSize(input, i + 5); | ||
@@ -122,3 +124,3 @@ // TODO: is orientation=0 a valid answer here? | ||
orientation, | ||
width: size.width | ||
width: size.width, | ||
}; | ||
@@ -130,3 +132,3 @@ } | ||
throw new TypeError('Invalid JPG, no size found'); | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.KTX = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.KTX = { | ||
validate: input => (0, interface_1.toUTF8String)(input, 1, 7) === 'KTX 11', | ||
calculate: input => ({ | ||
height: (0, interface_1.readUInt32LE)(input, 40), | ||
width: (0, interface_1.readUInt32LE)(input, 36), | ||
}) | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 1, 7) === 'KTX 11', | ||
calculate: (input) => ({ | ||
height: (0, utils_1.readUInt32LE)(input, 40), | ||
width: (0, utils_1.readUInt32LE)(input, 36), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PNG = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const pngSignature = 'PNG\r\n\x1a\n'; | ||
@@ -11,6 +11,6 @@ const pngImageHeaderChunkName = 'IHDR'; | ||
validate(input) { | ||
if (pngSignature === (0, interface_1.toUTF8String)(input, 1, 8)) { | ||
let chunkName = (0, interface_1.toUTF8String)(input, 12, 16); | ||
if (pngSignature === (0, utils_1.toUTF8String)(input, 1, 8)) { | ||
let chunkName = (0, utils_1.toUTF8String)(input, 12, 16); | ||
if (chunkName === pngFriedChunkName) { | ||
chunkName = (0, interface_1.toUTF8String)(input, 28, 32); | ||
chunkName = (0, utils_1.toUTF8String)(input, 28, 32); | ||
} | ||
@@ -25,13 +25,13 @@ if (chunkName !== pngImageHeaderChunkName) { | ||
calculate(input) { | ||
if ((0, interface_1.toUTF8String)(input, 12, 16) === pngFriedChunkName) { | ||
if ((0, utils_1.toUTF8String)(input, 12, 16) === pngFriedChunkName) { | ||
return { | ||
height: (0, interface_1.readUInt32BE)(input, 36), | ||
width: (0, interface_1.readUInt32BE)(input, 32) | ||
height: (0, utils_1.readUInt32BE)(input, 36), | ||
width: (0, utils_1.readUInt32BE)(input, 32), | ||
}; | ||
} | ||
return { | ||
height: (0, interface_1.readUInt32BE)(input, 20), | ||
width: (0, interface_1.readUInt32BE)(input, 16) | ||
height: (0, utils_1.readUInt32BE)(input, 20), | ||
width: (0, utils_1.readUInt32BE)(input, 16), | ||
}; | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PNM = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const PNMTypes = { | ||
@@ -13,3 +13,3 @@ P1: 'pbm/ascii', | ||
P7: 'pam', | ||
PF: 'pfm' | ||
PF: 'pfm', | ||
}; | ||
@@ -55,3 +55,3 @@ const handlers = { | ||
height: size.height, | ||
width: size.width | ||
width: size.width, | ||
}; | ||
@@ -62,14 +62,14 @@ } | ||
} | ||
} | ||
}, | ||
}; | ||
exports.PNM = { | ||
validate: input => (0, interface_1.toUTF8String)(input, 0, 2) in PNMTypes, | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 2) in PNMTypes, | ||
calculate(input) { | ||
const signature = (0, interface_1.toUTF8String)(input, 0, 2); | ||
const signature = (0, utils_1.toUTF8String)(input, 0, 2); | ||
const type = PNMTypes[signature]; | ||
// TODO: this probably generates garbage. move to a stream based parser | ||
const lines = (0, interface_1.toUTF8String)(input, 3).split(/[\r\n]+/); | ||
const lines = (0, utils_1.toUTF8String)(input, 3).split(/[\r\n]+/); | ||
const handler = handlers[type] || handlers.default; | ||
return handler(lines); | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PSD = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.PSD = { | ||
validate: input => (0, interface_1.toUTF8String)(input, 0, 4) === '8BPS', | ||
calculate: input => ({ | ||
height: (0, interface_1.readUInt32BE)(input, 14), | ||
width: (0, interface_1.readUInt32BE)(input, 18) | ||
}) | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 4) === '8BPS', | ||
calculate: (input) => ({ | ||
height: (0, utils_1.readUInt32BE)(input, 14), | ||
width: (0, utils_1.readUInt32BE)(input, 18), | ||
}), | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SVG = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/; | ||
@@ -18,7 +18,7 @@ const extractorRegExps = { | ||
ex: 8, | ||
m: 96 / INCH_CM * 100, | ||
m: (96 / INCH_CM) * 100, | ||
mm: 96 / INCH_CM / 10, | ||
pc: 96 / 72 / 12, | ||
pt: 96 / 72, | ||
px: 1 | ||
px: 1, | ||
}; | ||
@@ -37,3 +37,3 @@ const unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join('|')})?$`); | ||
height: parseLength(bounds[3]), | ||
width: parseLength(bounds[2]) | ||
width: parseLength(bounds[2]), | ||
}; | ||
@@ -77,5 +77,6 @@ } | ||
exports.SVG = { | ||
validate: input => svgReg.test((0, interface_1.toUTF8String)(input)), | ||
// Scan only the first kilo-byte to speed up the check on larger files | ||
validate: (input) => svgReg.test((0, utils_1.toUTF8String)(input, 0, 1000)), | ||
calculate(input) { | ||
const root = (0, interface_1.toUTF8String)(input).match(extractorRegExps.root); | ||
const root = (0, utils_1.toUTF8String)(input).match(extractorRegExps.root); | ||
if (root) { | ||
@@ -91,3 +92,3 @@ const attrs = parseAttributes(root[0]); | ||
throw new TypeError('Invalid SVG'); | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TGA = void 0; | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
exports.TGA = { | ||
validate(input) { | ||
return (0, interface_1.readUInt16LE)(input, 0) === 0 && (0, interface_1.readUInt16LE)(input, 4) === 0; | ||
return (0, utils_1.readUInt16LE)(input, 0) === 0 && (0, utils_1.readUInt16LE)(input, 4) === 0; | ||
}, | ||
calculate(input) { | ||
return { | ||
height: (0, interface_1.readUInt16LE)(input, 14), | ||
width: (0, interface_1.readUInt16LE)(input, 12), | ||
height: (0, utils_1.readUInt16LE)(input, 14), | ||
width: (0, utils_1.readUInt16LE)(input, 12), | ||
}; | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TIFF = void 0; | ||
// based on http://www.compix.com/fileformattif.htm | ||
// TO-DO: support big-endian as well | ||
const fs = require("fs"); | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
// Read IFD (image-file-directory) into a buffer | ||
function readIFD(input, filepath, isBigEndian) { | ||
const ifdOffset = (0, interface_1.readUInt)(input, 32, 4, isBigEndian); | ||
// read only till the end of the file | ||
let bufferSize = 1024; | ||
const fileSize = fs.statSync(filepath).size; | ||
if (ifdOffset + bufferSize > fileSize) { | ||
bufferSize = fileSize - ifdOffset - 10; | ||
} | ||
// populate the buffer | ||
const endBuffer = new Uint8Array(bufferSize); | ||
const descriptor = fs.openSync(filepath, 'r'); | ||
fs.readSync(descriptor, endBuffer, 0, bufferSize, ifdOffset); | ||
fs.closeSync(descriptor); | ||
return endBuffer.slice(2); | ||
function readIFD(input, isBigEndian) { | ||
const ifdOffset = (0, utils_1.readUInt)(input, 32, 4, isBigEndian); | ||
return input.slice(ifdOffset + 2); | ||
} | ||
// TIFF values seem to be messed up on Big-Endian, this helps | ||
function readValue(input, isBigEndian) { | ||
const low = (0, interface_1.readUInt)(input, 16, 8, isBigEndian); | ||
const high = (0, interface_1.readUInt)(input, 16, 10, isBigEndian); | ||
const low = (0, utils_1.readUInt)(input, 16, 8, isBigEndian); | ||
const high = (0, utils_1.readUInt)(input, 16, 10, isBigEndian); | ||
return (high << 16) + low; | ||
@@ -41,5 +27,5 @@ } | ||
while (temp && temp.length) { | ||
const code = (0, interface_1.readUInt)(temp, 16, 0, isBigEndian); | ||
const type = (0, interface_1.readUInt)(temp, 16, 2, isBigEndian); | ||
const length = (0, interface_1.readUInt)(temp, 32, 4, isBigEndian); | ||
const code = (0, utils_1.readUInt)(temp, 16, 0, isBigEndian); | ||
const type = (0, utils_1.readUInt)(temp, 16, 2, isBigEndian); | ||
const length = (0, utils_1.readUInt)(temp, 32, 4, isBigEndian); | ||
// 0 means end of IFD | ||
@@ -63,3 +49,3 @@ if (code === 0) { | ||
function determineEndianness(input) { | ||
const signature = (0, interface_1.toUTF8String)(input, 0, 2); | ||
const signature = (0, utils_1.toUTF8String)(input, 0, 2); | ||
if ('II' === signature) { | ||
@@ -79,11 +65,8 @@ return 'LE'; | ||
exports.TIFF = { | ||
validate: input => signatures.includes((0, interface_1.toHexString)(input, 0, 4)), | ||
calculate(input, filepath) { | ||
if (!filepath) { | ||
throw new TypeError('Tiff doesn\'t support buffer'); | ||
} | ||
validate: (input) => signatures.includes((0, utils_1.toHexString)(input, 0, 4)), | ||
calculate(input) { | ||
// Determine BE/LE | ||
const isBigEndian = determineEndianness(input) === 'BE'; | ||
// read the IFD | ||
const ifdBuffer = readIFD(input, filepath, isBigEndian); | ||
const ifdBuffer = readIFD(input, isBigEndian); | ||
// extract the tags from the IFD | ||
@@ -97,3 +80,3 @@ const tags = extractTags(ifdBuffer, isBigEndian); | ||
return { height, width }; | ||
} | ||
}, | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.WEBP = void 0; | ||
// based on https://developers.google.com/speed/webp/docs/riff_container | ||
const interface_1 = require("./interface"); | ||
const utils_1 = require("./utils"); | ||
function calculateExtended(input) { | ||
return { | ||
height: 1 + (0, interface_1.readUInt24LE)(input, 7), | ||
width: 1 + (0, interface_1.readUInt24LE)(input, 4) | ||
height: 1 + (0, utils_1.readUInt24LE)(input, 7), | ||
width: 1 + (0, utils_1.readUInt24LE)(input, 4), | ||
}; | ||
@@ -14,4 +13,5 @@ } | ||
return { | ||
height: 1 + (((input[4] & 0xF) << 10) | (input[3] << 2) | ((input[2] & 0xC0) >> 6)), | ||
width: 1 + (((input[2] & 0x3F) << 8) | input[1]) | ||
height: 1 + | ||
(((input[4] & 0xf) << 10) | (input[3] << 2) | ((input[2] & 0xc0) >> 6)), | ||
width: 1 + (((input[2] & 0x3f) << 8) | input[1]), | ||
}; | ||
@@ -23,4 +23,4 @@ } | ||
return { | ||
height: (0, interface_1.readInt16LE)(input, 8) & 0x3fff, | ||
width: (0, interface_1.readInt16LE)(input, 6) & 0x3fff | ||
height: (0, utils_1.readInt16LE)(input, 8) & 0x3fff, | ||
width: (0, utils_1.readInt16LE)(input, 6) & 0x3fff, | ||
}; | ||
@@ -30,9 +30,9 @@ } | ||
validate(input) { | ||
const riffHeader = 'RIFF' === (0, interface_1.toUTF8String)(input, 0, 4); | ||
const webpHeader = 'WEBP' === (0, interface_1.toUTF8String)(input, 8, 12); | ||
const vp8Header = 'VP8' === (0, interface_1.toUTF8String)(input, 12, 15); | ||
return (riffHeader && webpHeader && vp8Header); | ||
const riffHeader = 'RIFF' === (0, utils_1.toUTF8String)(input, 0, 4); | ||
const webpHeader = 'WEBP' === (0, utils_1.toUTF8String)(input, 8, 12); | ||
const vp8Header = 'VP8' === (0, utils_1.toUTF8String)(input, 12, 15); | ||
return riffHeader && webpHeader && vp8Header; | ||
}, | ||
calculate(input) { | ||
const chunkHeader = (0, interface_1.toUTF8String)(input, 12, 16); | ||
const chunkHeader = (0, utils_1.toUTF8String)(input, 12, 16); | ||
input = input.slice(20, 30); | ||
@@ -57,3 +57,3 @@ // Extended webp stream signature | ||
// Lossy webp stream signature | ||
const signature = (0, interface_1.toHexString)(input, 3, 6); | ||
const signature = (0, utils_1.toHexString)(input, 3, 6); | ||
if (chunkHeader === 'VP8L' && signature !== '9d012a') { | ||
@@ -63,3 +63,3 @@ return calculateLossless(input); | ||
throw new TypeError('Invalid WebP'); | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { imageType } from './types'; | ||
import type { imageType } from './types/index'; | ||
export declare function detector(input: Uint8Array): imageType | undefined; |
@@ -1,10 +0,1 @@ | ||
import { imageType } from './types'; | ||
import { ISizeCalculationResult } from './types/interface'; | ||
declare type CallbackFn = (e: Error | null, r?: ISizeCalculationResult) => void; | ||
export default imageSize; | ||
export declare function imageSize(input: Uint8Array | string): ISizeCalculationResult; | ||
export declare function imageSize(input: string, callback: CallbackFn): void; | ||
export declare const disableFS: (v: boolean) => void; | ||
export declare const disableTypes: (types: imageType[]) => void; | ||
export declare const setConcurrency: (c: number) => void; | ||
export declare const types: string[]; | ||
export { lookup as imageSize, disableTypes, types } from './lookup'; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const BMP: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const CUR: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const DDS: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const GIF: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const ICNS: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const ICO: IImage; |
@@ -1,2 +0,2 @@ | ||
export interface ISize { | ||
export type ISize = { | ||
width: number | undefined; | ||
@@ -6,19 +6,9 @@ height: number | undefined; | ||
type?: string; | ||
} | ||
export interface ISizeCalculationResult extends ISize { | ||
}; | ||
export type ISizeCalculationResult = { | ||
images?: ISize[]; | ||
} | ||
export declare const toUTF8String: (input: Uint8Array, start?: number, end?: number) => string; | ||
export declare const toHexString: (input: Uint8Array, start?: number, end?: number) => string; | ||
export declare const readInt16LE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readUInt16BE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readUInt16LE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readUInt24LE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readInt32LE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readUInt32BE: (input: Uint8Array, offset?: number) => number; | ||
export declare const readUInt32LE: (input: Uint8Array, offset?: number) => number; | ||
export declare function readUInt(input: Uint8Array, bits: 16 | 32, offset: number, isBigEndian: boolean): number; | ||
export interface IImage { | ||
} & ISize; | ||
export type IImage = { | ||
validate: (input: Uint8Array) => boolean; | ||
calculate: (input: Uint8Array, filepath?: string) => ISizeCalculationResult; | ||
} | ||
calculate: (input: Uint8Array) => ISizeCalculationResult; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const J2C: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const JP2: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const JPG: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const KTX: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PNG: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PNM: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PSD: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const SVG: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const TGA: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const TIFF: IImage; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const WEBP: IImage; |
{ | ||
"name": "image-size", | ||
"version": "2.0.0-alpha.1", | ||
"version": "2.0.0-alpha.2", | ||
"description": "get dimensions of any image file", | ||
"type": "module", | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"types": "dist/dts/index.d.ts", | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/esm/index.mjs", | ||
"types": "./dist/dts/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/esm/index.js", | ||
"require": "./dist/cjs/index.js" | ||
"require": "./dist/cjs/index.js", | ||
"import": "./dist/esm/index.mjs", | ||
"types": "./dist/dts/index.d.ts" | ||
}, | ||
"./*": { | ||
"require": "./dist/cjs/*.js", | ||
"import": "./dist/esm/*.mjs", | ||
"types": "./dist/dts/*.d.ts" | ||
}, | ||
"./types/*": { | ||
"require": "./dist/cjs/types/*.js", | ||
"import": "./dist/esm/types/*.mjs", | ||
"types": "./dist/dts/types/*.d.ts" | ||
} | ||
@@ -20,12 +30,14 @@ }, | ||
"engines": { | ||
"node": ">=16.18.0" | ||
"node": ">=18.18.0" | ||
}, | ||
"packageManager": "yarn@4.0.1", | ||
"bin": "bin/image-size.js", | ||
"scripts": { | ||
"pretest": "eslint --ext .ts,.js bin lib specs", | ||
"test": "nyc mocha", | ||
"lint": "eslint --ext .ts,.js bin lib specs", | ||
"format": "prettier --write lib specs", | ||
"test": "TS_NODE_PROJECT=tsconfig.cjs.json nyc mocha", | ||
"clean": "rm -rf dist docs", | ||
"generate-docs": "typedoc", | ||
"build": "tsc && tsc -p tsconfig.esm.json", | ||
"prepack": "yarn build" | ||
"build": "tsc && tsc -p tsconfig.cjs.json", | ||
"prepack": "yarn clean && yarn build && node scripts/fix-package.js" | ||
}, | ||
@@ -56,23 +68,24 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/chai": "4.3.1", | ||
"@types/glob": "7.2.0", | ||
"@types/mocha": "9.1.1", | ||
"@types/node": "18.0.3", | ||
"@types/sinon": "10.0.12", | ||
"@typescript-eslint/eslint-plugin": "5.30.6", | ||
"@typescript-eslint/parser": "5.30.6", | ||
"chai": "4.3.6", | ||
"eslint": "8.19.0", | ||
"glob": "8.0.3", | ||
"mocha": "10.0.0", | ||
"@types/chai": "4.3.10", | ||
"@types/chai-as-promised": "7.1.8", | ||
"@types/glob": "8.1.0", | ||
"@types/mocha": "10.0.4", | ||
"@types/node": "18.18.9", | ||
"@types/sinon": "17.0.1", | ||
"@typescript-eslint/eslint-plugin": "6.10.0", | ||
"@typescript-eslint/parser": "6.10.0", | ||
"chai": "4.3.10", | ||
"chai-as-promised": "7.1.1", | ||
"eslint": "8.53.0", | ||
"eslint-config-prettier": "9.0.0", | ||
"eslint-plugin-prettier": "5.0.1", | ||
"glob": "10.3.10", | ||
"mocha": "10.2.0", | ||
"nyc": "15.1.0", | ||
"sinon": "14.0.0", | ||
"ts-node": "10.8.2", | ||
"typedoc": "0.23.7", | ||
"typescript": "4.7.4" | ||
}, | ||
"dependencies": { | ||
"queue": "6.0.2" | ||
}, | ||
"packageManager": "yarn@3.2.0" | ||
"prettier": "3.1.0", | ||
"sinon": "17.0.1", | ||
"ts-node": "10.9.1", | ||
"typedoc": "0.25.3", | ||
"typescript": "5.2.2" | ||
} | ||
} |
130
Readme.md
@@ -11,21 +11,21 @@ # image-size | ||
* BMP | ||
* CUR | ||
* DDS | ||
* GIF | ||
* ICNS | ||
* ICO | ||
* J2C | ||
* JP2 | ||
* JPEG | ||
* KTX | ||
* PNG | ||
* PNM (PAM, PBM, PFM, PGM, PPM) | ||
* PSD | ||
* SVG | ||
* TGA | ||
* TIFF | ||
* WebP | ||
- BMP | ||
- CUR | ||
- DDS | ||
- GIF | ||
- ICNS | ||
- ICO | ||
- J2C | ||
- JP2 | ||
- JPEG | ||
- KTX | ||
- PNG | ||
- PNM (PAM, PBM, PFM, PGM, PPM) | ||
- PSD | ||
- SVG | ||
- TGA | ||
- TIFF | ||
- WebP | ||
## Programmatic Usage | ||
## Installation | ||
@@ -42,57 +42,31 @@ ```shell | ||
### Synchronous | ||
## Programmatic Usage | ||
### Passing in a Buffer/Uint8Array | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const dimensions = sizeOf('images/funny-cats.png') | ||
console.log(dimensions.width, dimensions.height) | ||
const { imageSize } = require('image-size') | ||
const { width, height } = imageSize(bufferObject) | ||
console.log(width, height) | ||
``` | ||
### Asynchronous | ||
### Reading from a file | ||
```javascript | ||
const sizeOf = require('image-size') | ||
sizeOf('images/funny-cats.png', function (err, dimensions) { | ||
console.log(dimensions.width, dimensions.height) | ||
}) | ||
const { imageSize } = require('image-size/fromFile') | ||
const dimensions = await imageSize('images/funny-cats.png') | ||
console.log(dimensions.width, dimensions.height) | ||
``` | ||
NOTE: The asynchronous version doesn't work if the input is a Uint8Array. Use synchronous version instead. | ||
Also, the asynchronous functions have a default concurrency limit of **100** | ||
NOTE: Reading from files haa a default concurrency limit of **100** | ||
To change this limit, you can call the `setConcurrency` function like this: | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const sizeOf = require('image-size/fromFile') | ||
sizeOf.setConcurrency(123456) | ||
``` | ||
### Using promises (nodejs 10.x+) | ||
```javascript | ||
const { promisify } = require('util') | ||
const sizeOf = promisify(require('image-size')) | ||
sizeOf('images/funny-cats.png') | ||
.then(dimensions => { console.log(dimensions.width, dimensions.height) }) | ||
.catch(err => console.error(err)) | ||
``` | ||
### Async/Await (Typescript & ES7) | ||
```javascript | ||
const { promisify } = require('util') | ||
const sizeOf = promisify(require('image-size')) | ||
(async () => { | ||
try { | ||
const dimensions = await sizeOf('images/funny-cats.png') | ||
console.log(dimensions.width, dimensions.height) | ||
} catch (err) { | ||
console.error(err) | ||
} | ||
})().then(c => console.log(c)) | ||
``` | ||
### Multi-size | ||
If the target file is an icon (.ico) or a cursor (.cur), the `width` and `height` will be the ones of the first found image. | ||
If the target file/buffer is an icon (.ico) or a cursor (.cur), the `width` and `height` will be the ones of the first found image. | ||
@@ -102,4 +76,4 @@ An additional `images` array is available and returns the dimensions of all the available images | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const images = sizeOf('images/multi-size.ico').images | ||
const { imageSize } = require('image-size') | ||
const { images } = imageSize('images/multi-size.ico') | ||
for (const dimensions of images) { | ||
@@ -113,6 +87,6 @@ console.log(dimensions.width, dimensions.height) | ||
```javascript | ||
const url = require('url') | ||
const http = require('http') | ||
const url = require('node:url') | ||
const http = require('node:http') | ||
const sizeOf = require('image-size') | ||
const { imageSize } = require('image-size') | ||
@@ -124,24 +98,21 @@ const imgUrl = 'http://my-amazing-website.com/image.jpeg' | ||
const chunks = [] | ||
response.on('data', function (chunk) { | ||
chunks.push(chunk) | ||
}).on('end', function() { | ||
const input = Buffer.concat(chunks) | ||
console.log(sizeOf(input)) | ||
}) | ||
response | ||
.on('data', function (chunk) { | ||
chunks.push(chunk) | ||
}) | ||
.on('end', function () { | ||
const buffer = Buffer.concat(chunks) | ||
console.log(imageSize(buffer)) | ||
}) | ||
}) | ||
``` | ||
You can optionally check the buffer length & stop downloading the image after a few kilobytes. | ||
You can optionally check the buffer lengths & stop downloading the image after a few kilobytes. | ||
**You don't need to download the entire image** | ||
### Disabling certain image types | ||
```javascript | ||
const imageSize = require('image-size') | ||
imageSize.disableTypes(['tiff', 'ico']) | ||
``` | ||
### Disabling all file-system reads | ||
```javascript | ||
const imageSize = require('image-size') | ||
imageSize.disableFS(true) | ||
const { disableTypes } = require('image-size') | ||
disableTypes(['tiff', 'ico']) | ||
``` | ||
@@ -154,5 +125,5 @@ | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const dimensions = sizeOf('images/photo.jpeg') | ||
console.log(dimensions.orientation) | ||
const { imageSize } = require('image-size/fromFile') | ||
const { width, height, orientation } = imageSize('images/photo.jpeg') | ||
console.log(width, height, orientation) | ||
``` | ||
@@ -178,3 +149,2 @@ | ||
## Credits | ||
@@ -181,0 +151,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
83356
0
78
2184
1
21
149
No
- Removedqueue@6.0.2
- Removedinherits@2.0.4(transitive)
- Removedqueue@6.0.2(transitive)