✕
JPIP Gigapixel Viewer
Only the precincts that fall inside the current viewport are fetched and decoded,
so pan-and-zoom on a 400+ MP image stays interactive.
Runs entirely in your browser. HTJ2K decoding is
WebAssembly — no native binary, no plugin, no server-side
decode. The JPIP server only returns JPP-stream bytes; reassembly and
IDWT happen on this page.
Pan
Drag the image with the mouse.
← → ↑ ↓ (Shift = large step)
Trackpad: two-finger scroll.
iPad / iPhone: one-finger drag.
Zoom
+ / − in / out, Home reset.
Trackpad: pinch. Mouse: Ctrl+wheel.
iPad / iPhone: two-finger pinch.
Stats bar
canvas size · zoom · reduce_NL · viewport region · pan · fetch/decode ms
Related
URL parameters
| Param | Default | Effect |
?server= | — | JPIP server (host[:port]). |
?debounce= | 60 | Trailing-debounce window in ms; 0 disables. Coalesces rapid wheel / trackpad events into one fetch. |
?debug | off | Per-frame timing dump to the browser console. |
?variant= | auto | mt or st — force multi- or single-threaded WASM. |
?maxSize= | 1920x1080 | Cap the WebGL render target to WxH. Bounds per-frame precinct fetch + decode work on 4K / ultrawide displays. Pass ?maxSize=window to disable the cap. |
?fit= | stretch | stretch — CSS scales the render target up to fill the window, GPU upsamples via GL_LINEAR.
contain — CSS size == render size, canvas is shown at native pixel scale centered in the window (like the foveation demo). |
?precinctCacheMB= | 64 | LRU precinct cache budget in megabytes. Received precincts are tracked in the &model= cache-model advertisement so the server skips ones already in the viewer's cache on subsequent pans (70–95% byte reduction typical). Set 0 to disable. |
?prefetchMargin= | 128 | After each successful render, fetch an N-canvas-pixel halo of adjacent precincts into the LRU cache so short follow-up pans hit locally. Auto-cancelled when the user resumes interacting. Set 0 to disable. |
?prefetchDelayMs= | 150 | Idle-delay before the halo prefetch fires (in milliseconds). Short enough to overlap typical pause-and-examine behaviour; long enough that continuous panning never triggers it. |
?midPaintMs= | 200 | Show a partial render (whatever precincts have arrived) if a fetch takes longer than N ms. Gives feedback on slow first-time loads; costs one extra decoder run. Fast (LAN / cached) fetches never trigger it. Set 0 to disable. |
?thumbnail= | 1 | Small bottom-right overview showing the full image (fetched once at connect time from the coarsest reduce level) with a rectangle marking the current viewport. Rectangle updates locally on every pan/zoom — no extra server round-trips. Set 0 to hide. |
?thumbnailSize= | 160 | CSS-pixel size of the thumbnail on its long side. Decoder output resolution is independent — only the displayed size changes. |
?cb= | off | Cache-buster for dev iteration. auto or 1 appends ?v=<Date.now()> to the WASM/JS fetches so the browser refetches after every rebuild. Any other value is used verbatim (snapshot at a build hash). Default (no ?cb): full HTTP caching, identical to before. |
?carryForward= | 1 | While a JPIP fetch is in flight after a pan or zoom, redraw the previous frame's pixels at their image-coord position with the thumbnail filling any uncovered area — the image scrolls smoothly under your gesture instead of freezing until the new bytes arrive. Set 0 to disable (canvas stays as last drawn until the new fetch completes). Auto-suppressed on fast networks via ?carryForwardMinMs=. |
?carryForwardMinMs= | 100 | Minimum median fetch+decode latency (ms) before carry-forward redraws fire. On localhost / LAN where fetches typically finish in <50 ms, the previous-frame translate would be visible for ≤2 frames before the sharp final paint replaces it — and the brief blurry-stretched intermediate looks worse than waiting. Above this threshold the smoothing kicks in. Set 0 to force-enable regardless of measured latency. |
JPIP query (§C.4)
Each pan fires one GET:
/jpip?fsiz=W,H&roff=X,Y&rsiz=W,H&type=jpp-stream&model=…
| Field | Meaning |
fsiz | Resolution frame size — picks the discard level. |
roff | Region offset within the frame. |
rsiz | Region size (viewport at the active reduce level). |
model | Cache-model advertisement (see below). |
Cache-model format (§C.9)
After frame 1 the viewer appends &model=Hm,Ht0,M0 (single-tile) or &model=Hm,Ht0-N,M0 (multi-tile) so the server skips header data-bins already delivered.
| Class | Prefix | Example |
| Main header | Hm | Hm |
| Tile header | Ht | Ht0, Ht1-5 |
| Metadata bin | M | M0 |
| Precinct | P | not sent by this demo |