Skip to main content
Builtins catalog / nika:image_compose

Media

Tool family from the canonical registry.

invoke

Call this builtin through the invoke verb.

Read this contract

This reference preserves the specification at the revision linked below. Source examples are fragments: their surrounding tasks, inputs and permissions are not supplied here. Consult engine status and nika catalog --tools --json for the installed implementation; a registry declaration is not a runtime qualification.

Usage and behavior

illustration
The §Media graduate #5 — several PNG images become ONE: a contact sheet or grid, a side-by-side (row), a vertical stack (column). Like image_fx it is pure pixel work: NO provider, NO network, NO clock, NO keys, and byte-identical output for identical (input bytes, args) — the artifact’s sha256 joins the hash-chained trace, re-render IS the tamper check, and the recipe (contract tag image_compose/v1 · each input’s sha256 and size · the resolved layout) rides the artifact as a PNG nika tEXt chunk. The recipe carries no timestamp and no path: the same bytes composed from another folder are the same file. Identical bytes already at out: = idempotent skip (skipped_existing). Geometry (NORMATIVE — for a byte-deterministic builtin the arithmetic IS the wire contract; round(a ÷ b) is ⌊(a + ⌊b ÷ 2⌋) ÷ b⌋, never below 1) ·
  • the placed size of a w × h input in a cw × ch cell: none → w × h · fit → round(w·ch ÷ h) × ch when w·ch ≤ h·cw, else cw × round(h·cw ÷ w) · fill → the cover box (round(w·ch ÷ h) × ch when w·ch ≥ h·cw, else cw × round(h·cw ÷ w)), cropped to cw × ch at (⌊(sw − cw) ÷ 2⌋, ⌊(sh − ch) ÷ 2⌋);
  • scaling is the image_fx resize op with filter: auto (linear light) to the placed box — the same bytes that op produces;
  • tracks: with fit / fill every column is cw wide and every row ch high; with none a column is as wide as its widest image and a row as high as its tallest;
  • each image is centered in its cell at (⌊(track_w − pw) ÷ 2⌋, ⌊(track_h − ph) ÷ 2⌋);
  • the canvas is 2·padding + Σ column widths + gap·(columns − 1) by 2·padding + Σ row heights + gap·(rows − 1);
  • an input’s alpha is composited over background BEFORE any scaling, per channel ⌊(c·a + bg·(255 − a) + 127) ÷ 255⌋ in sRGB integers · the artifact is RGB8 (PNG color type 2).
Caps (normative · -005) · each input ≤ 16384 per side · the SUM of the inputs’ pixels ≤ 2^26 · each fit / fill scaled box (the placed size above, before the fill crop) ≤ 16384 per side and ≤ 2^26 pixels · the canvas ≤ 16384 per side and ≤ 2^26 pixels — all judged from the PNG headers and the args BEFORE any decompression or canvas allocation. An input carries exactly one IHDR, its first chunk (PNG-3): the size the caps judged is the size decoded, and a second IHDR is -004. The input count (1..=64) is an argument, -001. Output · { path, sha256, size_bytes, width, height, format, layout, columns, rows, scale, inputs: [{ path, sha256, width, height }], skipped_existing } — artifact bytes NEVER ride outputs (the disk law). Authority. The tool grant, permits.fs.read for EVERY input and permits.fs.write for out:. A static checker judges each literal input path (or whole bare const: reference) as a read and a literal out: as a write, before anything runs: a missing read grant is a check-time NIKA-SEC-004, never a surprise at run, and a read grant an input uses is a use, never declared-but-unused advice. A templated list or element defers to the run’s boundary (NIKA-SEC-004 there). Determinism contract (normative) · no wall-clock · no randomness · integer/fixed-point pixel math · identical (input bytes, args) MUST produce byte-identical artifacts across platforms and releases within a stdlib major (the recipe carries the stable contract tag image_compose/v1, never the engine build). An engine that cannot honor this is not conformant (07-conformance §3). Labels and JPEG input are not part of v1. Throws · NIKA-BUILTIN-IMAGE_COMPOSE-001 invalid arguments (unknown key · out-of-range value · columns/rows outside grid · cell with scale: none · a grid smaller than the list · out: not .png · validation_error) · -002 an input read failed (tool_error · the message names the index) · -003 unsupported input format (non-PNG · palette · exotic depth/interlace · validation_error) · -004 decode failed (structural corruption · CRC/Adler mismatch · tool_error) · -005 a cap exceeded (security_error · never transient) · -006 artifact save failed (tool_error) — image_fx’s ladder, code for code. Plus the boundary NIKA-SEC-004 (paths outside permits.fs).

Arguments

Pass the values required by the tool contract.

Permissions

Understand authority before granting effects.

Errors and recovery

Read diagnostics and choose a recovery policy.

Workflow templates

Put the fragment inside a complete workflow.

Contract provenance

Read the pinned specification · Canonical registry. Tool identity: nika:image_compose. Specification revision: 5cd95cd25c0f.

Documentation

Guides, reference contracts and working examples.

Language spec

the nine-key envelope, Apache-2.0. The contract these docs explain.

Engine source

Rust, AGPL-3.0-or-later. Every commit public.

TypeScript SDK

Use one typed lifecycle locally or against authenticated nika serve HTTP.

Editor extension

The editor extension, frozen at 0.120 and not qualified with 0.124: use nika lsp and the JSON Schema.

Homebrew tap

brew install supernovae-st/tap/nika for the latest tagged CLI release.

SuperNovae

The Paris studio crafting Nika. 🦋