Imaging extension: add optional pure-Rust Skia backend #112
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Objective
Add a complete optional pure-Rust Skia-compatible image backend behind a Cargo feature named
rust-skia. Useskia-rs-codecfrom the current compatible 0.3 release line as the primary codec implementation. The backend must implement the same boundedITextureCodecbehavior and the same C#LibreMetaverse.Imaging.Skia.SkiaTextureCodecdecode semantics as the existing native rust-skia/Google Skia backend; it must not be a stub, a subprocess, or a wrapper that silently links C/C++ libraries.The existing C# source in
LibreMetaverse.Imaging.Skia/SkiaTextureCodec.csand the translated/golden Rust tests are the behavioral reference. Treat the C# as correct, but do not run or depend on .NET code.Current architecture
crates/libremetaverse-imaging-skiahas no default features.skiafeature enables optionalskia-safe0.99.0.skia-safeis a safe Rust API overskia-bindingsand native Google Skia C++ binaries; retain this backend unchanged.crates/libremetaverse-imaging-skia/src/skia_codec.rsowns bounded stream buffering, nativeskia_safe::codec::Codecadaptation, color/alpha mapping, premultiplied-alpha normalization, and conversion intoManagedImage.SkiaTextureCodecis the mapped public C# type and currently denotes the existing native Google Skia backend.skia-rs-codec0.3.0 declares Rust 1.85 and is compatible with that floor; lock and audit the exact selected version.Dependency caveat that must be handled
skia-rs-codec0.3.0 calls itself pure Rust, but its defaultwebpfeature depends onwebp0.3, which in turn linkslibwebp-sys. Therefore:skia-rs-codecwithdefault-features = falseand enable only audited pure-Rust codec features.skia-rs-codec/webpwhile it transitively useslibwebp-sys.image-webpfrom its current compatible 0.2 release line, or contribute/upgrade to an upstreamskia-rs-codecrelease that has removed the native dependency before completing this issue.rust-skiadependency graph must contain no-syscodec crate, CMake/cc-driven native codec, system package lookup, downloaded binary, or C/C++ source build.Feature and API design
skia-rs-codecand any required audited pure-Rust WebP dependency tolibremetaverse-imaging-skia.rust-skia = [...]to that crate. The feature must not enableskia,skia-safe,skia-bindings, Google Skia, or native libwebp.skiafeature andSkiaTextureCodecbehavior without a breaking rename or backend substitution.RustSkiaTextureCodec(or a comparably clear public name), implementingITextureCodecand the same bounded decode contract.ManagedImageconversion into backend-neutral code. Do not fork two subtly different copies of the compatibility rules.skiaandrust-skiatogether must compile and expose both backends.--all-featuresmust remain valid. Do not use feature ordering, mutually exclusive compile errors, or a conditional alias that silently changes whatSkiaTextureCodecmeans.Required decode behavior
ReadWrite + Sendstream.SkiaTextureCodecdimensions, first-frame behavior for animated inputs, logical canvas handling, component ordering, and alpha presence.ManagedImagemust be straight/unpremultiplied.Errorvariants for empty, malformed, truncated, unsupported, or oversized data. Never panic on decoder-controlled input.skia-rs-codeclacks a behavior needed for parity, implement a bounded adapter or contribute the missing behavior upstream. Do not accept and ignore a compatibility requirement.Resource safety
DEFAULT_MAX_ENCODED_BYTES + 1and reject oversized input before passing it to a decoder.DEFAULT_MAX_PIXELS, row-byte bounds, output length, component count, and every integer conversion before allocation or indexing.unsafe_code = "forbid"policy. Audit dependency unsafe code and fuzz-sensitive parsers rather than copying unchecked decoder logic into this repository.ubuntu-latestonly because this Gitea installation has no Windows or macOS runners.Tests
Refactor the codec contract tests so the same fixture/assertion table runs independently against native
SkiaTextureCodecandRustSkiaTextureCodec, with backend-specific tests only where unavoidable. Add audited deterministic fixtures for at least:For lossless inputs, require identical
ManagedImagedimensions, channel flags, and planes across the native and Rust backends. For lossy inputs, use explicit per-channel tolerances and invariant checks rather than byte-identical compressed or decoded output. Fixtures must be checked in with provenance and must not be generated at test time by C#, native Skia tools, ImageMagick, network services, or another subprocess.Add concurrent decode/drop tests proving the adapter is stateless, deterministic, bounded, and does not retain streams or decoded buffers after return.
Validation gates
The implementation is complete only when all of the following pass:
Also record and verify:
The pure-Rust tree must contain neither
skia-safe/skia-bindingsnorlibwebp-sysor any other native graphics/codec binding. Add an Ubuntu-only Gitea job forrust-skiathat does not install Ninja, Clang, CMake, pkg-config, or native image libraries. Keep the existing native Skia job for theskiafeature.Documentation and audit
rust-skiabuild/test commands and explain how it differs from the existing nativeskiafeature.crates/libremetaverse-imaging-skia/README.md,docs/imaging-meshing.md, and crate documentation with backend selection, supported formats, feature coexistence, MSRV, limits, and deployment implications.skia-rs-codec, the pure-Rust WebP implementation, and their codec dependencies.Definition of done
A user can build and test
libremetaverse-imaging-skiawith--no-default-features --features rust-skia, decode every format in the existing Skia adapter contract entirely in Rust, and obtain C#-compatible boundedManagedImageresults without downloading or linking Google Skia, libwebp, or any other native library. Existing default and nativeskiabuilds remain unchanged, the two backends coexist, and every gate above passes in isolation.Implemented and verified the optional pure-Rust Skia-compatible backend.
Implementation:
rust-skiafeature and publicRustSkiaTextureCodec, while preserving the nativeskia/SkiaTextureCodecAPI and allowing both features together.skia-safe,skia-bindings,libwebp-sys, and other native codec bindings.Commits:
8c18b2afeature implementation and testse0e76be,2ec65d0refreshed generated audit/consumer evidence6f67568deterministic auto-reset regression1ea44e5capability race and CI audit fixese16ad04audited license/dependency policyVerification:
rust-skia (Rust only)andrequired: https://git.rfc1437.de/hugo/MetaCrate/actions/runs/409