The module's ABI version. Always equal to SUPPORTED_ABI for a loaded module.
Every feature this build contains.
The module's own linear memory.
Pages of linear memory the module currently holds.
The library version, as [major, minor, patch].
The library version as major.minor.patch.
The blobs compiled into the module.
A Latin face under sans, the four ICC profiles under srgb, display-p3,
adobe-rgb-1998 and rec2020, and two LBP cascades. Nothing has to be loaded for text,
profile conversion or face detection to work; loadBlob is for a wider glyph set, a
different face or another cascade.
Loading a blob of a kind hides the builtins of that kind from face detection, so one resident cascade runs alone. This listing reports what ships either way.
Optionalkind: BlobKind
Which kind to list, or omitted for all of them.
The id and byte length of each.
Decodes to raw pixels.
The escape hatch below the transformation surface, for a caller who wants the samples themselves: a histogram, a hand-written kernel, or a comparison against another decoder. Prefer transform or Image when the answer is another image, because those let the planner decide what to decode and this decodes all of it.
The encoded image.
The extent, the channel count and width * height * channels bytes, rows tightly
packed.
Decodes one rectangle of a source to raw pixels, without decoding the rest.
For splitting one image across several invocations, which on Workers is how a request too large for one CPU allowance can still be served: CPU is rationed per invocation and wall time is not billed, so N bands each get their own allowance.
It pays for JPEG and BMP and costs more for everything else. A band's decode is proportional to the source rows it has to produce, which for those two is a real fraction of the frame. PNG, GIF, TIFF and WebP have to inflate or entropy-decode everything above the band before they can produce it, so N bands cost N times the whole decode and banding makes the total worse. Measured on WebP: a top quarter is 24% of the frame and a bottom half is 97%.
The region is clamped to the image, and a zero width or height means to that edge. Bands that feed a resample need to overlap by the filter's radius, which this does not do for you.
const band = await tinyimg.decodeRegion(source, { x: 0, y: 0, width: 0, height: 512 });
The extent, the channel count and width * height * channels bytes, rows tightly
packed.
Finds the faces in an image.
Runs the two cascades the module carries, or every cascade loaded through loadBlob when any is resident, and groups the results, so a frontal and a profile cascade together find both kinds of face and a face that fires both is one box.
The encoded image.
Most boxes to return.
The detections, ordered by confidence, in the source image's own coordinates.
Reads the name of an error code out of the module.
A negative TinyImageError value, or 0.
The short name the module carries for it.
Releases one resident blob.
What to release.
Optionalid: string
The id it was loaded under, or omitted for the first blob of that kind.
True when one was released.
Releases every resident blob.
Whether a feature was compiled into this module.
Worth checking before offering a format in a UI, rather than calling and handling a failure.
The feature to check.
True when the build contains it.
Hands the module a blob it will read later.
Nothing large or optional is linked in: fonts, color profiles and detection cascades all arrive at runtime, and the module owns the bytes from here until freeBlob. Two ways to deliver one, and no code changes between them:
// from a bucket, which costs one subrequest and no bundle bytes
const font = await env.BLOBS.get('fonts/DejaVuSans.ttf');
if (font) await tinyimg.loadBlob('font', 'sans', font.body);
// or imported as a wrangler Data module, which costs bundle bytes and no latency
import cascade from './lbp-frontalface.bin';
await tinyimg.loadBlob('cascade', 'frontal', cascade);
Loading over an existing kind and id replaces it. At most eight are resident at once.
Clears the work counters, then runs body and reports what it actually did.
Every reduction this library performs is a claim that some work does not happen, and a
label is not evidence: the quarter scale decode carried the word "reduced" through the API,
the planner and the decoder while transforming whole blocks and averaging the result away.
samplesPerTransform is the figure that catches that, reading 64 for a full block and 4 for
a genuine quarter.
The counters are a module-wide total, so nothing else may run against this module while
body does.
The operation's result and the counters it produced.
Reads a file's header without decoding any pixels.
Every format the library recognizes, including the ones it cannot decode: a HEIF answers fully here and fails with a specific error on decode, because it shares AVIF's container and carries HEVC rather than AV1.
The encoded image.
What the header says.
StaticloadInstantiates a compiled module.
Takes a WebAssembly.Module rather than bytes because workerd refuses
WebAssembly.Module(bytes) outright ("Wasm code generation disallowed by embedder"). On
Workers the module comes from importing the wasm file, which the runtime compiles at worker
startup:
import wasm from '@gmitch215/tinyimg/tinyimg.wasm';
import { TinyImgModule } from '@gmitch215/tinyimg';
const tinyimg = TinyImgModule.load(wasm);
The compiled module.
A loaded module ready to use.
StaticloadCompiles and instantiates from bytes.
The escape hatch from load, for node, bun and the browser, where compiling wasm at runtime is allowed. It throws on Workers, and that is the runtime's rule rather than this library's: import the wasm file there instead.
A loaded module ready to use.
A loaded tinyimg module.
One instance owns one linear memory, so a caller that wants isolation between concurrent requests loads more than one rather than sharing this. Sharing one is normally what you want on Workers: the module is compiled once at worker startup and the memory is reused, and the allocator hands every buffer back at the end of a call.