image-size
Advanced tools
Comparing version 1.0.2 to 1.1.0
@@ -1,3 +0,2 @@ | ||
/// <reference types="node" /> | ||
import { imageType } from './types'; | ||
export declare function detector(buffer: Buffer): imageType | undefined; | ||
import type { imageType } from './types/index'; | ||
export declare function detector(input: Uint8Array): imageType | undefined; |
"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,15 +17,15 @@ const firstBytes = { | ||
0x89: 'png', | ||
0xff: 'jpg' | ||
0xff: 'jpg', | ||
}; | ||
function detector(buffer) { | ||
const byte = buffer[0]; | ||
function detector(input) { | ||
const byte = input[0]; | ||
if (byte in firstBytes) { | ||
const type = firstBytes[byte]; | ||
if (type && types_1.typeHandlers[type].validate(buffer)) { | ||
if (type && index_1.typeHandlers[type].validate(input)) { | ||
return type; | ||
} | ||
} | ||
const finder = (key) => types_1.typeHandlers[key].validate(buffer); | ||
const finder = (key) => index_1.typeHandlers[key].validate(input); | ||
return keys.find(finder); | ||
} | ||
exports.detector = detector; |
@@ -1,7 +0,6 @@ | ||
/// <reference types="node" /> | ||
import { imageType } from './types'; | ||
import { ISizeCalculationResult } from './types/interface'; | ||
declare type CallbackFn = (e: Error | null, r?: ISizeCalculationResult) => void; | ||
import type { imageType } from './types/index'; | ||
import type { ISizeCalculationResult } from './types/interface'; | ||
type CallbackFn = (e: Error | null, r?: ISizeCalculationResult) => void; | ||
export default imageSize; | ||
export declare function imageSize(input: Buffer | string): ISizeCalculationResult; | ||
export declare function imageSize(input: Uint8Array | string): ISizeCalculationResult; | ||
export declare function imageSize(input: string, callback: CallbackFn): void; | ||
@@ -8,0 +7,0 @@ export declare const disableFS: (v: boolean) => void; |
@@ -7,7 +7,7 @@ "use strict"; | ||
const queue_1 = require("queue"); | ||
const types_1 = require("./types"); | ||
const index_1 = require("./types/index"); | ||
const detector_1 = require("./detector"); | ||
// Maximum buffer size, with a default of 512 kilobytes. | ||
// Maximum input size, with a default of 512 kilobytes. | ||
// TO-DO: make this adaptive based on the initial signature of the image | ||
const MaxBufferSize = 512 * 1024; | ||
const MaxInputSize = 512 * 1024; | ||
// This queue is for async `fs` operations, to avoid reaching file-descriptor limits | ||
@@ -17,14 +17,14 @@ const queue = new queue_1.default({ concurrency: 100, autostart: true }); | ||
disabledFS: false, | ||
disabledTypes: [] | ||
disabledTypes: [], | ||
}; | ||
/** | ||
* Return size information based on a buffer | ||
* Return size information based on an Uint8Array | ||
* | ||
* @param {Buffer} buffer | ||
* @param {Uint8Array} input | ||
* @param {String} filepath | ||
* @returns {Object} | ||
*/ | ||
function lookup(buffer, filepath) { | ||
function lookup(input, filepath) { | ||
// detect the file type.. don't rely on the extension | ||
const type = (0, detector_1.detector)(buffer); | ||
const type = (0, detector_1.detector)(input); | ||
if (typeof type !== 'undefined') { | ||
@@ -35,6 +35,6 @@ if (globalOptions.disabledTypes.indexOf(type) > -1) { | ||
// find an appropriate handler for this file type | ||
if (type in types_1.typeHandlers) { | ||
const size = types_1.typeHandlers[type].calculate(buffer, filepath); | ||
if (type in index_1.typeHandlers) { | ||
const size = index_1.typeHandlers[type].calculate(input, filepath); | ||
if (size !== undefined) { | ||
size.type = type; | ||
size.type = size.type ?? type; | ||
return size; | ||
@@ -48,7 +48,7 @@ } | ||
/** | ||
* Reads a file into a buffer. | ||
* Reads a file into an Uint8Array. | ||
* @param {String} filepath | ||
* @returns {Promise<Buffer>} | ||
* @returns {Promise<Uint8Array>} | ||
*/ | ||
async function asyncFileToBuffer(filepath) { | ||
async function readFileAsync(filepath) { | ||
const handle = await fs.promises.open(filepath, 'r'); | ||
@@ -60,6 +60,6 @@ try { | ||
} | ||
const bufferSize = Math.min(size, MaxBufferSize); | ||
const buffer = Buffer.alloc(bufferSize); | ||
await handle.read(buffer, 0, bufferSize, 0); | ||
return buffer; | ||
const inputSize = Math.min(size, MaxInputSize); | ||
const input = new Uint8Array(inputSize); | ||
await handle.read(input, 0, inputSize, 0); | ||
return input; | ||
} | ||
@@ -71,8 +71,8 @@ finally { | ||
/** | ||
* Synchronously reads a file into a buffer, blocking the nodejs process. | ||
* Synchronously reads a file into an Uint8Array, blocking the nodejs process. | ||
* | ||
* @param {String} filepath | ||
* @returns {Buffer} | ||
* @returns {Uint8Array} | ||
*/ | ||
function syncFileToBuffer(filepath) { | ||
function readFileSync(filepath) { | ||
// read from the file, synchronously | ||
@@ -85,6 +85,6 @@ const descriptor = fs.openSync(filepath, 'r'); | ||
} | ||
const bufferSize = Math.min(size, MaxBufferSize); | ||
const buffer = Buffer.alloc(bufferSize); | ||
fs.readSync(descriptor, buffer, 0, bufferSize, 0); | ||
return buffer; | ||
const inputSize = Math.min(size, MaxInputSize); | ||
const input = new Uint8Array(inputSize); | ||
fs.readSync(descriptor, input, 0, inputSize, 0); | ||
return input; | ||
} | ||
@@ -99,8 +99,8 @@ finally { | ||
/** | ||
* @param {Buffer|string} input - buffer or relative/absolute path of the image file | ||
* @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 buffer input | ||
if (Buffer.isBuffer(input)) { | ||
// Handle Uint8Array input | ||
if (input instanceof Uint8Array) { | ||
return lookup(input); | ||
@@ -110,3 +110,3 @@ } | ||
if (typeof input !== 'string' || globalOptions.disabledFS) { | ||
throw new TypeError('invalid invocation. input should be a Buffer'); | ||
throw new TypeError('invalid invocation. input should be a Uint8Array'); | ||
} | ||
@@ -116,18 +116,24 @@ // resolve the file path | ||
if (typeof callback === 'function') { | ||
queue.push(() => asyncFileToBuffer(filepath) | ||
.then((buffer) => process.nextTick(callback, null, lookup(buffer, filepath))) | ||
queue.push(() => readFileAsync(filepath) | ||
.then((input) => process.nextTick(callback, null, lookup(input, filepath))) | ||
.catch(callback)); | ||
} | ||
else { | ||
const buffer = syncFileToBuffer(filepath); | ||
return lookup(buffer, filepath); | ||
const input = readFileSync(filepath); | ||
return lookup(input, filepath); | ||
} | ||
} | ||
exports.imageSize = imageSize; | ||
const disableFS = (v) => { globalOptions.disabledFS = v; }; | ||
const disableFS = (v) => { | ||
globalOptions.disabledFS = v; | ||
}; | ||
exports.disableFS = disableFS; | ||
const disableTypes = (types) => { globalOptions.disabledTypes = types; }; | ||
const disableTypes = (types) => { | ||
globalOptions.disabledTypes = types; | ||
}; | ||
exports.disableTypes = disableTypes; | ||
const setConcurrency = (c) => { queue.concurrency = c; }; | ||
const setConcurrency = (c) => { | ||
queue.concurrency = c; | ||
}; | ||
exports.setConcurrency = setConcurrency; | ||
exports.types = Object.keys(types_1.typeHandlers); | ||
exports.types = Object.keys(index_1.typeHandlers); |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const BMP: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BMP = void 0; | ||
const utils_1 = require("./utils"); | ||
exports.BMP = { | ||
validate(buffer) { | ||
return ('BM' === buffer.toString('ascii', 0, 2)); | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: Math.abs(buffer.readInt32LE(22)), | ||
width: buffer.readUInt32LE(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), | ||
}), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const CUR: IImage; |
@@ -5,16 +5,14 @@ "use strict"; | ||
const ico_1 = require("./ico"); | ||
const utils_1 = require("./utils"); | ||
const TYPE_CURSOR = 2; | ||
exports.CUR = { | ||
validate(buffer) { | ||
const reserved = buffer.readUInt16LE(0); | ||
const imageCount = buffer.readUInt16LE(4); | ||
if (reserved !== 0 || imageCount === 0) { | ||
validate(input) { | ||
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 = buffer.readUInt16LE(2); | ||
const imageType = (0, utils_1.readUInt16LE)(input, 2); | ||
return imageType === TYPE_CURSOR; | ||
}, | ||
calculate(buffer) { | ||
return ico_1.ICO.calculate(buffer); | ||
} | ||
calculate: (input) => ico_1.ICO.calculate(input), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const DDS: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DDS = void 0; | ||
const utils_1 = require("./utils"); | ||
exports.DDS = { | ||
validate(buffer) { | ||
return buffer.readUInt32LE(0) === 0x20534444; | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: buffer.readUInt32LE(12), | ||
width: buffer.readUInt32LE(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), | ||
}), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const GIF: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GIF = void 0; | ||
const utils_1 = require("./utils"); | ||
const gifRegexp = /^GIF8[79]a/; | ||
exports.GIF = { | ||
validate(buffer) { | ||
const signature = buffer.toString('ascii', 0, 6); | ||
return (gifRegexp.test(signature)); | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: buffer.readUInt16LE(8), | ||
width: buffer.readUInt16LE(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), | ||
}), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const ICNS: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ICNS = void 0; | ||
const utils_1 = require("./utils"); | ||
/** | ||
@@ -65,7 +66,7 @@ * ICNS Header | ||
}; | ||
function readImageHeader(buffer, imageOffset) { | ||
function readImageHeader(input, imageOffset) { | ||
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; | ||
return [ | ||
buffer.toString('ascii', imageOffset, imageLengthOffset), | ||
buffer.readUInt32BE(imageLengthOffset) | ||
(0, utils_1.toUTF8String)(input, imageOffset, imageLengthOffset), | ||
(0, utils_1.readUInt32BE)(input, imageLengthOffset), | ||
]; | ||
@@ -78,22 +79,19 @@ } | ||
exports.ICNS = { | ||
validate(buffer) { | ||
return ('icns' === buffer.toString('ascii', 0, 4)); | ||
}, | ||
calculate(buffer) { | ||
const bufferLength = buffer.length; | ||
const fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET); | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 4) === 'icns', | ||
calculate(input) { | ||
const inputLength = input.length; | ||
const fileLength = (0, utils_1.readUInt32BE)(input, FILE_LENGTH_OFFSET); | ||
let imageOffset = SIZE_HEADER; | ||
let imageHeader = readImageHeader(buffer, imageOffset); | ||
let imageHeader = readImageHeader(input, imageOffset); | ||
let imageSize = getImageSize(imageHeader[0]); | ||
imageOffset += imageHeader[1]; | ||
if (imageOffset === fileLength) { | ||
if (imageOffset === fileLength) | ||
return imageSize; | ||
} | ||
const result = { | ||
height: imageSize.height, | ||
images: [imageSize], | ||
width: imageSize.width | ||
width: imageSize.width, | ||
}; | ||
while (imageOffset < fileLength && imageOffset < bufferLength) { | ||
imageHeader = readImageHeader(buffer, imageOffset); | ||
while (imageOffset < fileLength && imageOffset < inputLength) { | ||
imageHeader = readImageHeader(input, imageOffset); | ||
imageSize = getImageSize(imageHeader[0]); | ||
@@ -104,3 +102,3 @@ imageOffset += imageHeader[1]; | ||
return result; | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const ICO: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ICO = void 0; | ||
const utils_1 = require("./utils"); | ||
const TYPE_ICON = 1; | ||
@@ -32,40 +33,37 @@ /** | ||
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; // 16 | ||
function getSizeFromOffset(buffer, offset) { | ||
const value = buffer.readUInt8(offset); | ||
function getSizeFromOffset(input, offset) { | ||
const value = input[offset]; | ||
return value === 0 ? 256 : value; | ||
} | ||
function getImageSize(buffer, imageIndex) { | ||
const offset = SIZE_HEADER + (imageIndex * SIZE_IMAGE_ENTRY); | ||
function getImageSize(input, imageIndex) { | ||
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY; | ||
return { | ||
height: getSizeFromOffset(buffer, offset + 1), | ||
width: getSizeFromOffset(buffer, offset) | ||
height: getSizeFromOffset(input, offset + 1), | ||
width: getSizeFromOffset(input, offset), | ||
}; | ||
} | ||
exports.ICO = { | ||
validate(buffer) { | ||
const reserved = buffer.readUInt16LE(0); | ||
const imageCount = buffer.readUInt16LE(4); | ||
if (reserved !== 0 || imageCount === 0) { | ||
validate(input) { | ||
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 = buffer.readUInt16LE(2); | ||
const imageType = (0, utils_1.readUInt16LE)(input, 2); | ||
return imageType === TYPE_ICON; | ||
}, | ||
calculate(buffer) { | ||
const nbImages = buffer.readUInt16LE(4); | ||
const imageSize = getImageSize(buffer, 0); | ||
if (nbImages === 1) { | ||
calculate(input) { | ||
const nbImages = (0, utils_1.readUInt16LE)(input, 4); | ||
const imageSize = getImageSize(input, 0); | ||
if (nbImages === 1) | ||
return imageSize; | ||
} | ||
const imgs = [imageSize]; | ||
for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) { | ||
imgs.push(getImageSize(buffer, imageIndex)); | ||
imgs.push(getImageSize(input, imageIndex)); | ||
} | ||
const result = { | ||
return { | ||
height: imageSize.height, | ||
images: imgs, | ||
width: imageSize.width | ||
width: imageSize.width, | ||
}; | ||
return result; | ||
} | ||
}, | ||
}; |
@@ -1,3 +0,2 @@ | ||
/// <reference types="node" /> | ||
export interface ISize { | ||
export type ISize = { | ||
width: number | undefined; | ||
@@ -7,9 +6,9 @@ height: number | undefined; | ||
type?: string; | ||
} | ||
export interface ISizeCalculationResult extends ISize { | ||
}; | ||
export type ISizeCalculationResult = { | ||
images?: ISize[]; | ||
} | ||
export interface IImage { | ||
validate: (buffer: Buffer) => boolean; | ||
calculate: (buffer: Buffer, filepath?: string) => ISizeCalculationResult; | ||
} | ||
} & ISize; | ||
export type IImage = { | ||
validate: (input: Uint8Array) => boolean; | ||
calculate: (input: Uint8Array, filepath?: string) => ISizeCalculationResult; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const J2C: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.J2C = void 0; | ||
const utils_1 = require("./utils"); | ||
exports.J2C = { | ||
validate(buffer) { | ||
// TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC | ||
return buffer.toString('hex', 0, 4) === 'ff4fff51'; | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: buffer.readUInt32BE(12), | ||
width: buffer.readUInt32BE(8), | ||
}; | ||
} | ||
// TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC | ||
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), | ||
}), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const JP2: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.JP2 = void 0; | ||
const BoxTypes = { | ||
ftyp: '66747970', | ||
ihdr: '69686472', | ||
jp2h: '6a703268', | ||
jp__: '6a502020', | ||
rreq: '72726571', | ||
xml_: '786d6c20' | ||
}; | ||
const calculateRREQLength = (box) => { | ||
const unit = box.readUInt8(0); | ||
let offset = 1 + (2 * unit); | ||
const numStdFlags = box.readUInt16BE(offset); | ||
const flagsLength = numStdFlags * (2 + unit); | ||
offset = offset + 2 + flagsLength; | ||
const numVendorFeatures = box.readUInt16BE(offset); | ||
const featuresLength = numVendorFeatures * (16 + unit); | ||
return offset + 2 + featuresLength; | ||
}; | ||
const parseIHDR = (box) => { | ||
return { | ||
height: box.readUInt32BE(4), | ||
width: box.readUInt32BE(8), | ||
}; | ||
}; | ||
const utils_1 = require("./utils"); | ||
exports.JP2 = { | ||
validate(buffer) { | ||
const signature = buffer.toString('hex', 4, 8); | ||
const signatureLength = buffer.readUInt32BE(0); | ||
if (signature !== BoxTypes.jp__ || signatureLength < 1) { | ||
validate(input) { | ||
if ((0, utils_1.readUInt32BE)(input, 4) !== 0x6a502020 || (0, utils_1.readUInt32BE)(input, 0) < 1) | ||
return false; | ||
const ftypBox = (0, utils_1.findBox)(input, 'ftyp', 0); | ||
if (!ftypBox) | ||
return false; | ||
return (0, utils_1.readUInt32BE)(input, ftypBox.offset + 4) === 0x66747970; | ||
}, | ||
calculate(input) { | ||
const jp2hBox = (0, utils_1.findBox)(input, 'jp2h', 0); | ||
const ihdrBox = jp2hBox && (0, utils_1.findBox)(input, 'ihdr', jp2hBox.offset + 8); | ||
if (ihdrBox) { | ||
return { | ||
height: (0, utils_1.readUInt32BE)(input, ihdrBox.offset + 8), | ||
width: (0, utils_1.readUInt32BE)(input, ihdrBox.offset + 12), | ||
}; | ||
} | ||
const ftypeBoxStart = signatureLength + 4; | ||
const ftypBoxLength = buffer.readUInt32BE(signatureLength); | ||
const ftypBox = buffer.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength); | ||
return ftypBox.toString('hex', 0, 4) === BoxTypes.ftyp; | ||
throw new TypeError('Unsupported JPEG 2000 format'); | ||
}, | ||
calculate(buffer) { | ||
const signatureLength = buffer.readUInt32BE(0); | ||
const ftypBoxLength = buffer.readUInt16BE(signatureLength + 2); | ||
let offset = signatureLength + 4 + ftypBoxLength; | ||
const nextBoxType = buffer.toString('hex', offset, offset + 4); | ||
switch (nextBoxType) { | ||
case BoxTypes.rreq: | ||
// WHAT ARE THESE 4 BYTES????? | ||
// eslint-disable-next-line no-case-declarations | ||
const MAGIC = 4; | ||
offset = offset + 4 + MAGIC + calculateRREQLength(buffer.slice(offset + 4)); | ||
return parseIHDR(buffer.slice(offset + 8, offset + 24)); | ||
case BoxTypes.jp2h: | ||
return parseIHDR(buffer.slice(offset + 8, offset + 24)); | ||
default: | ||
throw new TypeError('Unsupported header found: ' + buffer.toString('ascii', offset, offset + 4)); | ||
} | ||
} | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const JPG: IImage; |
@@ -8,3 +8,3 @@ "use strict"; | ||
exports.JPG = void 0; | ||
const readUInt_1 = require("../readUInt"); | ||
const utils_1 = require("./utils"); | ||
const EXIF_MARKER = '45786966'; | ||
@@ -19,9 +19,9 @@ const APP1_DATA_SIZE_BYTES = 2; | ||
const NUM_DIRECTORY_ENTRIES_BYTES = 2; | ||
function isEXIF(buffer) { | ||
return (buffer.toString('hex', 2, 6) === EXIF_MARKER); | ||
function isEXIF(input) { | ||
return (0, utils_1.toHexString)(input, 2, 6) === EXIF_MARKER; | ||
} | ||
function extractSize(buffer, index) { | ||
function extractSize(input, index) { | ||
return { | ||
height: buffer.readUInt16BE(index), | ||
width: buffer.readUInt16BE(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, readUInt_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, readUInt_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, readUInt_1.readUInt)(block, 16, 2, isBigEndian); | ||
const dataFormat = (0, utils_1.readUInt)(block, 16, 2, isBigEndian); | ||
if (dataFormat !== 3) { | ||
@@ -58,15 +60,15 @@ return; | ||
// if there would more than 4 bytes in total it's a pointer | ||
const numberOfComponents = (0, readUInt_1.readUInt)(block, 32, 4, isBigEndian); | ||
const numberOfComponents = (0, utils_1.readUInt)(block, 32, 4, isBigEndian); | ||
if (numberOfComponents !== 1) { | ||
return; | ||
} | ||
return (0, readUInt_1.readUInt)(block, 16, 8, isBigEndian); | ||
return (0, utils_1.readUInt)(block, 16, 8, isBigEndian); | ||
} | ||
} | ||
} | ||
function validateExifBlock(buffer, index) { | ||
function validateExifBlock(input, index) { | ||
// Skip APP1 Data Size | ||
const exifBlock = buffer.slice(APP1_DATA_SIZE_BYTES, index); | ||
const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); | ||
// Consider byte alignment | ||
const byteAlign = exifBlock.toString('hex', 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 | ||
@@ -79,36 +81,34 @@ const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; | ||
} | ||
function validateBuffer(buffer, index) { | ||
function validateInput(input, index) { | ||
// index should be within buffer limits | ||
if (index > buffer.length) { | ||
if (index > input.length) { | ||
throw new TypeError('Corrupt JPG, exceeded buffer limits'); | ||
} | ||
// Every JPEG block must begin with a 0xFF | ||
if (buffer[index] !== 0xFF) { | ||
throw new TypeError('Invalid JPG, marker table corrupted'); | ||
} | ||
} | ||
exports.JPG = { | ||
validate(buffer) { | ||
const SOIMarker = buffer.toString('hex', 0, 2); | ||
return ('ffd8' === SOIMarker); | ||
}, | ||
calculate(buffer) { | ||
validate: (input) => (0, utils_1.toHexString)(input, 0, 2) === 'ffd8', | ||
calculate(input) { | ||
// Skip 4 chars, they are for signature | ||
buffer = buffer.slice(4); | ||
input = input.slice(4); | ||
let orientation; | ||
let next; | ||
while (buffer.length) { | ||
while (input.length) { | ||
// read length of the next block | ||
const i = buffer.readUInt16BE(0); | ||
if (isEXIF(buffer)) { | ||
orientation = validateExifBlock(buffer, i); | ||
const i = (0, utils_1.readUInt16BE)(input, 0); | ||
// Every JPEG block must begin with a 0xFF | ||
if (input[i] !== 0xff) { | ||
input = input.slice(1); | ||
continue; | ||
} | ||
if (isEXIF(input)) { | ||
orientation = validateExifBlock(input, i); | ||
} | ||
// ensure correct format | ||
validateBuffer(buffer, i); | ||
validateInput(input, i); | ||
// 0xFFC0 is baseline standard(SOF) | ||
// 0xFFC1 is baseline optimized(SOF) | ||
// 0xFFC2 is progressive(SOF2) | ||
next = buffer[i + 1]; | ||
if (next === 0xC0 || next === 0xC1 || next === 0xC2) { | ||
const size = extractSize(buffer, i + 5); | ||
next = input[i + 1]; | ||
if (next === 0xc0 || next === 0xc1 || next === 0xc2) { | ||
const size = extractSize(input, i + 5); | ||
// TODO: is orientation=0 a valid answer here? | ||
@@ -121,10 +121,10 @@ if (!orientation) { | ||
orientation, | ||
width: size.width | ||
width: size.width, | ||
}; | ||
} | ||
// move to the next block | ||
buffer = buffer.slice(i + 2); | ||
input = input.slice(i + 2); | ||
} | ||
throw new TypeError('Invalid JPG, no size found'); | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const KTX: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.KTX = void 0; | ||
const SIGNATURE = 'KTX 11'; | ||
const utils_1 = require("./utils"); | ||
exports.KTX = { | ||
validate(buffer) { | ||
return SIGNATURE === buffer.toString('ascii', 1, 7); | ||
validate: (input) => { | ||
const signature = (0, utils_1.toUTF8String)(input, 1, 7); | ||
return ['KTX 11', 'KTX 20'].includes(signature); | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: buffer.readUInt32LE(40), | ||
width: buffer.readUInt32LE(36), | ||
}; | ||
} | ||
calculate: (input) => { | ||
const type = input[5] === 0x31 ? 'ktx' : 'ktx2'; | ||
const offset = type === 'ktx' ? 36 : 20; | ||
return ({ | ||
height: (0, utils_1.readUInt32LE)(input, offset + 4), | ||
width: (0, utils_1.readUInt32LE)(input, offset), | ||
type, | ||
}); | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PNG: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PNG = void 0; | ||
const utils_1 = require("./utils"); | ||
const pngSignature = 'PNG\r\n\x1a\n'; | ||
@@ -9,7 +10,7 @@ const pngImageHeaderChunkName = 'IHDR'; | ||
exports.PNG = { | ||
validate(buffer) { | ||
if (pngSignature === buffer.toString('ascii', 1, 8)) { | ||
let chunkName = buffer.toString('ascii', 12, 16); | ||
validate(input) { | ||
if (pngSignature === (0, utils_1.toUTF8String)(input, 1, 8)) { | ||
let chunkName = (0, utils_1.toUTF8String)(input, 12, 16); | ||
if (chunkName === pngFriedChunkName) { | ||
chunkName = buffer.toString('ascii', 28, 32); | ||
chunkName = (0, utils_1.toUTF8String)(input, 28, 32); | ||
} | ||
@@ -23,14 +24,14 @@ if (chunkName !== pngImageHeaderChunkName) { | ||
}, | ||
calculate(buffer) { | ||
if (buffer.toString('ascii', 12, 16) === pngFriedChunkName) { | ||
calculate(input) { | ||
if ((0, utils_1.toUTF8String)(input, 12, 16) === pngFriedChunkName) { | ||
return { | ||
height: buffer.readUInt32BE(36), | ||
width: buffer.readUInt32BE(32) | ||
height: (0, utils_1.readUInt32BE)(input, 36), | ||
width: (0, utils_1.readUInt32BE)(input, 32), | ||
}; | ||
} | ||
return { | ||
height: buffer.readUInt32BE(20), | ||
width: buffer.readUInt32BE(16) | ||
height: (0, utils_1.readUInt32BE)(input, 20), | ||
width: (0, utils_1.readUInt32BE)(input, 16), | ||
}; | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PNM: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PNM = void 0; | ||
const utils_1 = require("./utils"); | ||
const PNMTypes = { | ||
@@ -12,5 +13,4 @@ P1: 'pbm/ascii', | ||
P7: 'pam', | ||
PF: 'pfm' | ||
PF: 'pfm', | ||
}; | ||
const Signatures = Object.keys(PNMTypes); | ||
const handlers = { | ||
@@ -55,3 +55,3 @@ default: (lines) => { | ||
height: size.height, | ||
width: size.width | ||
width: size.width, | ||
}; | ||
@@ -62,17 +62,14 @@ } | ||
} | ||
} | ||
}, | ||
}; | ||
exports.PNM = { | ||
validate(buffer) { | ||
const signature = buffer.toString('ascii', 0, 2); | ||
return Signatures.includes(signature); | ||
}, | ||
calculate(buffer) { | ||
const signature = buffer.toString('ascii', 0, 2); | ||
validate: (input) => (0, utils_1.toUTF8String)(input, 0, 2) in PNMTypes, | ||
calculate(input) { | ||
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 = buffer.toString('ascii', 3).split(/[\r\n]+/); | ||
const lines = (0, utils_1.toUTF8String)(input, 3).split(/[\r\n]+/); | ||
const handler = handlers[type] || handlers.default; | ||
return handler(lines); | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const PSD: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PSD = void 0; | ||
const utils_1 = require("./utils"); | ||
exports.PSD = { | ||
validate(buffer) { | ||
return ('8BPS' === buffer.toString('ascii', 0, 4)); | ||
}, | ||
calculate(buffer) { | ||
return { | ||
height: buffer.readUInt32BE(14), | ||
width: buffer.readUInt32BE(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), | ||
}), | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const SVG: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SVG = void 0; | ||
const utils_1 = require("./utils"); | ||
const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/; | ||
@@ -17,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, | ||
}; | ||
@@ -36,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]), | ||
}; | ||
@@ -76,8 +77,6 @@ } | ||
exports.SVG = { | ||
validate(buffer) { | ||
const str = String(buffer); | ||
return svgReg.test(str); | ||
}, | ||
calculate(buffer) { | ||
const root = buffer.toString('utf8').match(extractorRegExps.root); | ||
// 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, utils_1.toUTF8String)(input).match(extractorRegExps.root); | ||
if (root) { | ||
@@ -93,3 +92,3 @@ const attrs = parseAttributes(root[0]); | ||
throw new TypeError('Invalid SVG'); | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const TGA: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TGA = void 0; | ||
const utils_1 = require("./utils"); | ||
exports.TGA = { | ||
validate(buffer) { | ||
return buffer.readUInt16LE(0) === 0 && buffer.readUInt16LE(4) === 0; | ||
validate(input) { | ||
return (0, utils_1.readUInt16LE)(input, 0) === 0 && (0, utils_1.readUInt16LE)(input, 4) === 0; | ||
}, | ||
calculate(buffer) { | ||
calculate(input) { | ||
return { | ||
height: buffer.readUInt16LE(14), | ||
width: buffer.readUInt16LE(12), | ||
height: (0, utils_1.readUInt16LE)(input, 14), | ||
width: (0, utils_1.readUInt16LE)(input, 12), | ||
}; | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const TIFF: IImage; |
@@ -7,6 +7,6 @@ "use strict"; | ||
const fs = require("fs"); | ||
const readUInt_1 = require("../readUInt"); | ||
const utils_1 = require("./utils"); | ||
// Read IFD (image-file-directory) into a buffer | ||
function readIFD(buffer, filepath, isBigEndian) { | ||
const ifdOffset = (0, readUInt_1.readUInt)(buffer, 32, 4, isBigEndian); | ||
function readIFD(input, filepath, isBigEndian) { | ||
const ifdOffset = (0, utils_1.readUInt)(input, 32, 4, isBigEndian); | ||
// read only till the end of the file | ||
@@ -19,3 +19,3 @@ let bufferSize = 1024; | ||
// populate the buffer | ||
const endBuffer = Buffer.alloc(bufferSize); | ||
const endBuffer = new Uint8Array(bufferSize); | ||
const descriptor = fs.openSync(filepath, 'r'); | ||
@@ -27,21 +27,21 @@ fs.readSync(descriptor, endBuffer, 0, bufferSize, ifdOffset); | ||
// TIFF values seem to be messed up on Big-Endian, this helps | ||
function readValue(buffer, isBigEndian) { | ||
const low = (0, readUInt_1.readUInt)(buffer, 16, 8, isBigEndian); | ||
const high = (0, readUInt_1.readUInt)(buffer, 16, 10, isBigEndian); | ||
function readValue(input, 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; | ||
} | ||
// move to the next tag | ||
function nextTag(buffer) { | ||
if (buffer.length > 24) { | ||
return buffer.slice(12); | ||
function nextTag(input) { | ||
if (input.length > 24) { | ||
return input.slice(12); | ||
} | ||
} | ||
// Extract IFD tags from TIFF metadata | ||
function extractTags(buffer, isBigEndian) { | ||
function extractTags(input, isBigEndian) { | ||
const tags = {}; | ||
let temp = buffer; | ||
let temp = input; | ||
while (temp && temp.length) { | ||
const code = (0, readUInt_1.readUInt)(temp, 16, 0, isBigEndian); | ||
const type = (0, readUInt_1.readUInt)(temp, 16, 2, isBigEndian); | ||
const length = (0, readUInt_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 | ||
@@ -64,4 +64,4 @@ if (code === 0) { | ||
// Test if the TIFF is Big Endian or Little Endian | ||
function determineEndianness(buffer) { | ||
const signature = buffer.toString('ascii', 0, 2); | ||
function determineEndianness(input) { | ||
const signature = (0, utils_1.toUTF8String)(input, 0, 2); | ||
if ('II' === signature) { | ||
@@ -81,6 +81,4 @@ return 'LE'; | ||
exports.TIFF = { | ||
validate(buffer) { | ||
return signatures.includes(buffer.toString('hex', 0, 4)); | ||
}, | ||
calculate(buffer, filepath) { | ||
validate: (input) => signatures.includes((0, utils_1.toHexString)(input, 0, 4)), | ||
calculate(input, filepath) { | ||
if (!filepath) { | ||
@@ -90,5 +88,5 @@ throw new TypeError('Tiff doesn\'t support buffer'); | ||
// Determine BE/LE | ||
const isBigEndian = determineEndianness(buffer) === 'BE'; | ||
const isBigEndian = determineEndianness(input) === 'BE'; | ||
// read the IFD | ||
const ifdBuffer = readIFD(buffer, filepath, isBigEndian); | ||
const ifdBuffer = readIFD(input, filepath, isBigEndian); | ||
// extract the tags from the IFD | ||
@@ -102,3 +100,3 @@ const tags = extractTags(ifdBuffer, isBigEndian); | ||
return { height, width }; | ||
} | ||
}, | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { IImage } from './interface'; | ||
import type { IImage } from './interface'; | ||
export declare const WEBP: IImage; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.WEBP = void 0; | ||
function calculateExtended(buffer) { | ||
const utils_1 = require("./utils"); | ||
function calculateExtended(input) { | ||
return { | ||
height: 1 + buffer.readUIntLE(7, 3), | ||
width: 1 + buffer.readUIntLE(4, 3) | ||
height: 1 + (0, utils_1.readUInt24LE)(input, 7), | ||
width: 1 + (0, utils_1.readUInt24LE)(input, 4), | ||
}; | ||
} | ||
function calculateLossless(buffer) { | ||
function calculateLossless(input) { | ||
return { | ||
height: 1 + (((buffer[4] & 0xF) << 10) | (buffer[3] << 2) | ((buffer[2] & 0xC0) >> 6)), | ||
width: 1 + (((buffer[2] & 0x3F) << 8) | buffer[1]) | ||
height: 1 + | ||
(((input[4] & 0xf) << 10) | (input[3] << 2) | ((input[2] & 0xc0) >> 6)), | ||
width: 1 + (((input[2] & 0x3f) << 8) | input[1]), | ||
}; | ||
} | ||
function calculateLossy(buffer) { | ||
function calculateLossy(input) { | ||
// `& 0x3fff` returns the last 14 bits | ||
// TO-DO: include webp scaling in the calculations | ||
return { | ||
height: buffer.readInt16LE(8) & 0x3fff, | ||
width: buffer.readInt16LE(6) & 0x3fff | ||
height: (0, utils_1.readInt16LE)(input, 8) & 0x3fff, | ||
width: (0, utils_1.readInt16LE)(input, 6) & 0x3fff, | ||
}; | ||
} | ||
exports.WEBP = { | ||
validate(buffer) { | ||
const riffHeader = 'RIFF' === buffer.toString('ascii', 0, 4); | ||
const webpHeader = 'WEBP' === buffer.toString('ascii', 8, 12); | ||
const vp8Header = 'VP8' === buffer.toString('ascii', 12, 15); | ||
return (riffHeader && webpHeader && vp8Header); | ||
validate(input) { | ||
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(buffer) { | ||
const chunkHeader = buffer.toString('ascii', 12, 16); | ||
buffer = buffer.slice(20, 30); | ||
calculate(input) { | ||
const chunkHeader = (0, utils_1.toUTF8String)(input, 12, 16); | ||
input = input.slice(20, 30); | ||
// Extended webp stream signature | ||
if (chunkHeader === 'VP8X') { | ||
const extendedHeader = buffer[0]; | ||
const extendedHeader = input[0]; | ||
const validStart = (extendedHeader & 0xc0) === 0; | ||
const validEnd = (extendedHeader & 0x01) === 0; | ||
if (validStart && validEnd) { | ||
return calculateExtended(buffer); | ||
return calculateExtended(input); | ||
} | ||
@@ -48,12 +50,12 @@ else { | ||
// Lossless webp stream signature | ||
if (chunkHeader === 'VP8 ' && buffer[0] !== 0x2f) { | ||
return calculateLossy(buffer); | ||
if (chunkHeader === 'VP8 ' && input[0] !== 0x2f) { | ||
return calculateLossy(input); | ||
} | ||
// Lossy webp stream signature | ||
const signature = buffer.toString('hex', 3, 6); | ||
const signature = (0, utils_1.toHexString)(input, 3, 6); | ||
if (chunkHeader === 'VP8L' && signature !== '9d012a') { | ||
return calculateLossless(buffer); | ||
return calculateLossless(input); | ||
} | ||
throw new TypeError('Invalid WebP'); | ||
} | ||
}, | ||
}; |
{ | ||
"name": "image-size", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "get dimensions of any image file", | ||
@@ -12,7 +12,9 @@ "main": "dist/index.js", | ||
"engines": { | ||
"node": ">=14.0.0" | ||
"node": ">=18.0.0" | ||
}, | ||
"packageManager": "yarn@3.5.1", | ||
"bin": "bin/image-size.js", | ||
"scripts": { | ||
"pretest": "eslint --ext .ts,.js bin lib specs", | ||
"lint": "eslint --ext .ts,.js bin lib specs", | ||
"format": "prettier --write lib specs", | ||
"test": "nyc mocha", | ||
@@ -31,14 +33,17 @@ "clean": "rm -rf dist docs", | ||
"height", | ||
"png", | ||
"jpeg", | ||
"avif", | ||
"bmp", | ||
"cur", | ||
"gif", | ||
"heic", | ||
"heif", | ||
"icns", | ||
"ico", | ||
"jpeg", | ||
"png", | ||
"psd", | ||
"svg", | ||
"tga", | ||
"tiff", | ||
"webp", | ||
"svg", | ||
"icns", | ||
"ico", | ||
"cur" | ||
"webp" | ||
], | ||
@@ -49,23 +54,29 @@ "repository": "git://github.com/image-size/image-size.git", | ||
"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.5", | ||
"@types/glob": "8.1.0", | ||
"@types/mocha": "10.0.1", | ||
"@types/node": "18.16.16", | ||
"@types/sinon": "10.0.15", | ||
"@typescript-eslint/eslint-plugin": "5.59.8", | ||
"@typescript-eslint/parser": "5.59.8", | ||
"chai": "4.3.7", | ||
"eslint": "8.41.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-plugin-prettier": "4.2.1", | ||
"glob": "10.2.6", | ||
"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" | ||
"prettier": "2.8.8", | ||
"sinon": "15.1.0", | ||
"ts-node": "10.9.1", | ||
"typedoc": "0.24.7", | ||
"typescript": "5.0.4" | ||
}, | ||
"nyc": { | ||
"include": "lib", | ||
"exclude": "specs/*.spec.ts" | ||
}, | ||
"dependencies": { | ||
"queue": "6.0.2" | ||
}, | ||
"packageManager": "yarn@3.2.0" | ||
} | ||
} |
112
Readme.md
@@ -11,19 +11,20 @@ # 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 | ||
- HEIC (HEIF, AVCI, AVIF) | ||
- ICNS | ||
- ICO | ||
- J2C | ||
- JP2 | ||
- JPEG | ||
- KTX (1 and 2) | ||
- PNG | ||
- PNM (PAM, PBM, PFM, PGM, PPM) | ||
- PSD | ||
- SVG | ||
- TGA | ||
- TIFF | ||
- WebP | ||
@@ -45,4 +46,4 @@ ## Programmatic Usage | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const dimensions = sizeOf('images/funny-cats.png') | ||
const sizeOf = require("image-size") | ||
const dimensions = sizeOf("images/funny-cats.png") | ||
console.log(dimensions.width, dimensions.height) | ||
@@ -54,4 +55,4 @@ ``` | ||
```javascript | ||
const sizeOf = require('image-size') | ||
sizeOf('images/funny-cats.png', function (err, dimensions) { | ||
const sizeOf = require("image-size") | ||
sizeOf("images/funny-cats.png", function (err, dimensions) { | ||
console.log(dimensions.width, dimensions.height) | ||
@@ -67,3 +68,3 @@ }) | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const sizeOf = require("image-size") | ||
sizeOf.setConcurrency(123456) | ||
@@ -75,7 +76,9 @@ ``` | ||
```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)) | ||
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)) | ||
``` | ||
@@ -86,7 +89,6 @@ | ||
```javascript | ||
const { promisify } = require('util') | ||
const sizeOf = promisify(require('image-size')) | ||
(async () => { | ||
const { promisify } = require("util") | ||
const sizeOf = promisify(require("image-size"))(async () => { | ||
try { | ||
const dimensions = await sizeOf('images/funny-cats.png') | ||
const dimensions = await sizeOf("images/funny-cats.png") | ||
console.log(dimensions.width, dimensions.height) | ||
@@ -96,3 +98,3 @@ } catch (err) { | ||
} | ||
})().then(c => console.log(c)) | ||
})().then((c) => console.log(c)) | ||
``` | ||
@@ -107,4 +109,4 @@ | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const images = sizeOf('images/multi-size.ico').images | ||
const sizeOf = require("image-size") | ||
const images = sizeOf("images/multi-size.ico").images | ||
for (const dimensions of images) { | ||
@@ -118,8 +120,8 @@ console.log(dimensions.width, dimensions.height) | ||
```javascript | ||
const url = require('url') | ||
const http = require('http') | ||
const url = require("url") | ||
const http = require("http") | ||
const sizeOf = require('image-size') | ||
const sizeOf = require("image-size") | ||
const imgUrl = 'http://my-amazing-website.com/image.jpeg' | ||
const imgUrl = "http://my-amazing-website.com/image.jpeg" | ||
const options = url.parse(imgUrl) | ||
@@ -129,8 +131,10 @@ | ||
const chunks = [] | ||
response.on('data', function (chunk) { | ||
chunks.push(chunk) | ||
}).on('end', function() { | ||
const buffer = Buffer.concat(chunks) | ||
console.log(sizeOf(buffer)) | ||
}) | ||
response | ||
.on("data", function (chunk) { | ||
chunks.push(chunk) | ||
}) | ||
.on("end", function () { | ||
const buffer = Buffer.concat(chunks) | ||
console.log(sizeOf(buffer)) | ||
}) | ||
}) | ||
@@ -143,10 +147,12 @@ ``` | ||
### Disabling certain image types | ||
```javascript | ||
const imageSize = require('image-size') | ||
imageSize.disableTypes(['tiff', 'ico']) | ||
const imageSize = require("image-size") | ||
imageSize.disableTypes(["tiff", "ico"]) | ||
``` | ||
### Disabling all file-system reads | ||
```javascript | ||
const imageSize = require('image-size') | ||
const imageSize = require("image-size") | ||
imageSize.disableFS(true) | ||
@@ -160,4 +166,4 @@ ``` | ||
```javascript | ||
const sizeOf = require('image-size') | ||
const dimensions = sizeOf('images/photo.jpeg') | ||
const sizeOf = require("image-size") | ||
const dimensions = sizeOf("images/photo.jpeg") | ||
console.log(dimensions.orientation) | ||
@@ -184,10 +190,2 @@ ``` | ||
## Hosted API | ||
We also provide a hosted API for image-size which may simplify your use case. | ||
<a href="https://image-size.saasify.sh"> | ||
<img src="https://badges.saasify.sh?text=View%20Hosted%20API" height="40"/> | ||
</a> | ||
## Credits | ||
@@ -194,0 +192,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
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
49905
50
1227
19
184