1000 lines
33 KiB
C
1000 lines
33 KiB
C
/*
|
||
* WAI — Web AI media transport + execution.
|
||
*
|
||
* Auto-generated by cbindgen from src/ffi.rs. DO NOT EDIT — regenerate
|
||
* by rebuilding `wai-rs` (the build.rs runs cbindgen) or by running
|
||
* cbindgen --config cbindgen.toml --crate wai --output include/wai.h
|
||
*
|
||
* SDK contract:
|
||
* - Every `wai_*` function returns a `wai_status_t` (typedef int).
|
||
* 0 = ok; non-zero = see WAI_ERR_* below + wai_last_error().
|
||
* - Any `WaiBuffer` written into an out parameter MUST be freed via
|
||
* `wai_buffer_free`. Passing a zero-cap buffer to free is safe.
|
||
* - `wai_last_error()` returns a NUL-terminated UTF-8 string that is
|
||
* valid until the next wai_* call on the same thread.
|
||
*
|
||
* Build the library:
|
||
* cargo build --release # produces libwai.{so,dylib,a}
|
||
* Link with:
|
||
* gcc your.c -lwai # static or dynamic per linker
|
||
*/
|
||
|
||
|
||
#ifndef WAI_H
|
||
#define WAI_H
|
||
|
||
#pragma once
|
||
|
||
#include <stdarg.h>
|
||
#include <stdbool.h>
|
||
#include <stdint.h>
|
||
#include <stdlib.h>
|
||
|
||
/**
|
||
* The most samples a reader must accept from one audio payload (SPEC §2, *Reader
|
||
* limits*), counting every channel: 2^27, 46 minutes of one channel at 48 kHz. Decoded
|
||
* to `f32` it is 512 MiB. Longer audio is carried as more than one object.
|
||
*/
|
||
#define AUDIO_DECODED_MAX_SAMPLES (1 << 27)
|
||
|
||
/**
|
||
* The widest and the tallest picture a reader must accept (SPEC §2, *Reader limits*):
|
||
* 65 536 pixels, the largest side an AV1 sequence header can declare.
|
||
*/
|
||
#define IMAGE_MAX_SIDE (1 << 16)
|
||
|
||
/**
|
||
* The most pixels a reader must accept in one picture (SPEC §2, *Reader limits*):
|
||
* 2^27, a 16 384 × 8 192 picture. Decoded to 8-bit RGB it is 384 MiB.
|
||
*/
|
||
#define IMAGE_MAX_PIXELS (1 << 27)
|
||
|
||
/**
|
||
* The most bytes a `wai.text.zstd` or `wai.text.xz` payload may decode to that a reader
|
||
* must accept (SPEC §2, *Reader limits*): 2^27. The decoders here write no more than
|
||
* this, whatever the payload asks for: one that decodes to more is refused
|
||
* (`text_decoded_too_long`) when its output would pass the limit, so the output buffer
|
||
* never holds more. The reference writers refuse to encode more.
|
||
*/
|
||
#define TEXT_DECODED_MAX_LEN (1 << 27)
|
||
|
||
/**
|
||
* The base-2 logarithm of [`TEXT_WINDOW_MAX_LEN`].
|
||
*/
|
||
#define TEXT_WINDOW_MAX_LOG 27
|
||
|
||
/**
|
||
* The most history a `wai.text.zstd` or `wai.text.xz` stream may ask its decoder to
|
||
* keep that a reader must accept (SPEC §2, *Reader limits*): 2^27 bytes, as the zstd
|
||
* frame's window size or the LZMA2 dictionary size. A stream that declares more is
|
||
* refused (`text_window_too_large`) from the declaration, before the decoder allocates
|
||
* it. Together with [`TEXT_DECODED_MAX_LEN`] it bounds the memory a decode takes: the
|
||
* length limit bounds the output, and this bounds what the decoder holds beside it.
|
||
*/
|
||
#define TEXT_WINDOW_MAX_LEN (1 << TEXT_WINDOW_MAX_LOG)
|
||
|
||
/**
|
||
* The most temporal units a reader must accept in one AV1 payload (SPEC §2, *Reader
|
||
* limits*): 2^20, 4.9 hours at 60 frames a second. Each frame is held to the picture
|
||
* limits of [`crate::codecs::image::check_dimensions`].
|
||
*/
|
||
#define VIDEO_MAX_TEMPORAL_UNITS (1 << 20)
|
||
|
||
/**
|
||
* What the frames [`av1_decode`] returns may take together: 4 GiB of RGB. A payload
|
||
* within the reader limits can declare far more (2^20 frames of 2^27 pixels), and the
|
||
* whole-output entry points keep every frame at once, so they refuse one past their
|
||
* budget (`video_decoded_too_large`) from its header, before they decode.
|
||
* [`av1_decode_each`] keeps one frame at a time and decodes any payload within the
|
||
* reader limits.
|
||
*/
|
||
#define AV1_DECODE_DEFAULT_MAX_LEN 4294967296
|
||
|
||
/**
|
||
* The longest manifest, in bytes, a reader must accept (SPEC §2, *Reader limits*):
|
||
* 2^27 (128 MiB). It is sized to the largest manifest a conforming layer has: a `prev`
|
||
* (staged-delivery §3) that names a different producer for each of the 2^20 units a
|
||
* `WIR1` layer may cover (staged-delivery Appendix A.3, `n_units ≤ 2^20`), about 90
|
||
* bytes a run. The reference readers refuse a longer one before they read it, and the
|
||
* reference writers refuse to write one, so `man_len` never asks a reader to read
|
||
* more. It bounds the bytes read; [`MANIFEST_MAX_VALUES`] bounds what a parse builds
|
||
* from them. The manifest's nesting has its own limit: the JSON reader refuses 128
|
||
* nested arrays and objects and takes 127 ([`check_manifest_text`]).
|
||
*/
|
||
#define MANIFEST_MAX_LEN (1 << 27)
|
||
|
||
/**
|
||
* The most JSON values a manifest may hold that a reader must accept (SPEC §2, *Reader
|
||
* limits*): 2^22, counting the manifest object and every value nested in it, at any
|
||
* depth; a member's name is not a value. It is sized to the same layer as
|
||
* [`MANIFEST_MAX_LEN`]: a `prev` that names a different producer for each of 2^20 units
|
||
* is three values a run (the run, its `producer` and its `count`), 3·2^20 and a few more
|
||
* in all. The reference readers count a manifest's values before they parse it
|
||
* ([`check_manifest_text`]) and refuse it as soon as the count passes the limit
|
||
* (`manifest_too_many_values`), so the JSON tree a parse builds holds at most this many
|
||
* values, whatever the manifest's length.
|
||
*/
|
||
#define MANIFEST_MAX_VALUES (1 << 22)
|
||
|
||
/**
|
||
* The most samples, counting every channel, a reader must be willing to render from
|
||
* one object: 2^27, the audio limit of SPEC §2 (46 minutes of one channel at 48 kHz).
|
||
*/
|
||
#define RENDER_MAX_SAMPLES (1 << 27)
|
||
|
||
/**
|
||
* The most frames a reader must be willing to render from one object: 2^20, the
|
||
* video limit of SPEC §2 (4.9 hours at 60 frames a second).
|
||
*/
|
||
#define RENDER_MAX_FRAMES (1 << 20)
|
||
|
||
#define WAI_OK 0
|
||
|
||
#define WAI_ERR_INVALID_ARG 1
|
||
|
||
#define WAI_ERR_CODEC 2
|
||
|
||
#define WAI_ERR_CONTAINER 3
|
||
|
||
#define WAI_ERR_PANIC 4
|
||
|
||
/**
|
||
* A pin was refused (SPEC §3.1); `wai_last_error` starts with the reason.
|
||
*/
|
||
#define WAI_ERR_PRIOR 5
|
||
|
||
/**
|
||
* `intent = replicate` is not sound for the capability decoded through (SPEC §7).
|
||
*/
|
||
#define WAI_ERR_UNSOUND_REPLICATE 6
|
||
|
||
/**
|
||
* No rendition of a `WAI2` envelope can be picked (SPEC §7.1).
|
||
*/
|
||
#define WAI_ERR_NO_RENDITION 7
|
||
|
||
/**
|
||
* The budget a process starts with: 256 MiB. A set holds its weights as `i64` once
|
||
* lowered, four times their bytes in a `WHM1` file, so this keeps a set of about
|
||
* 60 MB of `WHM1` networks with room beside it for small ones.
|
||
*/
|
||
#define LoadedSets_DEFAULT_BUDGET (256 << 20)
|
||
|
||
/**
|
||
* What an entry is counted for beyond its set: its share of the store's two indexes
|
||
* (by key, and by last use). It is more than either index's node for one entry, so
|
||
* the count is never under what the store holds.
|
||
*/
|
||
#define LoadedSets_INDEX_BYTES_PER_ENTRY 4096
|
||
|
||
/**
|
||
* Probability output scale of [`softmax`]: results are at `2^PROB_FRAC`
|
||
* (they sum to ~`2^PROB_FRAC`).
|
||
*/
|
||
#define PROB_FRAC 16
|
||
|
||
/**
|
||
* Fractional bits of the Q16 fixed-point format.
|
||
*/
|
||
#define F 16
|
||
|
||
/**
|
||
* 1.0 in Q16.
|
||
*/
|
||
#define S (1 << F)
|
||
|
||
/**
|
||
* Number of action planes appended to the latent for the transition (dx, dy, btn).
|
||
*/
|
||
#define A 3
|
||
|
||
#define MARKER_SOC 65408
|
||
|
||
#define MARKER_EOC 65409
|
||
|
||
#define MARKER_PIH 65410
|
||
|
||
#define MARKER_TON 65411
|
||
|
||
#define MARKER_RDI 65412
|
||
|
||
#define MARKER_SOZ 65416
|
||
|
||
#define MARKER_SORP 65417
|
||
|
||
#define MARKER_SORS 65418
|
||
|
||
#define MARKER_SOQ 65419
|
||
|
||
#define MARKER_UDI 65420
|
||
|
||
/**
|
||
* The media kind of a [`WaiDecoded`].
|
||
*/
|
||
#define WAI_DECODED_AUDIO 1
|
||
|
||
/**
|
||
* The media kind of a [`WaiDecoded`].
|
||
*/
|
||
#define WAI_DECODED_IMAGE 2
|
||
|
||
/**
|
||
* The media kind of a [`WaiDecoded`].
|
||
*/
|
||
#define WAI_DECODED_VIDEO 3
|
||
|
||
/**
|
||
* `wai_neural_decode_ex` flag: apply SPEC §7's replicate rule (strict).
|
||
*/
|
||
#define WAI_DECODE_STRICT 1
|
||
|
||
#define SECTION_CONTRACT 1
|
||
|
||
#define SECTION_GRAPH 2
|
||
|
||
#define SECTION_ASSETS 3
|
||
|
||
#define SECTION_OPLOG 4
|
||
|
||
#define SECTION_SEAL 5
|
||
|
||
/**
|
||
* Payload = a record body (`n_cells u16 | cells…`). Target MUST
|
||
* equal `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `pos[3] | vel[3] | scalar` (7 × i64). Target MUST equal
|
||
* `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `pos[3] | vel[3] | radius | restitution` (8 × i64). Target MUST
|
||
* equal `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `parent[16] | translation[3] | rotation[4] | scale[3]`
|
||
* (16 + 10×`i64` Fx = 96 bytes). Target MUST equal
|
||
* `mint_node_id(actor, lamport)`. `parent` is another bone's node
|
||
* id, or all-zero for a root.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload — remove the bone.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload; removes a particle or member. LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* `field_idx u16 | cell(tag u8 | value)` — replace one cell.
|
||
* Resolution: LWW.
|
||
*/
|
||
#define SET_CELL 16
|
||
|
||
/**
|
||
* `field_idx u16 | i64` — add to an `Int` cell (saturating).
|
||
* Resolution: SUM.
|
||
*/
|
||
#define ADD_INT 17
|
||
|
||
/**
|
||
* `field_idx u16 | i64` (Fx bits) — add to a `Fixed` cell
|
||
* (saturating). Resolution: SUM.
|
||
*/
|
||
#define ADD_FIXED 18
|
||
|
||
#define Fx_FRAC_BITS 32
|
||
|
||
/**
|
||
* `scalar` (1 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_SCALAR 3
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to velocity. Resolution: SUM — two
|
||
* actors shoving the same node both act; neither is discarded.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to velocity. Resolution: SUM.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to a particle's velocity. SUM.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64) on a particle. LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `rotation[4]` (4×`i64` Fx quaternion x,y,z,w) — the animation
|
||
* driver: set a joint's local rotation.
|
||
*/
|
||
#define SET_ROTATION 16
|
||
|
||
/**
|
||
* `translation[3]` (3×`i64` Fx).
|
||
*/
|
||
#define SET_TRANSLATION 17
|
||
|
||
/**
|
||
* `scale[3]` (3×`i64` Fx).
|
||
*/
|
||
#define SET_SCALE 18
|
||
|
||
/**
|
||
* Create a particle: `pos[3] | vel[3] | inv_mass` (7 × i64).
|
||
* `inv_mass == 0` is an anchor (infinite mass — foundations).
|
||
* Target MUST equal `mint_node_id(actor, lamport)`. LWW.
|
||
*/
|
||
#define CREATE_PARTICLE 1
|
||
|
||
/**
|
||
* Create a member between two particles:
|
||
* `node_a (16 B) | node_b (16 B) | yield_strain (i64)`.
|
||
* Rest length is measured from the endpoints' current positions
|
||
* at apply time (weld what's there — deterministic, since apply
|
||
* order is canonical). Target MUST be minted; endpoints missing
|
||
* or coincident → deterministic no-op. LWW.
|
||
*/
|
||
#define CREATE_MEMBER 16
|
||
|
||
/**
|
||
* Fixed PCM window per reconstruction block (samples). The final block may
|
||
* be short; every block carries its index, so the partition is canonical.
|
||
*/
|
||
#define SEGMENT_SAMPLES 4096
|
||
|
||
#define SAW 0
|
||
|
||
#define SQUARE 1
|
||
|
||
#define TRIANGLE 2
|
||
|
||
#define PULSE25 3
|
||
|
||
/**
|
||
* The standard uncertainty, in microjoules, that sealing an estimate as a
|
||
* whole number of microjoules adds (`extensions/energy-measurement.md` §2.3,
|
||
* `u_res`). `joules_micro` is an integer, so a figure rounded to the nearest
|
||
* microjoule lies within ±0.5 µJ of the estimate it came from. With only that
|
||
* limit known the error is taken as rectangular (GUM F.2.2.1): `0.5/√3` µJ.
|
||
*
|
||
* It is the same in microjoules whatever the figure, so relative to the
|
||
* figure it is large when the figure is small: 29 % of 1 µJ, 2.9 % of 10 µJ.
|
||
*/
|
||
#define RESOLUTION_UNCERTAINTY_UJ 0.2886751345948129
|
||
|
||
/**
|
||
* The standard uncertainty, in microjoules, of the difference of two readings
|
||
* of a register that counts whole microjoules. Each reading stands for an
|
||
* energy up to one step away from it; two such offsets, each rectangular over
|
||
* one step, differ by a triangular error over (−1, +1) µJ (GUM 4.3.9):
|
||
* `1/√6` µJ. This is the resolution of a figure read as a counter delta.
|
||
*/
|
||
#define REGISTER_DELTA_UNCERTAINTY_UJ 0.4082482904638631
|
||
|
||
/**
|
||
* The least `joules_micro × relative_ppm` a declaration may have (§2.3). A
|
||
* declared relative uncertainty `ppm` on a figure of `F` µJ is an absolute
|
||
* standard uncertainty of `F · ppm / 10⁶` µJ, which must be at least the
|
||
* least resolution a whole-microjoule figure carries,
|
||
* [`RESOLUTION_UNCERTAINTY_UJ`]. That is `F · ppm ≥ 288 675.13…`, and since
|
||
* `F · ppm` is an integer, `≥ 288 676`. A figure read as a register delta
|
||
* carries more, [`REGISTER_DELTA_UNCERTAINTY_UJ`], which this floor does not
|
||
* check.
|
||
*
|
||
* It is checkable from the receipt alone, in integers, so every verifier
|
||
* reaches the same verdict.
|
||
*/
|
||
#define RESOLUTION_FLOOR_UJ_PPM 288676
|
||
|
||
/**
|
||
* The most chaining values a proof may carry.
|
||
*/
|
||
#define HeadProof_MAX_CV 64
|
||
|
||
/**
|
||
* The fixed part of the file: magic, cid, `envelope_len`, `covered_len`, `n_cv`.
|
||
*/
|
||
#define HeadProof_FIXED_LEN 53
|
||
|
||
/**
|
||
* How many earlier groups of one chain [`ReceiptChains`] keeps the link hashes of, to
|
||
* tell a fork from a gap (§3 step 3). Past it, the oldest are forgotten, and a fork from
|
||
* before them reads as a gap: refused all the same, for another reason.
|
||
*/
|
||
#define CHAIN_HELD_LINKS 65536
|
||
|
||
/**
|
||
* `CausalOp::mutation_kind` for an action input (move/look/buttons + free payload).
|
||
*/
|
||
#define MUT_ACTION 1
|
||
|
||
/**
|
||
* Fixed-point fractional bits for core scales and the reconstruction
|
||
* accumulator. Scales live at `2^SCALE_FRAC`; the i128 contraction rescales by
|
||
* `>> SCALE_FRAC` after absorbing each core's per-column scale.
|
||
*/
|
||
#define SCALE_FRAC 24
|
||
|
||
/**
|
||
* Trits per packed byte. `3^5 = 243 < 256`, the near-entropy-optimal
|
||
* balanced-ternary packing (1.58 bits/trit) the ternary fabric uses.
|
||
*/
|
||
#define TRITS_PER_BYTE 5
|
||
|
||
/**
|
||
* Q32.32 fixed-point value.
|
||
*/
|
||
typedef struct Fx Fx;
|
||
|
||
typedef struct wai_buffer_t {
|
||
uint8_t *data;
|
||
uintptr_t len;
|
||
uintptr_t cap;
|
||
} wai_buffer_t;
|
||
|
||
/**
|
||
* What decoding an integer payload will cost (`wai_int_payload_declared`,
|
||
* `extensions/integer-payloads.md` §7, *Memory and work*): the decoded output's
|
||
* bytes (`output_known` 1 where they are filled), the symbols its streams code, and,
|
||
* where `cost_known` is 1, the most bytes the reference decode holds at once beyond
|
||
* the payload and the parsed set (`working_bytes`) and the networks'
|
||
* multiply-accumulates, `macs_hi·2^64 + macs_lo`.
|
||
*/
|
||
typedef struct wai_int_declared_t {
|
||
uint64_t output_bytes;
|
||
uint8_t output_known;
|
||
uint64_t symbols;
|
||
uint64_t working_bytes;
|
||
uint64_t macs_lo;
|
||
uint64_t macs_hi;
|
||
uint8_t cost_known;
|
||
} wai_int_declared_t;
|
||
|
||
/**
|
||
* What `wai_neural_decode_ex` decoded.
|
||
*
|
||
* `kind` is `WAI_DECODED_AUDIO` (`data` holds `f32` samples, `sample_rate` set),
|
||
* `WAI_DECODED_IMAGE` (`data` holds RGB8, `width` and `height` set) or
|
||
* `WAI_DECODED_VIDEO` (`data` holds the frames' RGB8 concatenated, `width`,
|
||
* `height`, `n_frames` and `fps_x_1000` set). `index` is the `WAI2` rendition
|
||
* picked (0 for a `WAI1` envelope). Free `data` with `wai_buffer_free`.
|
||
* `wai_neural_decode_ex` writes the whole struct on every call that passes a
|
||
* non-null `out`: on failure `kind` is 0 and `data` is empty, so `data` is always
|
||
* safe to free.
|
||
*/
|
||
typedef struct wai_decoded_t {
|
||
uint32_t kind;
|
||
uint32_t index;
|
||
struct wai_buffer_t data;
|
||
uint32_t width;
|
||
uint32_t height;
|
||
uint32_t sample_rate;
|
||
uint32_t n_frames;
|
||
uint32_t fps_x_1000;
|
||
} wai_decoded_t;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif // __cplusplus
|
||
|
||
/**
|
||
* Free a buffer previously returned by any `wai_*_encode` /
|
||
* `wai_*_decode` / `wai_envelope_*` call. Safe to call with a null
|
||
* or zero-cap buffer.
|
||
*
|
||
* # Safety
|
||
* `buf.data` must have been produced by this crate.
|
||
*/
|
||
void wai_buffer_free(struct wai_buffer_t buf);
|
||
|
||
/**
|
||
* Returns a pointer to the most recent error message for this thread,
|
||
* or null if there is none. The pointer is valid until the next FFI
|
||
* call on this thread that sets an error.
|
||
*/
|
||
const char *wai_last_error(void);
|
||
|
||
/**
|
||
* Read what decoding the payload of an integer capability will cost before decoding
|
||
* it, so a sink can refuse a payload past its own size policy first
|
||
* (`extensions/integer-payloads.md` §7, *Memory and work*). `capability` is the
|
||
* envelope's capability (or the `WAI2` component's). The payload is parsed as a sink
|
||
* parses it: one that is not the format SPEC §5 pins `capability` to is
|
||
* `WAI_ERR_INVALID_ARG`, with its code in `wai_last_error`, and so is a capability
|
||
* with no pinned integer format.
|
||
*
|
||
* With `set_path` null, only the header is read: a `wai.neural.int_hyper` image's
|
||
* size is its synthesis network's, so `output_known` is 0 for it, and `cost_known` is
|
||
* 1 only for a `WIV1` with keyframe 0, which runs no network. With `set_path` naming
|
||
* the capability's parameter set — a directory holding its members by the names §9
|
||
* gives, or the file of a one-file set — every figure is filled
|
||
* (`int_payload::declared_cost`), and the set is checked against the payload as a
|
||
* decode checks it first (`set_incomplete`, `model_mismatch`, `geometry_mismatch`,
|
||
* …). The set is read as given, unverified: a pin is verified when the envelope is
|
||
* decoded. A build without `neural_int` reads no set.
|
||
*
|
||
* # Safety
|
||
* `capability` NUL-terminated; `payload` valid for `payload_len` bytes; `set_path`
|
||
* null or NUL-terminated UTF-8; `out` writable.
|
||
*/
|
||
|
||
int wai_int_payload_declared(const char *capability,
|
||
const uint8_t *payload,
|
||
uintptr_t payload_len,
|
||
const char *set_path,
|
||
struct wai_int_declared_t *out);
|
||
|
||
/**
|
||
* Builds a complete WAI file from a codec-produced payload + manifest
|
||
* fields. `manifest_json` is a UTF-8 JSON object overriding/supplying
|
||
* any fields; `payload` is the bytes from one of the codec encoders.
|
||
* Refuses (`WAI_ERR_INVALID_ARG`) a manifest that names a candidate capability
|
||
* as its capability or fallback, which an encoder MUST NOT emit (SPEC §5,
|
||
* *Candidate capabilities*), and a payload that is not the format SPEC §5 pins its
|
||
* integer capability or fallback to (*Payloads of the WAI-native integer codecs*):
|
||
* it emits through `Wai::to_emit_bytes`.
|
||
*
|
||
* # Safety
|
||
* `manifest_json` NUL-terminated; `payload` valid for `payload_len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_envelope_pack(const char *manifest_json,
|
||
const uint8_t *payload,
|
||
uintptr_t payload_len,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Detect WAI version from a byte stream. Returns 1 (WAI1), 2 (WAI2),
|
||
* or 0 with an error message in `wai_last_error` for unknown magic.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes.
|
||
*/
|
||
int wai_envelope_detect_version(const uint8_t *bytes, uintptr_t len);
|
||
|
||
/**
|
||
* Pack a WAI2 multi-rendition envelope.
|
||
*
|
||
* - `manifest_json` must declare a `renditions` array of length `n`.
|
||
* - `payload_data` is an array of `n` byte-buffer pointers.
|
||
* - `payload_lens` is the matching array of `n` lengths.
|
||
* - The i-th payload pairs with `manifest.renditions[i]`.
|
||
*
|
||
* Refuses (`WAI_ERR_INVALID_ARG`) a table with a component, in either role,
|
||
* whose capability is a candidate (SPEC §5, *Candidate capabilities*), or whose
|
||
* payload is not the format SPEC §5 pins its integer capability to: it emits
|
||
* through `WaiMulti::to_emit_bytes`.
|
||
*
|
||
* # Safety
|
||
* All array pointers must point to valid memory of the declared length.
|
||
*/
|
||
|
||
int wai_envelope_pack_multi(const char *manifest_json,
|
||
const uint8_t *const *payload_data,
|
||
const uintptr_t *payload_lens,
|
||
uintptr_t n_payloads,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Parse a WAI2 envelope. Writes three outputs:
|
||
*
|
||
* - `out_manifest` — the manifest JSON exactly as the envelope carries it
|
||
* (UTF-8 bytes, no NUL), so members this library does not model survive
|
||
* - `out_renditions_json` — a JSON array with one object per component:
|
||
* `capability`, `kind`, `offset` (into `out_payload_block`), `length`, and
|
||
* `selectable` (whether SPEC §7.1 may pick it: a companion, or a companion-only
|
||
* capability, never is), plus `id`, `sha256`, `prior`, `role`, `companion_of`
|
||
* and `companion_of_id` when the entry carries them. A C sink selects with
|
||
* `wai_envelope_select` rather than by hand.
|
||
* - `out_payload_block` — every rendition's payload bytes, packed
|
||
* contiguously. The caller indexes via the JSON above.
|
||
*
|
||
* This avoids exposing a C struct array (and the ownership pain that
|
||
* comes with it). Any JSON parser the consumer already has decodes
|
||
* the rendition table in two lines.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out_manifest` writable; `out_renditions_json` writable; `out_payload_block` writable.
|
||
*/
|
||
|
||
int wai_envelope_unpack_multi(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out_manifest,
|
||
struct wai_buffer_t *out_renditions_json,
|
||
struct wai_buffer_t *out_payload_block);
|
||
|
||
/**
|
||
* Parses a WAI envelope. Writes the manifest JSON exactly as the envelope
|
||
* carries it to `out_manifest` (so `security`, and members this library does not
|
||
* model, survive) and the raw payload to `out_payload`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out_manifest` writable; `out_payload` writable.
|
||
*/
|
||
|
||
int wai_envelope_unpack(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out_manifest,
|
||
struct wai_buffer_t *out_payload);
|
||
|
||
/**
|
||
* SPEC §7.1 selection for a `WAI2` envelope at a sink that advertises the
|
||
* capabilities in `advertised_json` (a NUL-terminated JSON array of capability
|
||
* strings). Writes the index of the picked rendition to `out_index`: the first
|
||
* entry that is selectable (never a companion, nor a capability that is not
|
||
* dispatchable under SPEC §4: companion-only, a candidate, a record or a
|
||
* derivation), advertised, and whose payload matches its `sha256`. This call holds no
|
||
* parameter set, so an entry whose pin applies is skipped (`prior_not_held`); a
|
||
* sink that holds parameter sets decodes through `wai_neural_decode_ex`, which
|
||
* verifies each pin. Returns `WAI_ERR_NO_RENDITION` when nothing is picked, with
|
||
* each entry's index and reason in `wai_last_error`.
|
||
*
|
||
* # Safety
|
||
* `envelope` valid for `envelope_len` bytes; `advertised_json` NUL-terminated;
|
||
* `out_index` writable.
|
||
*/
|
||
|
||
int wai_envelope_select(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *advertised_json,
|
||
uint32_t *out_index);
|
||
|
||
/**
|
||
* Encode RGB pixels (row-major, 3 bytes per pixel) as PNG.
|
||
*
|
||
* # Safety
|
||
* `rgb` must point to a valid RGB buffer of at least `len` bytes;
|
||
* `out` must be a writable `WaiBuffer*`. Pass `(null, 0)` for empty.
|
||
*/
|
||
|
||
int wai_image_png_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode a PNG byte stream to RGB. Returns `(rgb, h, w)`.
|
||
*
|
||
* A picture past the reader limits of SPEC §2 (wider or taller than
|
||
* [`IMAGE_MAX_SIDE`](crate::codecs::image::IMAGE_MAX_SIDE) or holding more than
|
||
* [`IMAGE_MAX_PIXELS`](crate::codecs::image::IMAGE_MAX_PIXELS) pixels) is refused with
|
||
* `WAI_ERR_CODEC` from the size it declares, before it decodes; the message begins
|
||
* `image_too_large`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_h` writable; `out_w` writable.
|
||
*/
|
||
|
||
int wai_image_png_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
/**
|
||
* # Safety
|
||
* `rgb` valid for `len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_image_avif_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* A picture past the reader limits of SPEC §2 (wider or taller than
|
||
* [`IMAGE_MAX_SIDE`](crate::codecs::image::IMAGE_MAX_SIDE) or holding more than
|
||
* [`IMAGE_MAX_PIXELS`](crate::codecs::image::IMAGE_MAX_PIXELS) pixels) is refused with
|
||
* `WAI_ERR_CODEC` from the size it declares, before it decodes; the message begins
|
||
* `image_too_large`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_h` writable; `out_w` writable.
|
||
*/
|
||
|
||
int wai_image_avif_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
/**
|
||
* `quality = 0` ⇒ lossless. Otherwise butteraugli distance proxy
|
||
* (higher quality = smaller distance internally).
|
||
*
|
||
* # Safety
|
||
* `rgb` valid for `len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_image_jxl_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* A picture past the reader limits of SPEC §2 (wider or taller than
|
||
* [`IMAGE_MAX_SIDE`](crate::codecs::image::IMAGE_MAX_SIDE) or holding more than
|
||
* [`IMAGE_MAX_PIXELS`](crate::codecs::image::IMAGE_MAX_PIXELS) pixels) is refused with
|
||
* `WAI_ERR_CODEC` from the size it declares, before it decodes; the message begins
|
||
* `image_too_large`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_h` writable; `out_w` writable.
|
||
*/
|
||
|
||
int wai_image_jxl_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
/**
|
||
* # Safety
|
||
* `samples` valid for `n` `f32`s; `out` writable.
|
||
*/
|
||
|
||
int wai_audio_opus_encode(const float *samples,
|
||
uintptr_t n,
|
||
uint32_t sr,
|
||
int32_t bitrate_bps,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Output past the reader limit of SPEC §2,
|
||
* [`AUDIO_DECODED_MAX_SAMPLES`](crate::codecs::audio::AUDIO_DECODED_MAX_SAMPLES)
|
||
* samples, is refused with `WAI_ERR_CODEC`; the message begins
|
||
* `audio_decoded_too_long`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_sr` writable.
|
||
*/
|
||
|
||
int wai_audio_opus_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_sr);
|
||
|
||
/**
|
||
* # Safety
|
||
* `samples` valid for `n` `f32`s; `out` writable.
|
||
*/
|
||
|
||
int wai_audio_flac_encode(const float *samples,
|
||
uintptr_t n,
|
||
uint32_t sr,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Output past the reader limit of SPEC §2,
|
||
* [`AUDIO_DECODED_MAX_SAMPLES`](crate::codecs::audio::AUDIO_DECODED_MAX_SAMPLES)
|
||
* samples, is refused with `WAI_ERR_CODEC`; the message begins
|
||
* `audio_decoded_too_long`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_sr` writable.
|
||
*/
|
||
|
||
int wai_audio_flac_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_sr);
|
||
|
||
/**
|
||
* # Safety
|
||
* `data` valid for `len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_text_zstd_encode(const uint8_t *data,
|
||
uintptr_t len,
|
||
int32_t level,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode a `wai.text.zstd` payload within the reader limits of SPEC §2: at most
|
||
* [`TEXT_DECODED_MAX_LEN`](crate::codecs::text::TEXT_DECODED_MAX_LEN) bytes of output
|
||
* and [`TEXT_WINDOW_MAX_LEN`](crate::codecs::text::TEXT_WINDOW_MAX_LEN) bytes of
|
||
* window. A payload past either is refused with `WAI_ERR_CODEC`; the message begins
|
||
* `text_decoded_too_long` or `text_window_too_large`.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable.
|
||
*/
|
||
int wai_text_zstd_decode(const uint8_t *bytes, uintptr_t len, struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* # Safety
|
||
* `data` valid for `len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_text_xz_encode(const uint8_t *data,
|
||
uintptr_t len,
|
||
uint32_t level,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode a `wai.text.xz` payload within the same limits as
|
||
* [`wai_text_zstd_decode`], the window limit applying to the dictionary.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable.
|
||
*/
|
||
int wai_text_xz_decode(const uint8_t *bytes, uintptr_t len, struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Encode a sequence of `n` RGB frames as AV1.
|
||
*
|
||
* # Safety
|
||
* `rgb` valid for `len` bytes; `out` writable.
|
||
*/
|
||
|
||
int wai_video_av1_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t n,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint32_t fps_num,
|
||
uint32_t fps_den,
|
||
uint8_t lossless,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode an AV1 WAI payload to a packed RGB buffer `n*h*w*3` bytes.
|
||
*
|
||
* A payload past the reader limits of SPEC §2 (more than
|
||
* [`VIDEO_MAX_TEMPORAL_UNITS`](crate::codecs::video::VIDEO_MAX_TEMPORAL_UNITS)
|
||
* temporal units, or frames past the picture limits) is refused from its header;
|
||
* the message begins `video_too_large`. Since the buffer holds every frame, so is
|
||
* one whose frames would take more than
|
||
* [`AV1_DECODE_DEFAULT_MAX_LEN`](crate::codecs::video::AV1_DECODE_DEFAULT_MAX_LEN)
|
||
* bytes together (`video_decoded_too_large`), and one whose frames differ in size.
|
||
*
|
||
* # Safety
|
||
* `bytes` valid for `len` bytes; `out` writable; `out_n` writable; `out_h` writable; `out_w` writable; `out_fps_num` writable; `out_fps_den` writable.
|
||
*/
|
||
|
||
int wai_video_av1_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_n,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w,
|
||
uint32_t *out_fps_num,
|
||
uint32_t *out_fps_den);
|
||
|
||
/**
|
||
* Decode a `wai.neural.<audio>` envelope (encodec32 / dac / mimi /
|
||
* wavtokenizer / snac). Writes mono `f32` samples into `out_samples`; the
|
||
* caller reads them as `float*` of length `out_samples.len / 4`.
|
||
*
|
||
* # Safety
|
||
* `envelope` valid for `envelope_len` bytes. `model_path` NUL-terminated
|
||
* UTF-8 path to the decoder. `out_samples` writable `WaiBuffer*`.
|
||
* `out_sample_rate` writable `uint32_t*` (or null to skip).
|
||
*/
|
||
|
||
int wai_neural_decode_audio(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_samples,
|
||
uint32_t *out_sample_rate);
|
||
|
||
/**
|
||
* Decode a neural image envelope. Writes packed RGB (row-major, 3 bytes/pixel)
|
||
* into `out_rgb`; writes width/height into `*out_width` / `*out_height`.
|
||
*
|
||
* # Safety
|
||
* See `wai_neural_decode_audio`.
|
||
*/
|
||
|
||
int wai_neural_decode_image(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_rgb,
|
||
uint32_t *out_width,
|
||
uint32_t *out_height);
|
||
|
||
/**
|
||
* Decode a neural video envelope. Writes all frames concatenated (frame 0
|
||
* RGB, then frame 1 RGB, …) into `out_frames_concat`; the caller splits at
|
||
* `width*height*3` strides.
|
||
*
|
||
* # Safety
|
||
* See `wai_neural_decode_audio`.
|
||
*/
|
||
|
||
int wai_neural_decode_video(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_frames_concat,
|
||
uint32_t *out_n_frames,
|
||
uint32_t *out_width,
|
||
uint32_t *out_height,
|
||
uint32_t *out_fps_x_1000);
|
||
|
||
/**
|
||
* Decode a `WAI1` or `WAI2` envelope against the parameter sets in
|
||
* `registry_json`: a NUL-terminated JSON object mapping each capability to an
|
||
* array of paths. The first path is the registered artifact; the others are
|
||
* further sets a pin may resolve against (a set and its successor). Every pin is
|
||
* verified first (SPEC §3.1); a `WAI2` rendition is picked by SPEC §7.1. With
|
||
* `flags & WAI_DECODE_STRICT`, SPEC §7's replicate rule applies too. A capability
|
||
* whose output has no `wai_decoded_t` kind (integer video, PCM, splat attributes) is
|
||
* not advertised, whatever `registry_json` says: dispatch moves on past it before
|
||
* decoding, and when nothing else decodes the error names it.
|
||
*
|
||
* `*out` is written on every call with a non-null `out`, before anything else is
|
||
* read: on failure it holds `kind` 0 and an empty `data`, so the caller may free
|
||
* `out->data` whatever the status.
|
||
*
|
||
* # Safety
|
||
* `envelope` valid for `envelope_len` bytes; `registry_json` NUL-terminated;
|
||
* `out` a writable `WaiDecoded*`, which need not be initialised.
|
||
*/
|
||
|
||
int wai_neural_decode_ex(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *registry_json,
|
||
uint32_t flags,
|
||
struct wai_decoded_t *out);
|
||
|
||
#ifdef __cplusplus
|
||
} // extern "C"
|
||
#endif // __cplusplus
|
||
|
||
#endif /* WAI_H */
|