poka.sh

Docs

Image + Metadata Viewer

<!-- GENERATED by build/scripts/gen-viewer-pages.py from viewers/poka-image-with-meta-viewer/plugin.json, viewers/poka-image-with-meta-viewer/src/main.rs, core/proto/preview.proto and FILE_FORMATS.csv. Do not edit by hand: change the source, then run the script. -->

poka-image-with-meta-viewer · version 1.0.0 · poka-image-with-meta-viewer.wasm

What it does

From the crate's //! header:

poka-image-with-meta-viewer. The image a parser decoded + a metadata side panel: PNG, JPEG, GIF, WebP and APNG, and DICOM, NIfTI, RAW, PSD, FITS and the other raster formats.

An image comes either as raw RGBA pixels (image_format "rgba"), which a small script in the page paints on a <canvas> with putImageData, so no browser image codec decodes anything (poka-parsers#451), or as a PNG, JPEG or WebP the parser wrote, shown in an <img> from a data: URI. An ImagePagesAst is either the pages of a document, shown as tabs (CSS only), or, when it carries frame_delays_ms, the frames of an animation, which the page's script plays on one canvas with its delays and play count. The script only moves the parser's pixels onto the canvas and times the frames; it reads no file. The player has Pause/Play, previous and next frame buttons and a frame counter, and starts paused when the system asks for reduced motion.

The image goes into the page as base64, which is 4/3 the size of the image (a data: URI, or the text of a <script type="application/x-poka-rgba"> for pixels), and parsers pass images of up to 8 MiB, or an animation's frames of up to 24 MiB together (poka-image-common's FRAMES_BYTES). The page is therefore streamed to stdout rather than built as one String: building it held the request, the decoded image, the base64 text and the page (grown by doubling) at once, and an incompressible 7.9 MiB PNG needed more than the 64 MiB in plugin.json (poka-parsers#22). Now the base64 is written in small blocks.

The request used to be read with read_to_end, which grows its buffer by doubling (16 MiB for an 8.3 MB request, briefly beside the old 8 MiB), and decoding copied the image into a Vec of its own: 25 MiB at the peak for a 7.9 MiB image. The size of stdin can't be learnt up front — the web and desktop hosts and wasmtime all report it as a stream of length 0 — so the request is read in blocks of up to 1 MiB that are never grown, and the image is decoded as Bytes (poka-viewers#42): a slice of its block when it fits in one, else a single copy of its exact size, with each block freed as it is consumed. The peak is about twice the image, 17 MiB for 7.9 MiB.

Limits

Memory cap 64 MB
Time cap 5000 ms

A module that exceeds either is killed and reported.

What it takes

Stdin is one of these messages, exactly the bytes the parser wrote (core/proto/preview.proto, "Parser → Viewer composition ABI"):

ImagePagesAst

Several pages of one image file (a multi-page TIFF; poka-parsers#242), each an ImageWithMetaAst, shown by poka-image-with-meta-viewer as tabs, or the frames of an animation, which it plays. The field numbers are 15 to 17, which ImageWithMetaAst reserves, so a viewer can take either message: bytes of a plain ImageWithMetaAst decode here as no pages, and bytes of this message never set an ImageWithMetaAst field. Page 1 carries the file's own sections (structure, page count); later pages carry only their own. Viewer: poka-image-with-meta-viewer.

Field Type Comment
pages repeated ImageWithMetaAst The pages, in order
frame_delays_ms repeated uint32 Set when the pages are the frames of one animation (GIF, APNG, animated WebP; poka-parsers#451) rather than the pages of a document: one delay per page, in milliseconds as the file declares it, and the viewer plays the frames in order instead of showing tabs. Empty for pages.
plays uint32 How many times the animation plays: 0 is for ever. Read only with frame_delays_ms.

ImageWithMetaAst

For formats where the visual preview matters AND the metadata is rich enough to warrant its own column: DICOM, NIfTI, RAW, PSD, FITS, and the PNG, JPEG, GIF and WebP previews. image_data is the image the module decoded: raw RGBA pixels (image_format "rgba"), which the viewer draws on a canvas so no browser codec is involved (poka-parsers#451), or, for the parsers not yet moved to that, a PNG, JPEG or WebP the module wrote. Viewer: poka-image-with-meta-viewer.

Field Type Comment
filename string Name of the previewed file
file_size uint64 Size of the previewed file, in bytes
source_format string Free-form header line
image_data bytes The decoded image. For "rgba": width × height × 4 bytes, rows top to bottom, 8-bit sRGB samples with straight (not premultiplied) alpha.
image_format string "rgba" | "png" | "jpeg" | "webp"
width uint32 Pixels of image_data (after any downscale)
height uint32 Pixels of image_data (after any downscale)
sections repeated MetadataSection Metadata shown beside the image

Used by

<!-- USED-BY:BEGIN -->

49 format(s) in FILE_FORMATS.csv name this viewer; the first 30 by name are listed.

Format Parser Extensions
APNG poka-apng .apng
ARW poka-arw .arw
AVIF poka-avif .avif
BMP poka-bmp .bmp
CBZ poka-cbz .cbz
CIN poka-cin .cin
CR2 poka-raw .cr2
CRW poka-crw .crw
CUR poka-cur .cur
DCM poka-dicom .dcm
DCR poka-dcr .dcr
DDS poka-dds .dds
DNG poka-dng .dng
DPX poka-dpx .dpx
EXR poka-exr .exr
FITS poka-fits .fits
GIF poka-gif .gif
HDR poka-hdr .hdr
ICNS poka-icns .icns
ICO poka-ico .ico
JFIF poka-jfif .jfif
JPE poka-jpe .jpe
JPEG poka-jpeg .jpg, .jpeg
JPG poka-jpeg .jpg, .jpeg
JXL poka-jxl .jxl
MRC poka-mrc .mrc
NEF poka-nef .nef
NII poka-nifti .nii
NRRD poka-nrrd .nrrd
ORF poka-orf .orf

And 19 more; the format catalogue in the poka-parsers docs has them all.

This list is read from FILE_FORMATS.csv of a local poka-parsers checkout. It is current only as of the last run of the generator with that checkout.

<!-- USED-BY:END -->