1import { readImageDimensions } from "@t3tools/shared/imageDimensions";
2
3const ICNS_HEADER_BYTES = 8;
4const ICNS_MAGIC = 0x69636e73; // "icns"
5const PNG_MAGIC = 0x89504e47; // "\x89PNG"
6
7/**
8 * Picks the smallest PNG at least `minSize` wide, else the largest; null when there is none.
9 * Returns a copy so the response does not pin the whole `.icns` buffer.
10 */
11export function extractIcnsPng(bytes: Uint8Array, minSize: number): Uint8Array | null {
12 const data = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
13 if (bytes.length < ICNS_HEADER_BYTES || data.getUint32(0) !== ICNS_MAGIC) return null;
14 const end = Math.min(data.getUint32(4), bytes.length);
15 let best: { readonly png: Uint8Array; readonly width: number } | null = null;
16 for (let offset = ICNS_HEADER_BYTES; offset + ICNS_HEADER_BYTES <= end;) {
17 const length = data.getUint32(offset + 4);
18 if (length < ICNS_HEADER_BYTES || offset + length > end) break;
19 const entry = bytes.subarray(offset + ICNS_HEADER_BYTES, offset + length);
20 const isPng = entry.length >= 4 && data.getUint32(offset + ICNS_HEADER_BYTES) === PNG_MAGIC;
21 offset += length;
22 const width = isPng ? readImageDimensions(entry)?.width : undefined;
23 if (width === undefined) continue;
24 const isBetter =
25 best === null ||
26 (best.width < minSize ? width > best.width : width >= minSize && width < best.width);
27 if (isBetter) best = { png: entry, width };
28 }
29 return best?.png.slice() ?? null;
30}