Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

image-size

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

image-size - npm Package Compare versions

Comparing version 2.0.0-alpha.1 to 2.0.0-alpha.2

dist/cjs/fromFile.js

22

bin/image-size.js
#!/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"
}
}

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc