'use strict'; function readPngSize(buf) { const sig = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); if (buf.length < 24 || !buf.subarray(0, 8).equals(sig)) return null; if (buf.toString('ascii', 12, 16) !== 'IHDR') return null; return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) }; } function readJpegSize(buf) { if (buf.length < 4 || buf[0] !== 0xff || buf[1] !== 0xd8) return null; let offset = 2; const SOF_MARKERS = new Set([ 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, ]); while (offset + 1 < buf.length) { if (buf[offset] !== 0xff) { offset++; continue; } const marker = buf[offset + 1]; if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) { offset += 2; continue; } if (marker === 0xd9 || offset + 3 >= buf.length) break; const segmentLength = buf.readUInt16BE(offset + 2); if (SOF_MARKERS.has(marker)) { const height = buf.readUInt16BE(offset + 5); const width = buf.readUInt16BE(offset + 7); return { width, height }; } offset += 2 + segmentLength; } return null; } function getImageSize(buffer) { try { return readPngSize(buffer) || readJpegSize(buffer); } catch { return null; } } module.exports = { getImageSize };