Skip to content

Releases: avala-ai/4dgs

fourdgs (Rust) 0.1.0

fourdgs (Rust) 0.1.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 29 Jul 06:15
a1754f9

What's changed

The first release of the Rust crate, and the first cut from a tag. It is the decoder and the
production encoder, and it is what the C++ and Swift packages bind to: the C ABI in
include/fourdgs.h is part of this release, not a side effect of it.

fourdgs-cli, which installs the 4dgs tool, is not released here. It is unpublished for a reason
recorded in its manifest.

Fixed and Changed below describe behaviour that changed against the pre-release code in this
repository, which people do vendor from git — not against 0.0.1, which held the name on crates.io
and contained nothing.

Added

  • Decoder: TLV container, streamed and indexed readers, both adaptive-precision rules, validity
    windows, whole-degree spherical harmonic bands, deflate by default with zstd behind a feature,
    and the audio, camera, metadata, attachment, statistics and summary-offset records.
  • include/fourdgs.h: a C ABI for decoding, and the surface the C++ and Swift packages bind to.
    Nothing unwinds across it, every fallible call returns a status, and null is safe to pass.
  • Conformance runners in rust/conformance, wired into the shared harness.
  • The production encoder: error-bounded quantization on the declared grids, the temporal chunk tree,
    independent chunks, an index, and deterministic output. It verifies its own claim before returning
    a file — every chunk is decoded back and every value checked against the bounds the Quantization
    record is about to declare, so a file whose bounds have not been measured never reaches a caller.
  • C ABI: the rest of the file. temporal_model, header attributes, metadata records, attachment
    names/media types/bytes, camera and keyframes, statistics, summary offsets, a tri-state
    summary CRC, a truncated flag, per-chunk load and per-chunk byte prediction, and _ex openers
    that force the sequential or indexed path. Strings read from file bytes cross as (pointer,
    length), never NUL-terminated, because the format's string may legally contain a NUL.
  • Structural fuzzing over seeded mutations, covering both read paths and the C ABI, with a counting
    allocator and a timer enforcing that no input causes an unbounded allocation or a hang. It found
    two allocation bugs and an integer overflow on its first run.
  • rust/encode-roundtrip.sh: the encoder's gate. Re-encodes every corpus variant and requires the
    Rust and Python decoders to agree on the result, because an encoder checked only against its own
    decoder proves nothing about the format.

Fixed

  • A file cut between a chunk and its spherical harmonic band records was refused as malformed
    instead of recovering the complete prefix. Bands are whole, so the short trailing chunks are
    dropped and everything that arrived intact is kept.
  • Asking for fewer spherical harmonic bands than were already resident answered from the cache,
    handing back a higher degree than requested and transferring nothing — which is exactly what a
    band-skipping byte budget measures.
  • The front-matter probe read 64 KiB, which on a small file was the whole thing. It is 8 KiB now:
    the records an indexed open must parse are a few hundred bytes, and everything else in the front
    matter is stepped over rather than read.

Changed

  • The streamed reader's retained summary run narrowed to Chunk Index, Statistics and Summary Offset,
    matching the new spec §4.5. Attachments are no longer retained: their size is unbounded, and
    admitting them would have made verifying a checksum cost whatever the payload weighed.

cargo add fourdgs@0.1.0 | crates.io | full changelog

fourdgs (Python) 0.1.0

Pre-release

Choose a tag to compare

@emal-avala emal-avala released this 29 Jul 01:31

What's changed

The first release of the Python reference implementation, and the first cut from a tag. It is what
the specification is checked against: where the two disagree, the conformance suite decides which
one is wrong.

Fixed and Changed below describe behaviour that changed against the pre-release code in this
repository, which people do vendor from git — not against 0.0.1, which held the name on PyPI and
contained nothing.

Added

  • The reader. Every top-level structure is a length-prefixed record with an opcode, so an
    unrecognized record is stepped over rather than fatal. Two read paths, neither an optimization of
    the other: read() walks a file front to back in bounded blocks and works on a pipe or a
    truncated file, and open_indexed() reads the index and then only the byte ranges an instant
    needs.
  • Gaussian state at a time t: per-gaussian birth, velocity, temporal extent and validity window,
    the two precision rules recomputed from the sigma bin, smallest-three rotations, the colour
    transform, and spherical harmonic bands merged as whole degrees. state_at() is where decoding
    ends — nothing here renders.
  • The writer, write() with WriteOptions. It optimizes for a file that is easy to reason about
    rather than for size or throughput, and verifies its own stated error bounds by decoding what it
    wrote.
  • WriteOptions.cutoff, so a file can declare a marginal threshold other than the default. It is
    not decoration: the cutoff sets the support constant the per-gaussian velocity grid is derived
    from, so encoder and decoder have to agree on it.
  • WriteOptions.record_trailers, which appends bytes to a record's content the way a later minor
    revision would add a field. Used by the conformance corpus to write a file that a reader must step
    over rather than stop at.
  • Audio, a camera trajectory, metadata and attachments as front-matter records. On the indexed path
    each costs exactly its own bytes to read, through read_camera, read_metadata and
    read_attachments; the streamed reader decodes spherical harmonic bands, verifies the Footer's
    summary CRC and collects Summary Offset records.
  • validate(), and fourdgs validate over it: structural validation where every finding names the
    record, the field and what was expected. This is what makes a third-party encoder possible —
    finding out why a file is wrong without reading this decoder.
  • convert_ply_sequence(), and fourdgs convert over it: a directory of per-frame gaussian splat
    .ply files becomes one continuous scene, each frame's gaussians taking that frame's slot as
    their validity window and velocities fitted across the frames a gaussian appears in.
  • fourdgs info and fourdgs decode, thin enough over the library that anything the CLI can do a
    caller can do. info reports what seeking costs: the bytes needed to display an instant.
  • Errors that name the problem — MalformedFile, TruncatedFile, UnsupportedCodec,
    UnsupportedVersion and BoundViolation, all under FourdgsError — so a file that is malformed
    is distinguishable from one that is merely newer.
  • Conformance runners under python/conformance/, which decode the generated corpus and print the
    canonical JSON the suite compares across SDKs.

Fixed

  • open_indexed raised ValueError — not a FourdgsError — on a footer whose summary_start
    points past the footer itself, so validate could not catch it and a malformed file crashed the
    tool meant to diagnose it. It is now a MalformedFile naming both offsets.
  • open_indexed could not open a file whose front matter held a record larger than its 64 KiB
    probe. An Audio record lives in the front matter, so any scene with a real soundtrack failed — on
    the seekable path, on the format's flagship case. The walk now steps over a record by arithmetic
    and fetches only what it wants.
  • A chunk's compression field was parsed and then ignored, so a conforming chunk-compressed file
    decoded to garbage instead of either working or failing. It is now honoured, and an unrecognized
    codec is refused by name.
  • The velocity precision grid used the default cutoff rather than the file's own, so any file
    declaring a different threshold decoded velocities the encoder did not write. state_at had the
    same assumption in its visibility test.
  • A file whose trailing magic is missing is now reported as truncated rather than as complete.

Changed

  • A window index outside the Window Table is refused rather than clamped. Clamping substituted
    one gaussian's lifetime for another's in a file that was already corrupt, turning a detectable
    fault into plausible wrong output. Files written by this encoder are unaffected; a reader that
    relied on the old behaviour will now see MalformedFile.
  • A file with no Window Table, or an empty one, reads as a single (0, 0) window. That was already
    the behaviour; it is now the documented one.

pip install fourdgs==0.1.0 | PyPI | full changelog