返回 DeepSeek-Reasonix
png.ts
根目录 / desktop / electron / src / main / browser / png.ts
1 import { crc32, inflateSync } from "node:zlib";
2 import { browserFailure } from "./errors.js";
3
4 export const MAX_CAPTURE_PIXELS = 16_777_216;
5 const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
6
7 export function pngSize(data: Buffer): { width: number; height: number } {
8 if (data.length < 33 || !data.subarray(0, 8).equals(signature) || data.toString("ascii", 12, 16) !== "IHDR") {
9 throw browserFailure("invalid_image", "capture did not return a PNG image");
10 }
11 const width = data.readUInt32BE(16), height = data.readUInt32BE(20);
12 if (width === 0 || height === 0 || width * height > MAX_CAPTURE_PIXELS) {
13 throw browserFailure("invalid_image", "capture has empty or excessive pixel dimensions; capture a smaller region");
14 }
15 return { width, height };
16 }
17
18 export function validatePNG(data: Buffer): { width: number; height: number } {
19 const size = pngSize(data);
20 const compressed: Buffer[] = [];
21 let ended = false;
22 for (let offset = 8; offset + 12 <= data.length;) {
23 const length = data.readUInt32BE(offset);
24 const end = offset + 8 + length;
25 if (end + 4 > data.length || crc32(data.subarray(offset + 4, end)) !== data.readUInt32BE(end)) {
26 throw browserFailure("invalid_image", "capture returned a truncated or corrupt PNG");
27 }
28 const kind = data.toString("ascii", offset + 4, offset + 8);
29 if (kind === "IDAT") compressed.push(data.subarray(offset + 8, end));
30 if (kind === "IEND") { ended = length === 0 && end + 4 === data.length; break; }
31 offset = end + 4;
32 }
33 if (!ended || compressed.length === 0) throw browserFailure("invalid_image", "capture returned an incomplete PNG");
34 try {
35 if (inflateSync(Buffer.concat(compressed), { maxOutputLength: MAX_CAPTURE_PIXELS * 8 + 65536 }).length === 0) throw new Error("empty raster");
36 } catch {
37 throw browserFailure("invalid_image", "capture returned an undecodable PNG raster");
38 }
39 return size;
40 }
41
41 lines TYPESCRIPT