OxiGDAL 0.1.7 Release
[0.1.7] - 2026-07-20
Added
- oxigdal-cloud-enhanced: real Azure IMDS managed-identity tokens via
azure_identity::ManagedIdentityCredential, replacing the placeholder-token stub; real GCP metadata-server access/identity tokens plus IAM Credentials API impersonation, withGCE_METADATA_HOSToverridable for mock-server tests - oxigdal-cloud: multicloud
build_backend()factory (S3/GCS/AzureBlob/Http, feature-gated) with a backend cache;get/put/delete/exists_in_providerare now functional against real backends - oxigdal-drivers-advanced: JPEG2000 decode now delegates to
oxigdal-jpeg2000for real decode with full header parsing, replacing the gray-placeholder-pixel stub - oxigdal-services: WFS-T Memory/File transactions fully implemented — insert/update/delete/replace with per-path write serialization
- oxigdal-services: WCS File/Url/Memory coverages now do real GeoTIFF read/write via
oxigdal-geotiff;encode_as_geotiffproduces real GeoTIFF bytes (was stub output) - oxigdal-ml-foundation:
onnx_export.rs— pure-Rust ONNX protobuf encoder (ir_version 8, opset 13), round-trip-validated againstoxionnx - oxigdal-ml-foundation: augmentation noise generation now uses real Gaussian sampling (
scirs2_coreseeded RNG) instead of a synthetic pattern - oxigdal-ml:
OnnxModel::infer_multiband— real multi-channel[1, C, H, W]NCHW tensor inference over aMultiBandBuffer(band-sequential channel order, unpacked back into one output band per channel); previouslyinferaccepted only a single-bandRasterBuffer - oxigdal-workflow: Temporal/Prefect
import_workflowround-trips exporter-generated definitions via metadata headers for lossless ID recovery; export now emits real activity bodies - oxigdal-etl:
calculate_ndvimap transform implemented, with a zero-denominator guard so masked/no-data pixels emit0.0rather thanNaN - oxigdal-cli:
info/statsimplemented for FlatGeobuf, GeoParquet, Zarr, GeoPackage, JPEG2000, COPC, PMTiles, MBTiles (previously "not yet implemented") - oxigdal-algorithms: Lanczos resampling
WrapandMirroredge modes implemented (rem_euclid/ reflect-101) - oxigdal-geojson-stream: TopoJSON writer now emits real arcs for LineString/MultiLineString — open-chain topology with endpoint junctions, no-rotation splitting, and shared-arc dedup via negative reversed indices (was an empty
"arcs": []stub) - oxigdal-gpu: subgroup/warp operations emit native WGSL subgroup builtins with a workgroup-shared-memory emulation fallback; Metal filter/reduction/nearest-neighbor shader generators implemented; ballot/vote/
SimdGroupOperationsupgraded; new execute-and-compare GPU tests (verified on Metal) - oxigdal-bench: raster/io scenarios now do real work (tile reads,
MmapDataSource) instead of synthetic placeholders - oxigdal-wasm:
WasmCogViewer.openBytes— drag-drop local GeoTIFF with full codec support including LZW/Zstd viaCogReader<MemorySource>;readTileElevation(SampleFormat tag 339 parsing);WasmTerrain— hillshade/multidirectional hillshade/slope/aspect/color-relief-shaded (Horn method,ImageDataoutput);WasmProjection+wgs84ToWebMercator/webMercatorToWgs84shims - GeoLab demo (
demo/cog-viewer): rebranded OxiGDAL GeoLab — drag-drop loading, terrain-analysis panel, honest byte counters, all CDN dependencies vendored locally; staged to cooljapan.tech/geolab/ (deploy manual) - oxigdal-security: new
attestationmodule — tamper-evident session ledger: domain-separated blake3 hash chain (SessionLog), Merkle root + per-entry inclusion proofs, Ed25519 session seal (SessionSigner::seal), andverify_attestation()re-verifying chain/root/signature from the attestation JSON alone; golden-fixture and tamper-detection tests; native skeptic's verifier exampleverify_attestation.rs; compiles for wasm32 under--no-default-features --features attestation - oxigdal-wasm:
sentinelmodule (GeoSentinel) —WasmStacClientEarth Search STAC scene-pair search with client-side cloud/nodata/grid filtering; self-contained UTM↔WGS84 (Krüger series, EPSG 326xx/327xx);GeoSentinelchange-detection pipeline: windowed COG reads → BOA offset → NDVI drop → fixed/Otsu threshold → polygonization → Karney geodesic hectares → GeoJSON, plus true-color and diff-heatmap RGBA overlays - oxigdal-wasm:
vaultmodule (GeoVault) —WasmVaultSessionblake3 hash-chained operation log sealed with Ed25519 into attestation JSON,verifyAttestation, blake3fileDigestHexfor dropped files - oxigdal-wasm:
anomalymodule — self-contained Z-score / IQR / modified-Z-score / percentile / σ-bounds detectors (parity-ported fromoxigdal-analytics/oxigdal-qc) with mask,ImageData, and summary-JSON outputs - oxigdal-wasm: COG reader overview-level reads — full per-overview IFD parsing (each level gets its own tile directory, predictor, and sample layout),
read_tile_level, andread_window_u16/read_window_rgb8window assembly; PREDICTOR=2 horizontal-differencing undo (TIFF tag 317) for u8/u16 samples on all tile and window paths - oxigdal-geoparquet: new
plan/pushdownAPIs —plan_pushdown()computes row-group bbox + attribute-statistics pruning and exact column-chunk byte ranges from metadata alone (zero I/O);execute_pushdown()runs pushdown over anyparquet::ChunkReader(GeoParquetReader::read_pushdownis now a thin wrapper) - oxigdal-geoparquet: bbox-column detection now honors GeoParquet 1.1
covering.bboxpaths from thegeometadata (authoritative) with a plainbboxstruct-root fallback — VIDA-style files (5.9 GB / 9,533 row groups) now prune correctly - oxigdal-geoparquet:
AttributeFilter::Cmpscalar comparisons (>,>=,<,<=,<>) with Int64/Float64 literal↔column coercion (a bare integer compares correctly against a Float64 column and a whole-valued decimal against an integer column); multiple filters compose as a conjunction viawith_attribute_filters - oxigdal-wasm-geoparquet (new crate): browser GeoParquet range-request client — remote footer decode,
SparseChunkReaderover prefetched byte ranges, 64 KiB-gap range coalescing, SQLWHERE-fragment → predicate lowering (sqlparser, typed rejections naming unsupported constructs),RecordBatch→ GeoJSON conversion, andRemoteGeoParquetopen/plan/query with byte and request accounting (npm:@cooljapan/oxigdal-geoparquet) - GeoSentinel demo (
demo/geosentinel): in-browser Sentinel-2 change detection — STAC pair search, streamed COG windows, NDVI-drop polygons with geodesic hectares, GeoJSON export, before/after crossfade; staged to cooljapan.tech/geosentinel/ (deploy manual) - GeoVault demo (
demo/geovault): sovereign clean-room workstation — CSP-enforced zero egress, live session ledger, seal → attestation download, independentverify.htmlverifier; synthetic Site K-7 DEM via newoxigdal-geotiffexamplegeovault_scene.rs; staged to cooljapan.tech/geovault/ (deploy manual) - GeoParquet Live demo (
demo/geoparquet): bounding-box + SQL attribute queries against the 5.9 GB VIDA GeoParquet via predicate pushdown over HTTP ranges — row-group strip visualization, plan-cost preview before any fetch, Cache API footer caching, offline sample + newoxigdal-geoparquetexamplegenerate_sample.rs; staged to cooljapan.tech/geoparquet/ (deploy manual) - oxigdal-server: new example
render_hero.rs(DEM → combined hillshade → colormap → PNG) - docs.rs metadata added to all 64 remaining publishable crates (21 curated for Pure-Rust-only docs builds)
- New
CONTRIBUTING.mdandCODE_OF_CONDUCT.md
Changed
- oxigdal-cloud-enhanced:
reqwestmade optional, gated behind thegcpfeature - oxigdal-ml-foundation: weights save/load moved to
oxicode(COOLJAPAN no-bincode policy) - oxigdal-services: Database transactions/feature-sources/SQL count moved behind new non-default
postgisfeature (oxigdal-postgispool,ST_GeomFromGeoJSON/ST_AsGeoJSON); WCSUrlcoverage fetch moved behind new non-defaultremotefeature - oxigdal-drivers-advanced:
jpeg2000feature is now dependency-gated (pulls inoxigdal-jpeg2000only when enabled) - oxigdal-security: dependencies split behind new
enterprise/tls/attestationfeatures (default enables all three) — the heavyweight server-side surface (tokio, dashmap, petgraph, scirs2-core, oxiarc-zstd, regex, parking_lot, uuid, chrono, crypto stack) is now optional underenterprise;tlsimpliesenterprise;attestationpulls onlyblake3+ed25519-dalek, keeping the wasm32 surface lean - GeoLab demo: shared
@cooljapan/oxigdalWASM package rebuilt (pkg refresh) — GeoLab, GeoSentinel, and GeoVault all serve the same refreshed package - Examples/benches reorganized: 31 orphaned top-level examples wired into
oxigdal-examples(API rot fixed, 5 duplicates pruned); 11 benches wired intooxigdal-bench - README: stats refreshed, doc links updated, GeoLab hero image made clickable, new
## Demosection with native-render gallery (docs/media/); section grown to## Demoswith hero/GIF/gallery/honest-notes blocks for GeoSentinel, GeoVault, and GeoParquet Live - Dependencies bumped to latest per the Latest Crates Policy:
oxiproj/oxiproj-core0.1.1 → 0.1.2,oxisql-core/oxisql-sqlite-compat0.3.2 → 0.4.0,oxinetcdf0.1.4 → 0.2.0,oxih50.1.4 → 0.2.0 — version-onlyCargo.tomlchanges; theoxih5/oxinetcdfjump to 0.2.0 was verified source-compatible with theoxigdal-drivers/hdf5/oxigdal-netcdfdriver code (no driver-side changes required)
Fixed (production-hardening campaign, 2026-07)
Parallel multi-lane defect sweep across the workspace: 233 verified defects fixed across
69 crates (correctness, unwrap-elimination, clippy, doc/README accuracy). Headline items:
Format drivers
- oxigdal-geotiff: floating-point predictor (TIFF
Predictor=3) decode and encode now
actually implemented — was previously a silent no-op that passed float32/float64 tile data
through unmodified, corrupting round-trips of predictor-encoded float COGs - oxigdal-jpeg2000: MQ arithmetic decoder
INITDECprocedure brought into ITU-T T.800
Annex C spec conformance - oxigdal-drivers/gml:
srsDimensionattribute now parsed, so 3D coordinate geometries
are no longer silently treated as 2D - oxigdal-drivers-advanced (VRT):
FirstValidpixel-function compositing fixed for
multi-byte sample types (u16/f32/f64 — was only correct for single-byte u8 samples);
BandMathpixel function now substitutesB10and higher band variables (previously only
B1–B9were recognized, silently dropping bands past 9 from expressions) - oxigdal-drivers/hdf5 and oxigdal-netcdf: both drivers re-backed by the real
Pure-Rustoxih5 0.1.4/oxinetcdf 0.1.4crates (crates.io, no libhdf5/libnetcdf FFI).
oxigdal-drivers/hdf5previously read a customOXIGDAL_HDF5_METADATA_V1JSON sidecar
and returned zeros for real.h5files; it now reads and writes genuine HDF5 viaoxih5.
oxigdal-netcdfnow reads genuine NetCDF-4/CF files viaoxinetcdf. Public API is
unchanged (Hdf5Reader::open,Attribute/AttributeValue/Datatype/Hdf5Version/
Hdf5Writer,NetCdfReader::open); 730 tests passing across the 4 affected crates,
clippy clean. Honest limitations carried forward:oxih50.1.4 fully reads
v0-superblock.h5files, while v2/v3-superblock files open but currently yield an empty
tree (best-effort, never faked); the writer produces contiguous real HDF5 (chunk/
compression hints are dropped, values are correct); the NetCDF reader surfaces the root
group, andscale_factor/add_offset/_FillValueare exposed as attributes but not
auto-applied
Algorithms
- oxigdal-algorithms: the raster/DSL calculator's algebraic optimizer no longer folds
x * 0/0 * xto a constant0.0— sinceNaN * 0.0 == NaNandInf * 0.0 == NaN,
the previous simplification silently discarded NoData/Inf semantics in NoData-masked
raster expressions; covered by a new NaN-semantics regression test - oxigdal-algorithms: Weiler-Atherton polygon clipping's concave-region fallback path no
longer silently returns a geometrically wrong (angularly-sorted) shape — the mismatch is
now surfaced as an explicit condition rather than masked as a plausible-looking result;
full boundary-walk reconstruction for concave fallbacks remains future work (see TODO.md)
Security
- oxigdal-security: RBAC
resource_patternmatching is now actually consulted by the
authorization check — was previously parsed and stored but never read, a
privilege-widening bug that let any pattern-scoped permission match every resource - oxigdal-gateway: TOTP verification switched to a constant-time comparison and gained a
±1 time-step (30s) clock-skew tolerance window per RFC 6238 §5.2; backup-code and
SMS-challenge comparisons are now constant-time as well
Cloud & infra
- oxigdal-server:
server.tomlis now actually loaded viaOXIGDAL_CONFIGin
Docker/Kubernetes deployments — was previously parsed and then discarded, silently
running on built-in defaults regardless of the mounted config file - oxigdal-stac: implicit
reqwestfeature pull replaced with an explicitasync
feature (withreqwestkept as a backwards-compatible alias) — the HTTP client and its
aws-lc-systransitive dependency are no longer pulled in for consumers who never use the
async surface - oxigdal-streaming: Kafka/Kinesis connector commit-strategy and consumer-lease
correctness fixes - oxigdal-query:
GROUP BYexecution implemented in the SQL executor (was previously a
no-op that ignored the clause)
Bindings
- oxigdal (umbrella):
DatasetWriter::finalize()now writes a real format, or returns a
typed error, instead of emitting a fakeOXIG-prefixed placeholder blob on unsupported
paths
no_std & platform
- oxigdal-core: now compiles under
--no-default-features --features alloc(no_std +
alloc, nostd) — the build previously failed under this combination, blocking
oxigdal-embedded/oxigdal-noallocno_std consumers
Fixed
- oxigdal-etl:
transform_crsnow implemented viaoxigdal_proj::transform_epsg, offloaded totokio::task::spawn_blocking— previously panicked with "Cannot start a runtime from within a runtime" when invoked inside any Tokio runtime, becausetransform_epsgopens the bundled PROJ database and builds its own current-thread runtime internally; this is a real bug fix, not a hardening change - oxigdal-etl:
calculate_bboxfixed — was unconditionally returning[0, 0, 0, 0] - oxigdal-ml-foundation: unavailable
scirs2input-gradient paths now return honest typed errors instead of silently returning zero gradients - oxigdal-gpkg: tile matrix set
srs_idnow writes the real EPSG:4326 SRS encoding via newint2_st()helper (was a hardcoded placeholder value of4) - oxigdal-cli:
mergeplaceholder test replaced with a real assertion - oxigdal-wasm: COG IFD parser —
BitsPerSample/SampleFormatentries carrying one SHORT per sample (count > 1, e.g. RGB TCI COGs) were read as inline scalars, yielding a garbage bit depth from the offset word and silently disabling predictor undo for multi-band tiles; arrays now go through offset-following array reads (first entry authoritative) - oxigdal-drivers/flatgeobuf: reader and writer now produce and parse the real FlatBuffers wire format — size-prefixed
Header/Featuretables per the official FlatGeobuf schema, written viaflatbuffers::FlatBufferBuilderand read back through a new bounds-checked vtable walker (fbsmodule) — instead of an ad-hoc custom binary layout; files are now interoperable with GDAL and other FlatGeobuf tooling. Newtests/real_format.rsindependently walks the on-disk bytes to confirm they are genuine FlatBuffers, not just round-trippable against this crate's own reader - oxigdal-geotiff: LERC decode (TIFF Compression tag 34887) now implements the real Esri/GDAL LERC2 bit-stuffed block format — header parsing, run-length-encoded validity mask,
BitStuffer2variable-bit-width unpacking, and exact dequantization — via a newlerc_codec::lerc2decoder; previously the codec only round-tripped its own raw-value payload and returned an explicit error on genuine GDAL/Esri-produced LERC streams. LERC encoding to the interoperable bit-stuffed format remains explicitly unimplemented (typed error, not a fabricated blob) - oxigdal-jpeg2000: Tier-2 packet-header parsing (new
tier2::layout/tier2::packet/tier2::tilemodules) now drives code-block decoding from the real per-(resolution, subband, code-block) precinct geometry and COD progression order, replacing a naive even-division byte split across code-blocks that did not reflect the actual packet structure of real JPEG2000 codestreams. Supports LRCP/RLCP progression, single quality layer, maximum-size precincts, and the reversible 5/3 wavelet; unsupported progression orders or multi-layer streams now return a typedUnsupportedFeatureerror instead of mis-decoding silently - oxigdal-drivers/hdf5: the ScaleOffset (
H5Z_SCALEOFFSET, id 6) and N-Bit (H5Z_NBIT, id 5) filters now implement libhdf5's actual on-diskcd_values/per-chunk layouts (matchingH5Zscaleoffset.c/H5Znbit.c) instead of an invented header format, so chunks produced by h5py/netcdf-c decode correctly and chunks written here are byte-compatible with libhdf5; a newfilters::pipeline_messageparser decodes the real Object Header Filter Pipeline message (both v1 and v2 on-disk layouts) that supplies each filter's parameters - oxigdal-embedded: the
powermodule now makes explicit thatPowerManagerperforms no hardware power/clock transitions unless a board-supportPowerControlleris installed (new trait extension point) — CPU-frequency scaling and clock/power gating are SoC-vendor-specific and were previously implied rather than actually performed;request_mode_strictadded for callers where a silent no-op would be a correctness bug - oxigdal-algorithms: both raster-algebra expression front-ends (the Pest-based
dslparser and the hand-written raster calculator parser) are recursive descent and had no bound on input nesting depth — a deeply nested expression such as((((...))))or a long-----xunary chain aborted the whole process with a stack overflow (SIGABRT), an unrecoverable crash reachable from untrusted expression text. Both now enforce a measuredMAX_EXPRESSION_DEPTH(64) before recursing, returning the typedAlgorithmError::NestingTooDeepinstead of crashing; wired through tooxigdal-node's error mapping as well - Test fixtures: two
oxigdal-cliintegration tests silently depended on demo fixtures excluded by.gitignore(demo/cog-viewer/*.zarr,*.fgb), so they only passed on machines where a developer had manually regenerated the fixture locally and failed deterministically on a clean checkout (previously misdiagnosed as a Linux-only flake).test_read_zarr_info_demo_fixtureis fixed by committing the actualiron-belt.zarrfixture;test_read_flatgeobuf_info_demo_fixtureis fixed by falling back to an equivalent in-process synthesized FlatGeobuf fixture when the demo file is absent, keeping the test self-contained either way - README: quickstart example now compiles as written (
crs()returnsOption) - Hygiene: removed a stray rustc-ICE dump, auto-fix-generated logs/backups, and 3 stray
.bakfiles from cratesrc/trees;.gitignorehardened;.cargo/config.tomlstalerusqlite/proj-sysentries removed;pypi-publish.ymlstaleopenssl-develstep removed;pyproject.tomlandpackage.jsonsynced to 0.1.7
Full Changelog: v0.1.6...v0.1.7