Skip to content

Operations ​

Registry reference. Syntax is defined in docs/reference/intents.md; this document defines the operations that occupy the name space.

An operation is identified by an immutable key. Aliases are accepted and never printed. A slot places it in the canonical order. An exclusive set makes members of the same set conflict.

A group with one member is not declared: repeating one operation is E_DUPLICATE, so a group whose only member is rotate would add nothing and docs/reference/config.md V8 refuses it as a probable mistake.

1. Name space ​

Reserved keys, all phases. Keys are permanent; a key is never reused for a different meaning.

KeyNameSlotExclusiveParameterStatus
qualityquality50encode-targetint, range per formatBuilt
losslesslossless50encode-targetnoneDeclared
sizesize50encode-targetsizeDeclared
efforteffort50noneint, range per formatDeclared
compresscompress50noneint, 0 to 9Declared
colorscolors50noneint, 2 to 256Declared
capcap28scaleint, 16 to 16384Built
resizeresize25scaledim, 1 to 16384 per sideBuilt
widthwidth26scaleint, 16 to 16384Built
heightheight27scaleint, 16 to 16384Built
cropcrop24noneratio, 1 to 1000 per sideDeclared
rotaterotate21noneenum: 90, 180, 270Built
fliphfliph22nonenoneBuilt
flipvflipv23nonenoneBuilt
graygray30nonenoneDeclared
nometanometa60nonenoneDeclared
noprofilenoprofile60nonenoneDeclared
trimtrim10time-slicerange of timeReserved
atat10time-slicetimeBuilt
speedspeed10tempoint 1 to 400, percentReserved
fpsfps10tempoint 1 to 240Built
mutemute40audio-tracknoneBuilt
normalizenormalize40nonenoneReserved
monomono40nonenoneReserved
bitratebitrate40audio-rateint, range per codecReserved
codeccodec40noneenum, per containerReserved
pagepage10time-slicerange of intReserved
dpidpi10noneint, 36 to 1200Reserved
askask90confirmnoneBuilt
nownow90confirmnoneBuilt

Status is Built when this build has a tool fragment for the operation, Declared when the grammar accepts it but no tool fragment exists yet, and Reserved when the name and its parameter are fixed but the operation is not implemented. Declared and Reserved operations fail with E_UNSUPPORTED rather than doing nothing.

Slots are integers used for presentation: they order a generated editor's controls and the rows of retype list, and they never reorder an intent string. Two operations that interact do not share a slot, so a generated interface does not present them as interchangeable. The geometry numbers run rotate 21, fliph 22, flipv 23, crop 24, resize 25, width 26, height 27, cap 28, which is a workable order to show them in and nothing more.

Aliases:

AliasKey
qquality
wwidth
hheight
ddpi
grey, grayscalegray

2. Geometry semantics ​

Geometry runs in the order written, and the order changes the result: rotate90+cap1080 rotates and then caps, while cap1080+rotate90 caps and then rotates, and the two are not the same image. Nothing reorders a string, docs/reference/intents.md C2.

OperationRule
rotateClockwise by the given multiple of 90 degrees. Pixel-exact, no resampling
fliph, flipvMirror about the vertical, respectively horizontal, axis
cropCentre crop to the given aspect ratio, keeping the largest region that fits. Never upscales
resizeFit inside WxH preserving aspect. A 0 side is computed from the other. Never upscales
widthScale so the width equals N, preserving aspect. Never upscales
heightScale so the height equals N, preserving aspect. Never upscales
capScale down so the longest edge is at most N. Equivalent to resize with both sides set to N

Resampling filter is Lanczos3 for downscale and triangle for upscale. Upscale is never implicit; a resize whose result would enlarge the image produces the source size unchanged.

3. Colour and metadata ​

OperationRule
grayConvert to single channel. luma from Rec. 709 coefficients in linear light
nometaRemove EXIF, XMP, IPTC, GPS, thumbnails and comments. Preserve the ICC profile
noprofileRemove the ICC profile. Pixel values are not converted, so colours may shift

Orientation is always applied from EXIF and then removed, once, before any geometry. A job never produces a file whose EXIF orientation contradicts its pixels.

4. Encoder semantics ​

OperationRule
qualityFidelity dial in the target format's own scale. Range and meaning per format in docs/reference/dials.md
effortSpeed dial in the target encoder's own scale. Higher is slower
losslessRequest lossless encoding. Conflicting with quality and size
sizeRe-encode to fit under a byte budget. The search tries quality, then effort; an unreachable budget is E_VALUE_RANGE after the search
compressLossless compression level, 0 to 9, for formats whose container has one (PNG deflate)
colorsPalette size for paletted formats. 256 means the format maximum

quality, size and lossless share the encode-target group: exactly one target per output. effort is orthogonal.

5. Applicability, image formats ​

y applicable, n inapplicable, so E_INAPPLICABLE.

Operationjpgpngwebpavifheicgiftiffbmpico
qualityynyyynnnn
effortnnyynnnnn
losslessnnyyynnnn
sizeyyyyynnnn
compressnynnnnynn
colorsnynnnynnn
capyyyyyyyyy
resizeyyyyyyyyy
widthyyyyyyyyy
heightyyyyyyyyy
cropyyyyyyyyy
rotateyyyyyyyyy
fliphyyyyyyyyy
flipvyyyyyyyyy
grayyyyyyyyyy
nometayyyyyyyny
noprofileyyyyyyyny

size on png means the deflate level is searched, not quality; on lossless targets it is satisfied or refused by compress bounds.

png with colors produces a paletted PNG, that is PNG8.

ico requires both dimensions at most 256. A plan that would produce a larger icon is rejected with E_INAPPLICABLE and a hint to add cap256, rather than left to the encoder to fail.

Per-format constraints of this kind come from Tools §6, because they are properties of the encoder rather than of the operation.

6. Not specified yet ​

at, fps, mute and cap work for video and audio. Documents have their formats and no operations: md, html, docx, odt, epub and pdf convert through pandoc.

Archives take no operations at all: zip, tar and tar.gz store the bytes they are given, and an operation that changed them would make the format an encoder. A plan that asks for one is E_UNSUPPORTED naming the archive. A directory is not an archive source, so the gesture stays container to container.

crop, gray, nometa, noprofile, lossless, size, effort, compress and colors are declared and do not yet have a tool fragment, so using one is E_UNSUPPORTED rather than a silent no-op.

trim, speed, normalize, mono, bitrate, codec, page and dpi stay reserved with their slots and parameters, and a job that uses one is E_UNSUPPORTED rather than E_NAME_UNKNOWN. Two of them have a reason rather than a pending vertical:

  • page and trim take a range, and a fragment has one {value} hole. The grammar reads a range, but expressing two numbers to a tool needs an argument that can carry both
  • dpi means something different to every document engine, and nothing at all to docx: pandoc's variable reaches a LaTeX preamble and a typst document alike only by accident. A dial that silently does nothing in half its targets is worse than a dial that refuses

7. Presets ​

A preset is a named token sequence and occupies the same name space. See docs/reference/config.md.

toml
[presets.thumbnail]
param = { class = 'int', min = 16, max = 4096 }
tokens = ['cap={value}', 'quality85']

[presets.headshot]
tokens = ['crop1x1', 'cap1024', 'quality80', 'nometa']

Presets MUST expand to a conflict-free token set at load; a preset that cannot satisfy its own exclusivity rules fails to load. A preset MUST NOT contain ask or now.