| 1 | // Minimal PNG dimension reader: parses the IHDR chunk only. Lives in src/ |
| 2 | // (not scripts/lib) because src/ ships standalone to remote agents. |
| 3 | import fs from "node:fs"; |
| 4 | |
| 5 | const SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]); |
| 6 | |
| 7 | /** @returns {{w:number, h:number} | null} pixel dimensions, or null when the file is not a PNG. */ |
| 8 | export function pngSize(file) { |
| 9 | let fd; |
| 10 | try { |
| 11 | fd = fs.openSync(file, "r"); |
| 12 | const head = Buffer.alloc(24); |
| 13 | if (fs.readSync(fd, head, 0, 24, 0) < 24) return null; |
| 14 | if (!head.subarray(0, 8).equals(SIGNATURE)) return null; |
| 15 | if (head.toString("latin1", 12, 16) !== "IHDR") return null; |
| 16 | return { w: head.readUInt32BE(16), h: head.readUInt32BE(20) }; |
| 17 | } catch { |
| 18 | return null; |
| 19 | } finally { |
| 20 | try { if (fd != null) fs.closeSync(fd); } catch {} |
| 21 | } |
| 22 | } |
| 23 |