Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889import { beforeAll, describe, expect, it } from "vitest"import { createRequire } from "node:module"import { readFile } from "node:fs/promises"import * as Webp from "@jsquash/webp/encode.js"import * as Avif from "@jsquash/avif/encode.js"import { encodeImage } from "./jsquash"import type { ExportSettings } from "./settings"
const require = createRequire(import.meta.url)
const compileWasm = async (pkg: string, rel: string): Promise<WebAssembly.Module> => WebAssembly.compile(await readFile(require.resolve(`${pkg}/${rel}`)))
/** * Pre-init the emscripten codecs (webp/avif): their node branch cannot * fetch wasm (no readBinary), so compile the codec binary and hand the * module to `init`. The webp glue picks its simd build via * wasm-feature-detect, so compile the simd binary first and fall back to * the scalar one — compile fails on runtimes without simd, which is the * same check the glue makes. */const initEmscriptenCodecs = async (): Promise<void> => { let webpModule: WebAssembly.Module try { webpModule = await compileWasm("@jsquash/webp", "codec/enc/webp_enc_simd.wasm") } catch { webpModule = await compileWasm("@jsquash/webp", "codec/enc/webp_enc.wasm") } await Webp.init(webpModule) await Avif.init(await compileWasm("@jsquash/avif", "codec/enc/avif_enc.wasm"))}
/** A 64×48 gradient image exercising all channels. */const makeImage = (width = 64, height = 48): ImageData => { const data = new Uint8ClampedArray(width * height * 4) for (let i = 0; i < width * height; i++) { data[i * 4] = (i * 3) % 256 data[i * 4 + 1] = (i * 7) % 256 data[i * 4 + 2] = (i * 11) % 256 data[i * 4 + 3] = 255 } return new ImageData(data, width, height)}
const settings = ( format: ExportSettings["format"], overrides: Partial<ExportSettings> = {},): ExportSettings => // The spread of Partial overrides widens the literal; the cast is the // deliberate escape hatch for the test's convenience. // oxlint-disable-next-line consistent-type-assertions ({ format, quality: 75, scale: 1, ...overrides }) as ExportSettings
const PNG_MAGIC = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]
describe("encodeImage", () => { beforeAll(initEmscriptenCodecs) it("encodes PNG (lossless, no quality knob)", async () => { const bytes = await encodeImage(makeImage(), settings("png", { quality: null })) expect([...bytes.subarray(0, 8)]).toEqual(PNG_MAGIC) })
it("encodes JPEG", async () => { const bytes = await encodeImage(makeImage(), settings("jpeg")) expect(bytes[0]).toBe(0xff) expect(bytes[1]).toBe(0xd8) })
it("encodes WebP", async () => { const bytes = await encodeImage(makeImage(), settings("webp")) expect([...bytes.subarray(0, 4)]).toEqual([0x52, 0x49, 0x46, 0x46]) // RIFF expect([...bytes.subarray(8, 12)]).toEqual([0x57, 0x45, 0x42, 0x50]) // WEBP })
it("encodes AVIF", async () => { const bytes = await encodeImage(makeImage(), settings("avif")) // ISO-BMFF: size + 'ftyp' box. expect([...bytes.subarray(4, 8)]).toEqual([0x66, 0x74, 0x79, 0x70]) })
it("downscales before encoding at 50%", async () => { const bytes = await encodeImage(makeImage(64, 48), settings("png", { quality: null, scale: 0.5 })) // PNG IHDR: width at offset 16, height at offset 20 (big-endian). const width = (bytes[16]! << 24) | (bytes[17]! << 16) | (bytes[18]! << 8) | bytes[19]! const height = (bytes[20]! << 24) | (bytes[21]! << 16) | (bytes[22]! << 8) | bytes[23]! expect([width, height]).toEqual([32, 24]) })})