ExCodecs.Spatial.Accel (ex_codecs v0.2.3)

Copy Markdown View Source

Elixir facade over the spatial Rust NIFs (EXCP, GSPL, binary PLY).

Callers fall back to pure Elixir when available?/0 is false or a call returns :nif_not_loaded. This module defines the cross-language ABI: row tuple shapes must match native/ex_codecs_native/src/spatial.rs.

Chunk semantics

Unpack NIFs return {:ok, {rows, next_offset}}. Pass at most chunk_size/0 (4096) rows per call and advance offset from next_offset. Whole-payload decode paths loop the same way. A partial final record is silently skipped (the unpack breaks); callers can detect truncation by comparing next_offset to the expected body size.

Data coercion

Out-of-range color bytes are clamped to [0, 255] (not wrapped). Missing SH coefficients are zero-filled to the declared sh_rest length. Both coercions are lossy: a round-trip through encode may not reproduce the original if the input contained out-of-range values.

Row formats

  • EXCP point row: {x, y, z, color, normal} where color / normal are nil or tuples matching header flags
  • GSPL gaussian row: {{x, y, z}, {r, g, b}, opacity, {sx, sy, sz}, {rw, rx, ry, rz}, sh_list}
  • PLY binary: flat numeric lists per vertex, typed by ply_type_tag/1

mmap

Do not truncate or replace a file while an mmap resource from mmap_open/1 is live — concurrent truncation can SIGBUS and kill the BEAM. Prefer accel: false / plain IO for untrusted paths.

This module is intentional infrastructure; HexDocs may still group it under internals depending on ExDoc filters.

Summary

Functions

append_file(path, data)

available?()

@spec available?() :: boolean()

Returns whether spatial NIFs are loaded (cached for the VM lifetime).

chunk_size()

@spec chunk_size() :: pos_integer()

Preferred max row count per unpack NIF call.

excp_pack(points, flags)

excp_unpack(data, flags, offset \\ 0, max_count \\ 4096)

excp_unpack_mmap(resource, flags, offset \\ 0, max_count \\ 4096)

gaussian_to_row(g, sh_rest)

gspl_pack(gaussians, sh_rest)

gspl_unpack(data, sh_rest, offset \\ 0, max_count \\ 4096)

gspl_unpack_mmap(resource, sh_rest, offset \\ 0, max_count \\ 4096)

mmap_len(resource)

mmap_open(path)

ply_binary_unpack(data, types, endian, offset \\ 0, max_count \\ 4096)

ply_binary_unpack_mmap(resource, types, endian, offset \\ 0, max_count \\ 4096)

ply_type_tag(type)

point_to_row(p)

row_to_gaussian(arg, sh_rest)

row_to_point(arg)