tinyimg - v1.1.1
    Preparing search index...

    Class TinyImgModule

    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.

    Index
    • get features(): (
          | "text"
          | "icc"
          | "png"
          | "bmp"
          | "simd"
          | "jpeg"
          | "gif"
          | "tiff"
          | "webp"
          | "avif"
          | "detect"
      )[]

      Every feature this build contains.

      Returns (
          | "text"
          | "icc"
          | "png"
          | "bmp"
          | "simd"
          | "jpeg"
          | "gif"
          | "tiff"
          | "webp"
          | "avif"
          | "detect"
      )[]

    • get memory(): Memory

      The module's own linear memory.

      Returns Memory

    • get pages(): number

      Pages of linear memory the module currently holds.

      Returns number

    • get version(): [number, number, number]

      The library version, as [major, minor, patch].

      Returns [number, number, number]

    • get versionText(): string

      The library version as major.minor.patch.

      Returns string

    • 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.

      Parameters

      • Optionalkind: BlobKind

        Which kind to list, or omitted for all of them.

      Returns BuiltinBlob[]

      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.

      Parameters

      • source: Source

        The encoded image.

      Returns Promise<RawImage>

      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 });
      

      Parameters

      • source: Source

        The encoded image.

      • region: Rect

        The rectangle in source pixels.

      Returns Promise<RawImage>

      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.

      Parameters

      • source: Source

        The encoded image.

      • limit: number = 16

        Most boxes to return.

      Returns Promise<FaceBox[]>

      The detections, ordered by confidence, in the source image's own coordinates.

    • Reads the name of an error code out of the module.

      Parameters

      • code: number

        A negative TinyImageError value, or 0.

      Returns string

      The short name the module carries for it.

    • Releases one resident blob.

      Parameters

      • kind: BlobKind

        What to release.

      • Optionalid: string

        The id it was loaded under, or omitted for the first blob of that kind.

      Returns boolean

      True when one was released.

    • Releases every resident blob.

      Returns void

    • Whether a feature was compiled into this module.

      Worth checking before offering a format in a UI, rather than calling and handling a failure.

      Parameters

      • name:
            | "text"
            | "icc"
            | "png"
            | "bmp"
            | "simd"
            | "jpeg"
            | "gif"
            | "tiff"
            | "webp"
            | "avif"
            | "detect"

        The feature to check.

      Returns boolean

      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.

      Parameters

      • kind: BlobKind

        What the bytes are.

      • id: string

        The name the module will find it by, at most 31 characters.

      • source: Source

        The bytes, in any shape Source accepts.

      Returns Promise<void>

      TinyImgError If all eight slots are taken, or a cascade does not parse.

    • 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.

      Type Parameters

      • T

      Parameters

      • body: () => T | Promise<T>

        The operation to measure. Its result is returned unchanged.

      Returns Promise<Measured<T>>

      The operation's result and the counters it produced.

      const { work } = await tinyimg.measure(() => image.pixels());
      console.log(work.samplesPerTransform, work.decodedSamples / work.sourceSamples);
    • 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.

      Parameters

      • source: Source

        The encoded image.

      Returns Promise<ImageInfo>

      What the header says.

    • Instantiates 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);

      Parameters

      • module: Module

        The compiled module.

      Returns TinyImgModule

      A loaded module ready to use.

      TinyImgLoadError If the module is not tinyimg, or its ABI is one this wrapper does not understand.

    • Compiles 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.

      Parameters

      • source: Source

        The module's bytes, in any shape Source accepts.

      Returns Promise<TinyImgModule>

      A loaded module ready to use.