/** * Intrinsic image dimensions from file headers. * * pi-tui already exports getImageDimensions(), but it is imported here through * a narrow wrapper so a missing/renamed export degrades to a sane default * instead of throwing at extension load. */ export interface Dimensions { widthPx: number; heightPx: number; } /** Used when a header cannot be parsed. 4:3 keeps the grid from going silly. */ export const DEFAULT_DIMENSIONS: Dimensions = { widthPx: 800, heightPx: 600 }; function png(buf: Buffer): Dimensions | null { if (buf.length < 24) return null; if (buf.readUInt32BE(0) !== 0x89504e47) return null; // IHDR is always the first chunk: width/height at fixed offsets. return { widthPx: buf.readUInt32BE(16), heightPx: buf.readUInt32BE(20) }; } function gif(buf: Buffer): Dimensions | null { if (buf.length < 10) return null; if (buf.toString("ascii", 0, 3) !== "GIF") return null; return { widthPx: buf.readUInt16LE(6), heightPx: buf.readUInt16LE(8) }; } function jpeg(buf: Buffer): Dimensions | null { if (buf.length < 4 || buf[0] !== 0xff || buf[1] !== 0xd8) return null; let offset = 2; while (offset + 9 < buf.length) { if (buf[offset] !== 0xff) { offset++; // Resync over padding bytes. continue; } const marker = buf[offset + 1]!; const length = buf.readUInt16BE(offset + 2); // SOF0-SOF15, excluding DHT(c4), JPG(c8) and DAC(cc) which are not frames. if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) { return { heightPx: buf.readUInt16BE(offset + 5), widthPx: buf.readUInt16BE(offset + 7) }; } if (length < 2) return null; // Malformed: would loop forever. offset += 2 + length; } return null; } function webp(buf: Buffer): Dimensions | null { if (buf.length < 30) return null; if (buf.toString("ascii", 0, 4) !== "RIFF" || buf.toString("ascii", 8, 12) !== "WEBP") return null; const format = buf.toString("ascii", 12, 16); if (format === "VP8 ") { return { widthPx: buf.readUInt16LE(26) & 0x3fff, heightPx: buf.readUInt16LE(28) & 0x3fff }; } if (format === "VP8L") { const bits = buf.readUInt32LE(21); return { widthPx: (bits & 0x3fff) + 1, heightPx: ((bits >> 14) & 0x3fff) + 1 }; } if (format === "VP8X") { const w = buf[24]! | (buf[25]! << 8) | (buf[26]! << 16); const h = buf[27]! | (buf[28]! << 8) | (buf[29]! << 16); return { widthPx: w + 1, heightPx: h + 1 }; } return null; } /** Best-effort intrinsic size. Never throws. */ export function imageDimensions(bytes: Buffer): Dimensions { const parsed = png(bytes) ?? gif(bytes) ?? jpeg(bytes) ?? webp(bytes); if (!parsed || parsed.widthPx <= 0 || parsed.heightPx <= 0) return DEFAULT_DIMENSIONS; return parsed; }