perf(read-image-resizer): decode only first 32KB of base64 for dimension parsing
Previously decoded entire image buffer to read headers. Now slices base64 to 32KB prefix before decoding — sufficient for PNG/GIF/WebP/JPEG headers. Dramatically reduces memory allocation for large images.
This commit is contained in:
@@ -28,6 +28,13 @@ function createGifDataUrl(width: number, height: number): string {
|
||||
return `data:image/gif;base64,${buf.toString("base64")}`
|
||||
}
|
||||
|
||||
function createLargePngDataUrl(width: number, height: number, extraBase64Chars: number): string {
|
||||
const baseDataUrl = createPngDataUrl(width, height)
|
||||
const base64Data = baseDataUrl.slice(baseDataUrl.indexOf(",") + 1)
|
||||
const paddedBase64 = `${base64Data}${"A".repeat(extraBase64Chars)}`
|
||||
return `data:image/png;base64,${paddedBase64}`
|
||||
}
|
||||
|
||||
describe("parseImageDimensions", () => {
|
||||
it("parses PNG 1x1 dimensions", () => {
|
||||
//#given
|
||||
@@ -51,6 +58,17 @@ describe("parseImageDimensions", () => {
|
||||
expect(result).toEqual({ width: 3000, height: 2000 })
|
||||
})
|
||||
|
||||
it("parses PNG dimensions from a very large base64 payload", () => {
|
||||
//#given
|
||||
const dataUrl = createLargePngDataUrl(4096, 2160, 10 * 1024 * 1024)
|
||||
|
||||
//#when
|
||||
const result = parseImageDimensions(dataUrl, "image/png")
|
||||
|
||||
//#then
|
||||
expect(result).toEqual({ width: 4096, height: 2160 })
|
||||
})
|
||||
|
||||
it("parses GIF 1x1 dimensions", () => {
|
||||
//#given
|
||||
const dataUrl = GIF_1X1_DATA_URL
|
||||
|
||||
@@ -2,6 +2,9 @@ import type { ImageDimensions } from "./types"
|
||||
|
||||
import { extractBase64Data } from "../../tools/look-at/mime-type-inference"
|
||||
|
||||
const HEADER_BYTES = 32_768
|
||||
const HEADER_BASE64_CHARS = Math.ceil(HEADER_BYTES / 3) * 4
|
||||
|
||||
function toImageDimensions(width: number, height: number): ImageDimensions | null {
|
||||
if (!Number.isFinite(width) || !Number.isFinite(height)) {
|
||||
return null
|
||||
@@ -157,7 +160,8 @@ export function parseImageDimensions(base64DataUrl: string, mimeType: string): I
|
||||
return null
|
||||
}
|
||||
|
||||
const buffer = Buffer.from(rawBase64, "base64")
|
||||
const headerBase64 = rawBase64.length > HEADER_BASE64_CHARS ? rawBase64.slice(0, HEADER_BASE64_CHARS) : rawBase64
|
||||
const buffer = Buffer.from(headerBase64, "base64")
|
||||
if (buffer.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user