Openstatus www.openstatus.dev
at main 75 lines 1.9 kB view raw
1import { readFileSync } from "node:fs"; 2import { join } from "node:path"; 3 4interface ImageDimensions { 5 width: number; 6 height: number; 7} 8 9/** 10 * Get image dimensions from PNG file 11 * PNG spec: width and height are stored at bytes 16-23 as 4-byte integers 12 */ 13function getPngDimensions(buffer: Buffer): ImageDimensions { 14 const width = buffer.readUInt32BE(16); 15 const height = buffer.readUInt32BE(20); 16 return { width, height }; 17} 18 19/** 20 * Get image dimensions from JPEG file 21 */ 22function getJpegDimensions(buffer: Buffer): ImageDimensions { 23 let offset = 2; // Skip SOI marker 24 25 while (offset < buffer.length) { 26 // Check for marker 27 if (buffer[offset] !== 0xff) break; 28 29 const marker = buffer[offset + 1]; 30 offset += 2; 31 32 // SOF markers (Start of Frame) 33 if ( 34 marker >= 0xc0 && 35 marker <= 0xcf && 36 marker !== 0xc4 && 37 marker !== 0xc8 && 38 marker !== 0xcc 39 ) { 40 const height = buffer.readUInt16BE(offset + 3); 41 const width = buffer.readUInt16BE(offset + 5); 42 return { width, height }; 43 } 44 45 // Skip to next marker 46 const segmentLength = buffer.readUInt16BE(offset); 47 offset += segmentLength; 48 } 49 50 throw new Error("Could not find JPEG dimensions"); 51} 52 53/** 54 * Get dimensions for an image in the public directory 55 */ 56export function getImageDimensions(publicPath: string): ImageDimensions | null { 57 try { 58 const fullPath = join(process.cwd(), "public", publicPath); 59 const buffer = readFileSync(fullPath); 60 61 // Check file signature 62 if (buffer[0] === 0x89 && buffer.toString("ascii", 1, 4) === "PNG") { 63 return getPngDimensions(buffer); 64 } 65 66 if (buffer[0] === 0xff && buffer[1] === 0xd8) { 67 return getJpegDimensions(buffer); 68 } 69 70 return null; 71 } catch (error) { 72 console.warn(`Failed to get dimensions for ${publicPath}:`, error); 73 return null; 74 } 75}