//#region src/image-dimensions.ts
function readUint32BE(bytes, offset) {
	return ((bytes[offset] ?? 0) << 24 | (bytes[offset + 1] ?? 0) << 16 | (bytes[offset + 2] ?? 0) << 8 | (bytes[offset + 3] ?? 0)) >>> 0;
}
function readUint16BE(bytes, offset) {
	return ((bytes[offset] ?? 0) << 8 | (bytes[offset + 1] ?? 0)) >>> 0;
}
function readUint24LE(bytes, offset) {
	return ((bytes[offset] ?? 0) | (bytes[offset + 1] ?? 0) << 8 | (bytes[offset + 2] ?? 0) << 16) >>> 0;
}
function parsePngDimensions(header) {
	if (header.length < 24) return null;
	const pngSig = [
		137,
		80,
		78,
		71,
		13,
		10,
		26,
		10
	];
	for (let i = 0; i < pngSig.length; i++) if (header[i] !== pngSig[i]) return null;
	if (String.fromCharCode(header[12] ?? 0, header[13] ?? 0, header[14] ?? 0, header[15] ?? 0) !== "IHDR") return null;
	return {
		width: readUint32BE(header, 16),
		height: readUint32BE(header, 20)
	};
}
function parseJpegDimensions(header) {
	let offset = 2;
	while (offset + 9 < header.length) {
		if (header[offset] !== 255) {
			offset++;
			continue;
		}
		const marker = header[offset + 1] ?? 0;
		if (marker === 216 || marker === 217) {
			offset += 2;
			continue;
		}
		if (marker >= 192 && marker <= 195 || marker >= 197 && marker <= 199 || marker >= 201 && marker <= 203 || marker >= 205 && marker <= 207) return {
			height: readUint16BE(header, offset + 5),
			width: readUint16BE(header, offset + 7)
		};
		const segmentLength = readUint16BE(header, offset + 2);
		if (segmentLength < 2) return null;
		offset += 2 + segmentLength;
	}
	return null;
}
function parseWebpDimensions(header) {
	if (header.length < 30) return null;
	const riff = String.fromCharCode(header[0] ?? 0, header[1] ?? 0, header[2] ?? 0, header[3] ?? 0);
	const webp = String.fromCharCode(header[8] ?? 0, header[9] ?? 0, header[10] ?? 0, header[11] ?? 0);
	if (riff !== "RIFF" || webp !== "WEBP") return null;
	const chunk = String.fromCharCode(header[12] ?? 0, header[13] ?? 0, header[14] ?? 0, header[15] ?? 0);
	if (chunk === "VP8X" && header.length >= 30) return {
		width: readUint24LE(header, 24) + 1,
		height: readUint24LE(header, 27) + 1
	};
	if (chunk === "VP8 " && header.length >= 30) return {
		width: readUint16BE(header, 26) & 16383,
		height: readUint16BE(header, 28) & 16383
	};
	if (chunk === "VP8L" && header.length >= 25) {
		const bits = readUint32BE(header, 21);
		return {
			width: (bits & 16383) + 1,
			height: (bits >> 14 & 16383) + 1
		};
	}
	return null;
}
/** Parse PNG/WebP/JPEG dimensions from header bytes only. */
function parseImageDimensions(header) {
	const png = parsePngDimensions(header);
	if (png) return png;
	const webp = parseWebpDimensions(header);
	if (webp) return webp;
	return parseJpegDimensions(header);
}
//#endregion
export { parseImageDimensions };
