import { readUInt, toHexString, toUTF8String } from "./utils.js"; function readIFD(input, isBigEndian) { const ifdOffset = readUInt(input, 32, 4, isBigEndian); return input.slice(ifdOffset + 2); } function readValue(input, isBigEndian) { const low = readUInt(input, 16, 8, isBigEndian); const high = readUInt(input, 16, 10, isBigEndian); return (high << 16) + low; } function nextTag(input) { if (input.length > 24) { return input.slice(12); } } function extractTags(input, isBigEndian) { const tags = {}; let temp = input; while (temp && temp.length) { const code = readUInt(temp, 16, 0, isBigEndian); const type = readUInt(temp, 16, 2, isBigEndian); const length = readUInt(temp, 32, 4, isBigEndian); if (code === 0) { break; } else { if (length === 1 && (type === 3 || type === 4)) { tags[code] = readValue(temp, isBigEndian); } temp = nextTag(temp); } } return tags; } function determineEndianness(input) { const signature = toUTF8String(input, 0, 2); if ("II" === signature) { return "LE"; } else if ("MM" === signature) { return "BE"; } } const signatures = [ // '492049', // currently not supported "49492a00", // Little endian "4d4d002a" // Big Endian // '4d4d002a', // BigTIFF > 4GB. currently not supported ]; const TIFF = { validate: (input) => signatures.includes(toHexString(input, 0, 4)), calculate(input) { const isBigEndian = determineEndianness(input) === "BE"; const ifdBuffer = readIFD(input, isBigEndian); const tags = extractTags(ifdBuffer, isBigEndian); const width = tags[256]; const height = tags[257]; if (!width || !height) { throw new TypeError("Invalid Tiff. Missing tags"); } return { height, width }; } }; export { TIFF };