Download packages/coding-agent/src/utils/mime.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 3.8 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/utils/mime.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/src/utils/mime.ts
-
curl -L -o mime.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/utils/mime.ts
3.8 kB
| import { open } from "node:fs/promises"; | |
| const IMAGE_TYPE_SNIFF_BYTES = 4100; | |
| const PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; | |
| export function detectSupportedImageMimeType(buffer: Uint8Array): string | null { | |
| if (startsWith(buffer, [0xff, 0xd8, 0xff])) { | |
| return buffer[3] === 0xf7 ? null : "image/jpeg"; | |
| } | |
| if (startsWith(buffer, PNG_SIGNATURE)) { | |
| return isPng(buffer) && !isAnimatedPng(buffer) ? "image/png" : null; | |
| } | |
| if (startsWithAscii(buffer, 0, "GIF")) { | |
| return "image/gif"; | |
| } | |
| if (startsWithAscii(buffer, 0, "RIFF") && startsWithAscii(buffer, 8, "WEBP")) { | |
| return "image/webp"; | |
| } | |
| if (startsWithAscii(buffer, 0, "BM") && isBmp(buffer)) { | |
| return "image/bmp"; | |
| } | |
| return null; | |
| } | |
| export async function detectSupportedImageMimeTypeFromFile(filePath: string): Promise<string | null> { | |
| const fileHandle = await open(filePath, "r"); | |
| try { | |
| const buffer = Buffer.alloc(IMAGE_TYPE_SNIFF_BYTES); | |
| const { bytesRead } = await fileHandle.read(buffer, 0, IMAGE_TYPE_SNIFF_BYTES, 0); | |
| return detectSupportedImageMimeType(buffer.subarray(0, bytesRead)); | |
| } finally { | |
| await fileHandle.close(); | |
| } | |
| } | |
| function isPng(buffer: Uint8Array): boolean { | |
| return ( | |
| buffer.length >= 16 && readUint32BE(buffer, PNG_SIGNATURE.length) === 13 && startsWithAscii(buffer, 12, "IHDR") | |
| ); | |
| } | |
| function isAnimatedPng(buffer: Uint8Array): boolean { | |
| let offset = PNG_SIGNATURE.length; | |
| while (offset + 8 <= buffer.length) { | |
| const chunkLength = readUint32BE(buffer, offset); | |
| const chunkTypeOffset = offset + 4; | |
| if (startsWithAscii(buffer, chunkTypeOffset, "acTL")) return true; | |
| if (startsWithAscii(buffer, chunkTypeOffset, "IDAT")) return false; | |
| const nextOffset = offset + 8 + chunkLength + 4; | |
| if (nextOffset <= offset || nextOffset > buffer.length) return false; | |
| offset = nextOffset; | |
| } | |
| return false; | |
| } | |
| function isBmp(buffer: Uint8Array): boolean { | |
| if (buffer.length < 26) return false; | |
| const declaredFileSize = readUint32LE(buffer, 2); | |
| const pixelDataOffset = readUint32LE(buffer, 10); | |
| const dibHeaderSize = readUint32LE(buffer, 14); | |
| if (declaredFileSize !== 0 && declaredFileSize < 26) return false; | |
| if (pixelDataOffset < 14 + dibHeaderSize) return false; | |
| if (declaredFileSize !== 0 && pixelDataOffset >= declaredFileSize) return false; | |
| let colorPlanes: number; | |
| let bitsPerPixel: number; | |
| if (dibHeaderSize === 12) { | |
| colorPlanes = readUint16LE(buffer, 22); | |
| bitsPerPixel = readUint16LE(buffer, 24); | |
| } else if (dibHeaderSize >= 40 && dibHeaderSize <= 124) { | |
| if (buffer.length < 30) return false; | |
| colorPlanes = readUint16LE(buffer, 26); | |
| bitsPerPixel = readUint16LE(buffer, 28); | |
| } else { | |
| return false; | |
| } | |
| return colorPlanes === 1 && [1, 4, 8, 16, 24, 32].includes(bitsPerPixel); | |
| } | |
| function readUint16LE(buffer: Uint8Array, offset: number): number { | |
| return (buffer[offset] ?? 0) + ((buffer[offset + 1] ?? 0) << 8); | |
| } | |
| function readUint32BE(buffer: Uint8Array, offset: number): number { | |
| return ( | |
| (buffer[offset] ?? 0) * 0x1000000 + | |
| ((buffer[offset + 1] ?? 0) << 16) + | |
| ((buffer[offset + 2] ?? 0) << 8) + | |
| (buffer[offset + 3] ?? 0) | |
| ); | |
| } | |
| function readUint32LE(buffer: Uint8Array, offset: number): number { | |
| return ( | |
| (buffer[offset] ?? 0) + | |
| ((buffer[offset + 1] ?? 0) << 8) + | |
| ((buffer[offset + 2] ?? 0) << 16) + | |
| (buffer[offset + 3] ?? 0) * 0x1000000 | |
| ); | |
| } | |
| function startsWith(buffer: Uint8Array, bytes: number[]): boolean { | |
| if (buffer.length < bytes.length) return false; | |
| return bytes.every((byte, index) => buffer[index] === byte); | |
| } | |
| function startsWithAscii(buffer: Uint8Array, offset: number, text: string): boolean { | |
| if (buffer.length < offset + text.length) return false; | |
| for (let index = 0; index < text.length; index++) { | |
| if (buffer[offset + index] !== text.charCodeAt(index)) return false; | |
| } | |
| return true; | |
| } | |