# MetaCrate Skia adapter This crate implements the pinned `SkiaTextureCodec` behavior at a bounded, project-owned image boundary. The core `libremetaverse-imaging` crate never exposes a `skia-safe` type and never discovers or links Skia. ## Features and formats The default feature set enables the pure-Rust `rust-skia` backend and has no native Google Skia dependency. `SkiaTextureCodec::decode` and `RustSkiaTextureCodec::decode` return a typed `InvalidOperation` error when their respective feature is disabled, while conversion from the checked project-owned `backend::SKBitmap` remains available for tests and callers that already own decoded pixels. For a fully Rust implementation, enable: ```sh cargo test -p libremetaverse-imaging-skia ``` `rust-skia` pins [`skia-rs-codec` 0.3.0](https://github.com/rust-skia/skia-rs) with default features disabled and only its pure-Rust PNG, JPEG, and GIF codecs selected. Its `webp` feature is deliberately disabled because that feature selects `libwebp-sys`; WebP is instead decoded by the separately pinned, safe-Rust [`image-webp` 0.2.4](https://github.com/image-rs/image-webp) crate. BMP, ICO, and WBMP are built into `skia-rs-codec`. The resulting normal/build graph has no codec `-sys` crate, C/C++ compilation, CMake, system-library lookup, or binary download. The locked transitive codec lines are `png` 0.17.16, `jpeg-decoder` 0.3.2, `jpeg-encoder` 0.6.1 (the upstream JPEG feature couples decode and encode), and `gif` 0.13.3. `skia-rs-codec` also brings its ordinary Rust core, paint, and path crates; their build helpers only select Rust cfgs and compile no native code. A source audit of the locked `skia-rs-*` crates found no unsafe blocks, and `image-webp` declares `forbid(unsafe_code)`. MetaCrate itself continues to compile with workspace `unsafe_code = "forbid"`. `RustSkiaTextureCodec` implements the same `ITextureCodec` abstraction and decodes BMP, GIF, ICO, baseline/progressive JPEG, interlaced PNG, WBMP, and lossless/lossy/animated WebP. GIF and WebP return frame one composited on the logical canvas; ICO chooses its largest valid entry. Both Skia features may be enabled together, and each codec remains independently constructible. The graph builds on the workspace Rust 1.96 MSRV; both selected direct codecs declare older compatible Rust floors. Enable native decoding with: ```sh cargo test -p libremetaverse-imaging-skia --features skia ``` The native `skia` feature decodes the CPU codec formats supported by the pinned rust-skia release: BMP, GIF, ICO, JPEG, PNG, WBMP, and WebP. Input is buffered to at most 64 MiB. Dimensions are rejected before native pixel allocation when they exceed the core 16,777,216-pixel limit, and decoded storage uses checked strides and owned Rust buffers. The mapped C# adapter exposes decoding and `SKBitmap`-to-`ManagedImage` conversion only; it has no encoding or resize method. Encoding selection stays with the format-specific imaging APIs, and callers use `ManagedImage`'s checked resize methods after decoding. Premultiplied pixels are converted to straight alpha at this boundary. RGB565, BGRA8888, RGBA8888, RGBA/BGRA1010102, Gray8, Alpha8, row padding, and the reference byte-width fallback retain the pinned C# channel and rounding rules. Both paths accept any `ReadWrite + Send` stream and stop buffering after 64 MiB plus one sentinel byte. The pure-Rust path probes encoded dimensions before codec pixel allocation and enforces the shared 16,777,216-pixel ceiling; WebP also receives an explicit decoder memory limit. Checked dimensions, strides, buffer sizes, and fallible project-owned allocations turn malformed, truncated, oversized, and allocation failures into typed errors. Decoded rows have a top-left origin and premultiplied native samples are normalized to straight alpha at the shared `ManagedImage` boundary. The pure-Rust graph has identical code on Linux, Windows, macOS, and WASM and does not call platform APIs. Checked static fixtures cover top-down/bottom-up BMP, palette/offset GIF, largest-entry ICO, baseline/progressive JPEG, interlaced palette PNG, multibyte WBMP, lossless-alpha/lossy WebP, malformed and oversized inputs, and concurrent decode/drop. Gitea runs the `rust-skia` suite in a dedicated `ubuntu-latest` job that installs no native codec prerequisites. `image-webp` 0.2's animated-canvas blend fast path rounds fully opaque nonzero samples one low; the bounded adapter corrects that single upstream edge so the checked first-frame planes remain byte-identical to native Skia. ## Binary cache and source builds `skia-safe` 0.99.0 downloads an official prebuilt Skia archive when the target and Cargo feature set match a published archive. MetaCrate deliberately selects the published WebP-capable feature sets: - Linux and Windows: JPEG, PDF, SVG, text layout, Vulkan, and WebP; - macOS: JPEG, PDF, SVG, text layout, and WebP. Vulkan is selected on Linux and Windows only to match the published CPU/WebP archive; this adapter does not create a GPU context or call a platform graphics API. The same feature is therefore usable on macOS, Linux, and Windows without leaking platform-specific behavior. Build prerequisites for the supported desktop targets are: - Linux: a C++ linker/runtime, `curl`, `pkg-config`, FreeType, and Fontconfig; - macOS: Xcode command-line tools and `curl`; - Windows MSVC: the Rust MSVC toolchain, Visual Studio C++ build tools, and `curl`. The build script downloads cache archives from the `rust-skia/skia-binaries` GitHub releases. Pin or mirror `SKIA_BINARIES_URL` in offline/reproducible build environments. `FORCE_SKIA_BINARIES_DOWNLOAD=1` makes a missing archive fail instead of compiling Skia. If no archive matches and that variable is absent, rust-skia falls back to a source build, which additionally requires Python 3, Ninja, and an LLVM/Clang toolchain. `FORCE_SKIA_BUILD=1` selects that path explicitly. ## Licensing and redistribution `skia-safe` and rust-skia's bindings are MIT licensed; the linked Skia library is BSD-3-Clause licensed. Official binary-cache archives contain compiled Skia. Products that redistribute the resulting native artifacts must preserve the applicable MIT and BSD notices and audit the exact archive they ship. `skia-rs-codec` is MIT OR Apache-2.0 and `image-webp` is MIT OR Apache-2.0. They are ordinary Rust source dependencies recorded in `Cargo.lock`; generated dependency notices and the distribution manifest bind their crates.io checksums and license texts for source and binary redistribution.