mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-30 02:22:11 +00:00
refactor(core): avoid encoding rejected image candidates (#46073)
This commit is contained in:
parent
6e954f75ee
commit
6cfffeb031
2 changed files with 47 additions and 3 deletions
|
|
@ -78,9 +78,15 @@ export const make = Effect.gen(function* () {
|
|||
...JPEG_QUALITIES.map((quality) => ["image/jpeg", () => resized.get_bytes_jpeg(quality)] as const),
|
||||
]
|
||||
for (const [mime, encode] of encoders) {
|
||||
const candidate = Buffer.from(encode()).toString("base64")
|
||||
if (Buffer.byteLength(candidate, "utf-8") <= limits.maxBase64Bytes)
|
||||
return { ...content, content: candidate, encoding: "base64" as const, mime }
|
||||
const candidate = encode()
|
||||
// Base64 uses four bytes per three input bytes, including padding.
|
||||
if (Math.ceil(candidate.length / 3) * 4 <= limits.maxBase64Bytes)
|
||||
return {
|
||||
...content,
|
||||
content: Buffer.from(candidate).toString("base64"),
|
||||
encoding: "base64" as const,
|
||||
mime,
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
resized.free()
|
||||
|
|
|
|||
|
|
@ -437,6 +437,44 @@ describe("ReadTool", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("accepts PNG candidates at the exact base64 limit and skips them one byte below", () =>
|
||||
Effect.gen(function* () {
|
||||
const photon = yield* Effect.promise(() => import("@silvia-odwyer/photon-node"))
|
||||
const source = new photon.PhotonImage(
|
||||
Uint8Array.from({ length: 16 * 4 }, () => 255),
|
||||
16,
|
||||
1,
|
||||
)
|
||||
const content = {
|
||||
uri: "file:///wide.png",
|
||||
content: Buffer.from(source.get_bytes()).toString("base64"),
|
||||
encoding: "base64" as const,
|
||||
mime: "image/png",
|
||||
}
|
||||
source.free()
|
||||
const image = yield* Image.Service
|
||||
|
||||
for (const [maxWidth, padding] of [
|
||||
[4, "=="],
|
||||
[5, "="],
|
||||
[6, ""],
|
||||
] as const) {
|
||||
yield* image.transform((draft) => draft.configure({ maxWidth, maxBase64Bytes: 1_024 }))
|
||||
const candidate = yield* image.normalize("wide.png", content)
|
||||
expect(candidate.mime).toBe("image/png")
|
||||
expect(candidate.content.match(/=*$/)?.[0]).toBe(padding)
|
||||
|
||||
yield* image.transform((draft) => draft.configure({ maxBase64Bytes: candidate.content.length }))
|
||||
expect(yield* image.normalize("wide.png", content)).toEqual(candidate)
|
||||
|
||||
yield* image.transform((draft) => draft.configure({ maxBase64Bytes: candidate.content.length - 1 }))
|
||||
const smaller = yield* image.normalize("wide.png", content)
|
||||
expect(smaller.mime).toBe("image/png")
|
||||
expect(smaller.content.length).toBeLessThan(candidate.content.length)
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("drops images that cannot fit max base64 bytes after resize attempts", () =>
|
||||
Effect.gen(function* () {
|
||||
const png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue