Socket
Socket
Sign inDemoInstall

image-meta

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

image-meta - npm Package Compare versions

Comparing version 0.0.0 to 0.0.1

CHANGELOG.md

7

dist/index.d.ts

@@ -17,5 +17,6 @@ /// <reference types="node" />

*/
declare function imageSize(input: Buffer): ISizeCalculationResult | void;
declare const types: string[]
declare function imageMeta(input: Buffer): ISizeCalculationResult | void;
declare const types: string[];
export { imageSize, types }
export default imageMeta;
export { types };

@@ -1,47 +0,47 @@

'use strict'
'use strict';
Object.defineProperty(exports, '__esModule', { value: true })
Object.defineProperty(exports, '__esModule', { value: true });
const BMP = {
validate (buffer) {
return buffer.toString('ascii', 0, 2) === 'BM'
validate(buffer) {
return buffer.toString("ascii", 0, 2) === "BM";
},
calculate (buffer) {
calculate(buffer) {
return {
height: Math.abs(buffer.readInt32LE(22)),
width: buffer.readUInt32LE(18)
}
};
}
}
};
const TYPE_ICON = 1
const SIZE_HEADER = 2 + 2 + 2
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4
function getSizeFromOffset (buffer, offset) {
const value = buffer.readUInt8(offset)
return value === 0 ? 256 : value
const TYPE_ICON = 1;
const SIZE_HEADER = 2 + 2 + 2;
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;
function getSizeFromOffset(buffer, offset) {
const value = buffer.readUInt8(offset);
return value === 0 ? 256 : value;
}
function getImageSize (buffer, imageIndex) {
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY
function getImageSize(buffer, imageIndex) {
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY;
return {
height: getSizeFromOffset(buffer, offset + 1),
width: getSizeFromOffset(buffer, offset)
}
};
}
const ICO = {
validate (buffer) {
validate(buffer) {
if (buffer.readUInt16LE(0) !== 0) {
return false
return false;
}
return buffer.readUInt16LE(2) === TYPE_ICON
return buffer.readUInt16LE(2) === TYPE_ICON;
},
calculate (buffer) {
const nbImages = buffer.readUInt16LE(4)
const imageSize = getImageSize(buffer, 0)
calculate(buffer) {
const nbImages = buffer.readUInt16LE(4);
const imageSize = getImageSize(buffer, 0);
if (nbImages === 1) {
return imageSize
return imageSize;
}
const imgs = [imageSize]
const imgs = [imageSize];
for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
imgs.push(getImageSize(buffer, imageIndex))
imgs.push(getImageSize(buffer, imageIndex));
}

@@ -52,56 +52,56 @@ const result = {

width: imageSize.width
}
return result
};
return result;
}
}
};
const TYPE_CURSOR = 2
const TYPE_CURSOR = 2;
const CUR = {
validate (buffer) {
validate(buffer) {
if (buffer.readUInt16LE(0) !== 0) {
return false
return false;
}
return buffer.readUInt16LE(2) === TYPE_CURSOR
return buffer.readUInt16LE(2) === TYPE_CURSOR;
},
calculate (buffer) {
return ICO.calculate(buffer)
calculate(buffer) {
return ICO.calculate(buffer);
}
}
};
const DDS = {
validate (buffer) {
return buffer.readUInt32LE(0) === 542327876
validate(buffer) {
return buffer.readUInt32LE(0) === 542327876;
},
calculate (buffer) {
calculate(buffer) {
return {
height: buffer.readUInt32LE(12),
width: buffer.readUInt32LE(16)
}
};
}
}
};
const gifRegexp = /^GIF8[79]a/
const gifRegexp = /^GIF8[79]a/;
const GIF = {
validate (buffer) {
const signature = buffer.toString('ascii', 0, 6)
return gifRegexp.test(signature)
validate(buffer) {
const signature = buffer.toString("ascii", 0, 6);
return gifRegexp.test(signature);
},
calculate (buffer) {
calculate(buffer) {
return {
height: buffer.readUInt16LE(8),
width: buffer.readUInt16LE(6)
}
};
}
}
};
const SIZE_HEADER$1 = 4 + 4
const FILE_LENGTH_OFFSET = 4
const ENTRY_LENGTH_OFFSET = 4
const SIZE_HEADER$1 = 4 + 4;
const FILE_LENGTH_OFFSET = 4;
const ENTRY_LENGTH_OFFSET = 4;
const ICON_TYPE_SIZE = {
ICON: 32,
'ICN#': 32,
'icm#': 16,
"ICN#": 32,
"icm#": 16,
icm4: 16,
icm8: 16,
'ics#': 16,
"ics#": 16,
ics4: 16,

@@ -132,27 +132,27 @@ ics8: 16,

ic10: 1024
}
function readImageHeader (buffer, imageOffset) {
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET
};
function readImageHeader(buffer, imageOffset) {
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
return [
buffer.toString('ascii', imageOffset, imageLengthOffset),
buffer.toString("ascii", imageOffset, imageLengthOffset),
buffer.readUInt32BE(imageLengthOffset)
]
];
}
function getImageSize$1 (type) {
const size = ICON_TYPE_SIZE[type]
return { width: size, height: size, type }
function getImageSize$1(type) {
const size = ICON_TYPE_SIZE[type];
return {width: size, height: size, type};
}
const ICNS = {
validate (buffer) {
return buffer.toString('ascii', 0, 4) === 'icns'
validate(buffer) {
return buffer.toString("ascii", 0, 4) === "icns";
},
calculate (buffer) {
const bufferLength = buffer.length
const fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET)
let imageOffset = SIZE_HEADER$1
let imageHeader = readImageHeader(buffer, imageOffset)
let imageSize = getImageSize$1(imageHeader[0])
imageOffset += imageHeader[1]
calculate(buffer) {
const bufferLength = buffer.length;
const fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET);
let imageOffset = SIZE_HEADER$1;
let imageHeader = readImageHeader(buffer, imageOffset);
let imageSize = getImageSize$1(imageHeader[0]);
imageOffset += imageHeader[1];
if (imageOffset === fileLength) {
return imageSize
return imageSize;
}

@@ -163,43 +163,43 @@ const result = {

width: imageSize.width
}
};
while (imageOffset < fileLength && imageOffset < bufferLength) {
imageHeader = readImageHeader(buffer, imageOffset)
imageSize = getImageSize$1(imageHeader[0])
imageOffset += imageHeader[1]
result.images.push(imageSize)
imageHeader = readImageHeader(buffer, imageOffset);
imageSize = getImageSize$1(imageHeader[0]);
imageOffset += imageHeader[1];
result.images.push(imageSize);
}
return result
return result;
}
}
};
const J2C = {
validate (buffer) {
return buffer.toString('hex', 0, 4) === 'ff4fff51'
validate(buffer) {
return buffer.toString("hex", 0, 4) === "ff4fff51";
},
calculate (buffer) {
calculate(buffer) {
return {
height: buffer.readUInt32BE(12),
width: buffer.readUInt32BE(8)
}
};
}
}
};
const BoxTypes = {
ftyp: '66747970',
ihdr: '69686472',
jp2h: '6a703268',
jp__: '6a502020',
rreq: '72726571',
xml_: '786d6c20'
}
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 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) => {

@@ -209,120 +209,120 @@ return {

width: box.readUInt32BE(8)
}
}
};
};
const JP2 = {
validate (buffer) {
const signature = buffer.toString('hex', 4, 8)
const signatureLength = buffer.readUInt32BE(0)
validate(buffer) {
const signature = buffer.toString("hex", 4, 8);
const signatureLength = buffer.readUInt32BE(0);
if (signature !== BoxTypes.jp__ || signatureLength < 1) {
return false
return false;
}
const ftypeBoxStart = signatureLength + 4
const ftypBoxLength = buffer.readUInt32BE(signatureLength)
const ftypBox = buffer.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength)
return ftypBox.toString('hex', 0, 4) === BoxTypes.ftyp
const ftypeBoxStart = signatureLength + 4;
const ftypBoxLength = buffer.readUInt32BE(signatureLength);
const ftypBox = buffer.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength);
return ftypBox.toString("hex", 0, 4) === BoxTypes.ftyp;
},
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)
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:
const MAGIC = 4
offset = offset + 4 + MAGIC + calculateRREQLength(buffer.slice(offset + 4))
return parseIHDR(buffer.slice(offset + 8, offset + 24))
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))
return parseIHDR(buffer.slice(offset + 8, offset + 24));
default:
throw new TypeError('Unsupported header found: ' + buffer.toString('ascii', offset, offset + 4))
throw new TypeError("Unsupported header found: " + buffer.toString("ascii", offset, offset + 4));
}
}
}
};
function readUInt (buffer, bits, offset, isBigEndian) {
offset = offset || 0
const endian = isBigEndian ? 'BE' : 'LE'
const methodName = 'readUInt' + bits + endian
return buffer[methodName].call(buffer, offset)
function readUInt(buffer, bits, offset, isBigEndian) {
offset = offset || 0;
const endian = isBigEndian ? "BE" : "LE";
const methodName = "readUInt" + bits + endian;
return buffer[methodName].call(buffer, offset);
}
const EXIF_MARKER = '45786966'
const APP1_DATA_SIZE_BYTES = 2
const EXIF_HEADER_BYTES = 6
const TIFF_BYTE_ALIGN_BYTES = 2
const BIG_ENDIAN_BYTE_ALIGN = '4d4d'
const LITTLE_ENDIAN_BYTE_ALIGN = '4949'
const IDF_ENTRY_BYTES = 12
const NUM_DIRECTORY_ENTRIES_BYTES = 2
function isEXIF (buffer) {
return buffer.toString('hex', 2, 6) === EXIF_MARKER
const EXIF_MARKER = "45786966";
const APP1_DATA_SIZE_BYTES = 2;
const EXIF_HEADER_BYTES = 6;
const TIFF_BYTE_ALIGN_BYTES = 2;
const BIG_ENDIAN_BYTE_ALIGN = "4d4d";
const LITTLE_ENDIAN_BYTE_ALIGN = "4949";
const IDF_ENTRY_BYTES = 12;
const NUM_DIRECTORY_ENTRIES_BYTES = 2;
function isEXIF(buffer) {
return buffer.toString("hex", 2, 6) === EXIF_MARKER;
}
function extractSize (buffer, index) {
function extractSize(buffer, index) {
return {
height: buffer.readUInt16BE(index),
width: buffer.readUInt16BE(index + 2)
}
};
}
function extractOrientation (exifBlock, isBigEndian) {
const idfOffset = 8
const offset = EXIF_HEADER_BYTES + idfOffset
const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian)
function extractOrientation(exifBlock, isBigEndian) {
const idfOffset = 8;
const offset = EXIF_HEADER_BYTES + idfOffset;
const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian);
for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) {
const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES
const end = start + IDF_ENTRY_BYTES
const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES;
const end = start + IDF_ENTRY_BYTES;
if (start > exifBlock.length) {
return
return;
}
const block = exifBlock.slice(start, end)
const tagNumber = readUInt(block, 16, 0, isBigEndian)
const block = exifBlock.slice(start, end);
const tagNumber = readUInt(block, 16, 0, isBigEndian);
if (tagNumber === 274) {
const dataFormat = readUInt(block, 16, 2, isBigEndian)
const dataFormat = readUInt(block, 16, 2, isBigEndian);
if (dataFormat !== 3) {
return
return;
}
const numberOfComponents = readUInt(block, 32, 4, isBigEndian)
const numberOfComponents = readUInt(block, 32, 4, isBigEndian);
if (numberOfComponents !== 1) {
return
return;
}
return readUInt(block, 16, 8, isBigEndian)
return readUInt(block, 16, 8, isBigEndian);
}
}
}
function validateExifBlock (buffer, index) {
const exifBlock = buffer.slice(APP1_DATA_SIZE_BYTES, index)
const byteAlign = exifBlock.toString('hex', EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES)
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN
const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN
function validateExifBlock(buffer, index) {
const exifBlock = buffer.slice(APP1_DATA_SIZE_BYTES, index);
const byteAlign = exifBlock.toString("hex", EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES);
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN;
if (isBigEndian || isLittleEndian) {
return extractOrientation(exifBlock, isBigEndian)
return extractOrientation(exifBlock, isBigEndian);
}
}
function validateBuffer (buffer, index) {
function validateBuffer(buffer, index) {
if (index > buffer.length) {
throw new TypeError('Corrupt JPG, exceeded buffer limits')
throw new TypeError("Corrupt JPG, exceeded buffer limits");
}
if (buffer[index] !== 255) {
throw new TypeError('Invalid JPG, marker table corrupted')
throw new TypeError("Invalid JPG, marker table corrupted");
}
}
const JPG = {
validate (buffer) {
const SOIMarker = buffer.toString('hex', 0, 2)
return SOIMarker === 'ffd8'
validate(buffer) {
const SOIMarker = buffer.toString("hex", 0, 2);
return SOIMarker === "ffd8";
},
calculate (buffer) {
buffer = buffer.slice(4)
let orientation
let next
calculate(buffer) {
buffer = buffer.slice(4);
let orientation;
let next;
while (buffer.length) {
const i = buffer.readUInt16BE(0)
const i = buffer.readUInt16BE(0);
if (isEXIF(buffer)) {
orientation = validateExifBlock(buffer, i)
orientation = validateExifBlock(buffer, i);
}
validateBuffer(buffer, i)
next = buffer[i + 1]
validateBuffer(buffer, i);
next = buffer[i + 1];
if (next === 192 || next === 193 || next === 194) {
const size = extractSize(buffer, i + 5)
const size = extractSize(buffer, i + 5);
if (!orientation) {
return size
return size;
}

@@ -333,46 +333,46 @@ return {

width: size.width
}
};
}
buffer = buffer.slice(i + 2)
buffer = buffer.slice(i + 2);
}
throw new TypeError('Invalid JPG, no size found')
throw new TypeError("Invalid JPG, no size found");
}
}
};
const SIGNATURE = 'KTX 11'
const SIGNATURE = "KTX 11";
const KTX = {
validate (buffer) {
return SIGNATURE === buffer.toString('ascii', 1, 7)
validate(buffer) {
return SIGNATURE === buffer.toString("ascii", 1, 7);
},
calculate (buffer) {
calculate(buffer) {
return {
height: buffer.readUInt32LE(40),
width: buffer.readUInt32LE(36)
}
};
}
}
};
const pngSignature = 'PNG\r\n\n'
const pngImageHeaderChunkName = 'IHDR'
const pngFriedChunkName = 'CgBI'
const pngSignature = "PNG\r\n\n";
const pngImageHeaderChunkName = "IHDR";
const pngFriedChunkName = "CgBI";
const PNG = {
validate (buffer) {
if (pngSignature === buffer.toString('ascii', 1, 8)) {
let chunkName = buffer.toString('ascii', 12, 16)
validate(buffer) {
if (pngSignature === buffer.toString("ascii", 1, 8)) {
let chunkName = buffer.toString("ascii", 12, 16);
if (chunkName === pngFriedChunkName) {
chunkName = buffer.toString('ascii', 28, 32)
chunkName = buffer.toString("ascii", 28, 32);
}
if (chunkName !== pngImageHeaderChunkName) {
throw new TypeError('Invalid PNG')
throw new TypeError("Invalid PNG");
}
return true
return true;
}
return false
return false;
},
calculate (buffer) {
if (buffer.toString('ascii', 12, 16) === pngFriedChunkName) {
calculate(buffer) {
if (buffer.toString("ascii", 12, 16) === pngFriedChunkName) {
return {
height: buffer.readUInt32BE(36),
width: buffer.readUInt32BE(32)
}
};
}

@@ -382,27 +382,27 @@ return {

width: buffer.readUInt32BE(16)
}
};
}
}
};
const PNMTypes = {
P1: 'pbm/ascii',
P2: 'pgm/ascii',
P3: 'ppm/ascii',
P4: 'pbm',
P5: 'pgm',
P6: 'ppm',
P7: 'pam',
PF: 'pfm'
}
const Signatures = Object.keys(PNMTypes)
P1: "pbm/ascii",
P2: "pgm/ascii",
P3: "ppm/ascii",
P4: "pbm",
P5: "pgm",
P6: "ppm",
P7: "pam",
PF: "pfm"
};
const Signatures = Object.keys(PNMTypes);
const handlers = {
default: (lines) => {
let dimensions = []
let dimensions = [];
while (lines.length > 0) {
const line = lines.shift()
if (line[0] === '#') {
continue
const line = lines.shift();
if (line[0] === "#") {
continue;
}
dimensions = line.split(' ')
break
dimensions = line.split(" ");
break;
}

@@ -413,20 +413,20 @@ if (dimensions.length === 2) {

width: parseInt(dimensions[0], 10)
}
};
} else {
throw new TypeError('Invalid PNM')
throw new TypeError("Invalid PNM");
}
},
pam: (lines) => {
const size = {}
const size = {};
while (lines.length > 0) {
const line = lines.shift()
const line = lines.shift();
if (line.length > 16 || line.charCodeAt(0) > 128) {
continue
continue;
}
const [key, value] = line.split(' ')
const [key, value] = line.split(" ");
if (key && value) {
size[key.toLowerCase()] = parseInt(value, 10)
size[key.toLowerCase()] = parseInt(value, 10);
}
if (size.height && size.width) {
break
break;
}

@@ -438,35 +438,35 @@ }

width: size.width
}
};
} else {
throw new TypeError('Invalid PAM')
throw new TypeError("Invalid PAM");
}
}
}
};
const PNM = {
validate (buffer) {
const signature = buffer.toString('ascii', 0, 2)
return Signatures.includes(signature)
validate(buffer) {
const signature = buffer.toString("ascii", 0, 2);
return Signatures.includes(signature);
},
calculate (buffer) {
const signature = buffer.toString('ascii', 0, 2)
const type = PNMTypes[signature]
const lines = buffer.toString('ascii', 3).split(/[\r\n]+/)
const handler = handlers[type] || handlers.default
return handler(lines)
calculate(buffer) {
const signature = buffer.toString("ascii", 0, 2);
const type = PNMTypes[signature];
const lines = buffer.toString("ascii", 3).split(/[\r\n]+/);
const handler = handlers[type] || handlers.default;
return handler(lines);
}
}
};
const PSD = {
validate (buffer) {
return buffer.toString('ascii', 0, 4) === '8BPS'
validate(buffer) {
return buffer.toString("ascii", 0, 4) === "8BPS";
},
calculate (buffer) {
calculate(buffer) {
return {
height: buffer.readUInt32BE(14),
width: buffer.readUInt32BE(18)
}
};
}
}
};
const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/
const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/;
const extractorRegExps = {

@@ -477,4 +477,4 @@ height: /\sheight=(['"])([^%]+?)\1/,

width: /\swidth=(['"])([^%]+?)\1/
}
const INCH_CM = 2.54
};
const INCH_CM = 2.54;
const units = {

@@ -488,21 +488,21 @@ cm: 96 / INCH_CM,

pt: 96 / 72
}
function parseLength (len) {
const m = /([0-9.]+)([a-z]*)/.exec(len)
};
function parseLength(len) {
const m = /([0-9.]+)([a-z]*)/.exec(len);
if (!m) {
return void 0
return void 0;
}
return Math.round(parseFloat(m[1]) * (units[m[2]] || 1))
return Math.round(parseFloat(m[1]) * (units[m[2]] || 1));
}
function parseViewbox (viewbox) {
const bounds = viewbox.split(' ')
function parseViewbox(viewbox) {
const bounds = viewbox.split(" ");
return {
height: parseLength(bounds[3]),
width: parseLength(bounds[2])
}
};
}
function parseAttributes (root) {
const width = root.match(extractorRegExps.width)
const height = root.match(extractorRegExps.height)
const viewbox = root.match(extractorRegExps.viewbox)
function parseAttributes(root) {
const width = root.match(extractorRegExps.width);
const height = root.match(extractorRegExps.height);
const viewbox = root.match(extractorRegExps.viewbox);
return {

@@ -512,12 +512,12 @@ height: height && parseLength(height[2]),

width: width && parseLength(width[2])
}
};
}
function calculateByDimensions (attrs) {
function calculateByDimensions(attrs) {
return {
height: attrs.height,
width: attrs.width
}
};
}
function calculateByViewbox (attrs, viewbox) {
const ratio = viewbox.width / viewbox.height
function calculateByViewbox(attrs, viewbox) {
const ratio = viewbox.width / viewbox.height;
if (attrs.width) {

@@ -527,3 +527,3 @@ return {

width: attrs.width
}
};
}

@@ -534,3 +534,3 @@ if (attrs.height) {

width: Math.floor(attrs.height * ratio)
}
};
}

@@ -540,72 +540,72 @@ return {

width: viewbox.width
}
};
}
const SVG = {
validate (buffer) {
const str = String(buffer)
return svgReg.test(str)
validate(buffer) {
const str = String(buffer);
return svgReg.test(str);
},
calculate (buffer) {
const root = buffer.toString('utf8').match(extractorRegExps.root)
calculate(buffer) {
const root = buffer.toString("utf8").match(extractorRegExps.root);
if (root) {
const attrs = parseAttributes(root[0])
const attrs = parseAttributes(root[0]);
if (attrs.width && attrs.height) {
return calculateByDimensions(attrs)
return calculateByDimensions(attrs);
}
if (attrs.viewbox) {
return calculateByViewbox(attrs, attrs.viewbox)
return calculateByViewbox(attrs, attrs.viewbox);
}
}
throw new TypeError('Invalid SVG')
throw new TypeError("Invalid SVG");
}
}
};
function calculateExtended (buffer) {
function calculateExtended(buffer) {
return {
height: 1 + buffer.readUIntLE(7, 3),
width: 1 + buffer.readUIntLE(4, 3)
}
};
}
function calculateLossless (buffer) {
function calculateLossless(buffer) {
return {
height: 1 + ((buffer[4] & 15) << 10 | buffer[3] << 2 | (buffer[2] & 192) >> 6),
width: 1 + ((buffer[2] & 63) << 8 | buffer[1])
}
};
}
function calculateLossy (buffer) {
function calculateLossy(buffer) {
return {
height: buffer.readInt16LE(8) & 16383,
width: buffer.readInt16LE(6) & 16383
}
};
}
const WEBP = {
validate (buffer) {
const riffHeader = buffer.toString('ascii', 0, 4) === 'RIFF'
const webpHeader = buffer.toString('ascii', 8, 12) === 'WEBP'
const vp8Header = buffer.toString('ascii', 12, 15) === 'VP8'
return riffHeader && webpHeader && vp8Header
validate(buffer) {
const riffHeader = buffer.toString("ascii", 0, 4) === "RIFF";
const webpHeader = buffer.toString("ascii", 8, 12) === "WEBP";
const vp8Header = buffer.toString("ascii", 12, 15) === "VP8";
return riffHeader && webpHeader && vp8Header;
},
calculate (buffer) {
const chunkHeader = buffer.toString('ascii', 12, 16)
buffer = buffer.slice(20, 30)
if (chunkHeader === 'VP8X') {
const extendedHeader = buffer[0]
const validStart = (extendedHeader & 192) === 0
const validEnd = (extendedHeader & 1) === 0
calculate(buffer) {
const chunkHeader = buffer.toString("ascii", 12, 16);
buffer = buffer.slice(20, 30);
if (chunkHeader === "VP8X") {
const extendedHeader = buffer[0];
const validStart = (extendedHeader & 192) === 0;
const validEnd = (extendedHeader & 1) === 0;
if (validStart && validEnd) {
return calculateExtended(buffer)
return calculateExtended(buffer);
} else {
throw new TypeError('Invalid WebP')
throw new TypeError("Invalid WebP");
}
}
if (chunkHeader === 'VP8 ' && buffer[0] !== 47) {
return calculateLossy(buffer)
if (chunkHeader === "VP8 " && buffer[0] !== 47) {
return calculateLossy(buffer);
}
const signature = buffer.toString('hex', 3, 6)
if (chunkHeader === 'VP8L' && signature !== '9d012a') {
return calculateLossless(buffer)
const signature = buffer.toString("hex", 3, 6);
if (chunkHeader === "VP8L" && signature !== "9d012a") {
return calculateLossless(buffer);
}
throw new TypeError('Invalid WebP')
throw new TypeError("Invalid WebP");
}
}
};

@@ -628,56 +628,56 @@ const typeHandlers = {

webp: WEBP
}
};
const getMimeType = (type) => {
if (type === 'svg') {
return 'image/svg+xml'
if (type === "svg") {
return "image/svg+xml";
}
return `image/${type}`
}
return `image/${type}`;
};
const keys = Object.keys(typeHandlers)
const keys = Object.keys(typeHandlers);
const firstBytes = {
56: 'psd',
66: 'bmp',
68: 'dds',
71: 'gif',
73: 'tiff',
77: 'tiff',
82: 'webp',
105: 'icns',
137: 'png',
255: 'jpg'
}
function detector (buffer) {
const byte = buffer[0]
56: "psd",
66: "bmp",
68: "dds",
71: "gif",
73: "tiff",
77: "tiff",
82: "webp",
105: "icns",
137: "png",
255: "jpg"
};
function detector(buffer) {
const byte = buffer[0];
if (byte in firstBytes) {
const type = firstBytes[byte]
const type = firstBytes[byte];
if (typeHandlers[type].validate(buffer)) {
return type
return type;
}
}
const finder = key => typeHandlers[key].validate(buffer)
return keys.find(finder)
const finder = (key) => typeHandlers[key].validate(buffer);
return keys.find(finder);
}
function lookup (buffer, filepath) {
const type = detector(buffer)
function lookup(buffer, filepath) {
const type = detector(buffer);
if (type && type in typeHandlers) {
const size = typeHandlers[type].calculate(buffer, filepath)
const size = typeHandlers[type].calculate(buffer, filepath);
if (size !== void 0) {
size.type = type
size.mimeType = getMimeType(type)
return size
size.type = type;
size.mimeType = getMimeType(type);
return size;
}
}
throw new TypeError('unsupported file type: ' + type + ' (file: ' + filepath + ')')
throw new TypeError("unsupported file type: " + type + " (file: " + filepath + ")");
}
function imageSize (input) {
function imageMeta(input) {
if (Buffer.isBuffer(input)) {
return lookup(input)
return lookup(input);
}
throw new Error('Input should be buffer!')
throw new Error("Input should be buffer!");
}
const types = Object.keys(typeHandlers)
const types = Object.keys(typeHandlers);
exports.imageSize = imageSize
exports.types = types
exports.default = imageMeta;
exports.types = types;
{
"name": "image-meta",
"version": "0.0.0",
"version": "0.0.1",
"description": "",

@@ -16,2 +16,3 @@ "repository": "nuxt-contrib/image-meta",

"lint": "eslint --ext .ts,.js .",
"release": "yarn test && yarn build && standard-version && git push --follow-tags && npm publish",
"test": "yarn lint"

@@ -23,2 +24,3 @@ },

"siroc": "^0.4.0",
"standard-version": "^9.0.0",
"typescript": "^4.0.5"

@@ -25,0 +27,0 @@ },

# image-meta
...
[![npm version][npm-v-src]][npm-v-href]
[![npm downloads][npm-d-src]][npm-d-href]
[![bundle phobia][bundlephobia-src]][bundlephobia-href]
Using yarn:
```
yarn add image-meta
```
Using npm:
```
npm install image-meta
```
Usage:
```ts
import imageMeta from 'image-meta'
import fetch from 'node-fetch'
const data = await fetch(url).then(res => res.buffer())
const { width, height, mimeType } = await imageMeta(data)
```
**Note:** This package only works with Node.js because of `Buffer` dependency!
## License
[MIT](./LICENSE) - Based on [image-size](https://github.com/image-size/image-size)
<!-- Refs -->
[npm-v-src]: https://img.shields.io/npm/v/image-meta?style=flat-square
[npm-v-href]: https://npmjs.com/package/image-meta
[npm-d-src]: https://img.shields.io/npm/dm/image-meta?style=flat-square
[npm-d-href]: https://npmjs.com/package/image-meta
[github-actions-src]: https://img.shields.io/github/workflow/status/nuxt-contrib/image-meta/ci/master?style=flat-square
[github-actions-href]: https://github.com/nuxt-contrib/image-meta/actions?query=workflow%3Aci
[bundlephobia-src]: https://img.shields.io/bundlephobia/min/image-meta?style=flat-square
[bundlephobia-href]: https://bundlephobia.com/result?p=image-meta
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