libxtm
libxtm is a C++ library and command-line utility for compression, encoding, decoding, and analysis of terrain/elevation data. It provides a specialized .xtm format designed for efficient storage and random-access retrieval of geospatial terrain data.
Features
- Specialized Terrain Compression: predictive coding tailored for terrain data, with optional wavelet coding.
- Predictors: six deterministic models — Left, Gradient, JPEG-LS, GAP, Polynomial, and Least Squares — chosen per block by a cost estimator.
- Quadtree Partitioning: 512×512 → 64×64 hierarchical partitioning driven by a rate-cost split rule.
- Split-Precision Coding: sub-meter scales encode meter and precision planes independently.
- Geospatial Support: GDAL-based I/O with full geotransform and WKT projection preservation.
- Region of Interest (ROI) Decoding: decode only a bounding region from the
.xtmfile without uncompressing the dataset. - Comprehensive Analyzer: terrain statistics, predictor performance, and compression diagnostics via
xtm analyze.
Architecture
apps/xtm/CLI — encode, decode, analyze, info, verifyinclude/public APIsrc/terrainquantization, NoData inpaintingpartitionquadtree 512→64 partitioning, block viewspredictorpredictor models (Left, Gradient, JpegLs, Gap, Polynomial, LeastSquares)analyzerper-block predictor selection + statisticstransformCDF 5/3 integer waveletcodingarithmetic coder, context modeling, pipelinecontainer.xtm format (header, block index, CRC32)ioGDAL reader/writer
tests/CTest suite
The encoder and the analyzer share one pipeline implementation — for_each_superblock (src/coding/Pipeline.cpp) owns superblock slicing, quadtree partitioning, and predictor selection for both, on top of the generic parallel_for_superblocks worker pool. See docs/pipeline.md for the full technical reference.
Requirements
To build and use libxtm, you will need:
- C++20 compiler (GCC or MSVC)
- CMake >= 3.21 and Ninja (when using the presets)
- GDAL library
- (Optional) GoogleTest (fetched automatically via CMake if tests are enabled and GTest is not found system-wide)
- (Optional) Python >= 3.10 dev headers — only when building the Python bindings (
-DXTM_BUILD_PYTHON=ON); nanobind is fetched automatically via CMake
Building the Project
libxtm uses CMake. Two presets are provided in CMakePresets.json:
| Preset | Build dir | Type | Flags |
|---|---|---|---|
dev |
build/dev |
Debug | TSan + UBSan, export compile commands |
release |
build/release |
Release | -O3 -march=native -mtune=native, LTO, export compile commands |
# Configure, build, and test with a preset (Ninja required)
cmake --preset release
cmake --build --preset release
ctest --preset release
Without presets, a plain configure works too (defaults to Release if no build type is given):
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j
Build behavior worth knowing:
- Default build type:
Releaseif none is specified. - Warnings as errors:
-Wall -Wextra -Wpedantic+-Werror(GCC, viaXTM_WERROR) or/W4 /WX(MSVC). - Release optimizations:
-O3 -march=native -mtune=native -ftree-vectorizeplus LTO when supported (GCC). - ccache is used automatically when detected (zero-config; skipped silently otherwise).
- Output layout: executables in
build/bin(xtm), libraries inbuild/lib(libxtm_core). - Compile database: with
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON(on in both presets),compile_commands.jsonis symlinked to the project root for IDE/clangd. - Install:
cmake --install build(GNUInstallDirs; installsxtm_core, thextmbinary, and headers).
Build Options
| Option | Default | Description |
|---|---|---|
-DBUILD_SHARED_LIBS=ON |
OFF |
Build xtm_core as a shared library instead of static |
-DBUILD_TESTING=ON/OFF |
ON |
Build the CTest suite; GoogleTest v1.18.0 is fetched from GitHub if not found system-wide |
-DENABLE_TSAN=ON |
OFF |
Thread Sanitizer |
-DENABLE_UBSAN=ON |
OFF |
Undefined Behavior Sanitizer |
-DXTM_BUILD_PYTHON=ON |
OFF |
Build Python bindings (nanobind); module lands in <build>/lib |
-DCMAKE_BUILD_TYPE=... |
Release |
Debug or Release |
Run the unit tests with ctest (via ctest --preset dev|release, or plain ctest inside the build directory); the suite covers lossless round-trips, ROI-vs-full-decode equality, thread determinism, and container/header corruption handling.
Usage
The project builds an executable named xtm:
Usage: xtm <command> [options]
Commands:
analyze Evaluate terrain statistics and compression diagnostics
encode Compress a raster into the .xtm format
decode Decompress an .xtm file (optionally a bounding region) to a raster
info Show .xtm file metadata
verify Verify a decode against source data
Analyze
xtm analyze <input.tif> [--scale <value>] [--wavelet]
Encode
Compress an input raster (e.g., GeoTIFF) into the xtm format:
xtm encode <input.tif> -o <output.xtm> [--scale <value>] [--pipeline predictor|wavelet] [--context simple|extended] [--disable-quadtree]
Decode
Decompress an xtm file back into a raster. Optionally decode a bounding region:
xtm decode <input.xtm> -o <output.tif> [--region x y w h]
Precision model
XTM is an error-bounded codec, not a bit-exact Float32 codec. Elevations are
quantized to fixed-point integers before coding, so every sample round-trips
within |z - z_hat| <= scale / 2 units (the CLI default scale is 1.0, i.e.
meter precision; pass --scale 0.01 for centimeter precision at the cost of
larger files). The quantization is lossless with respect to the quantized
integer grid: decode reproduces the exact grid the encoder produced.
Note: the experimental --pipeline wavelet mode is only valid with
--scale >= 1.0.
C++ API
Alongside the CLI, libxtm exposes a high-level file-oriented API in the
xtm::api namespace (include/xtm/Api.hpp). The CLI commands are thin
wrappers around these functions — the API is the single source of truth for
the encode/decode/analyze/info/verify flows.
| Function | Purpose |
|---|---|
encode_file(input, output, options) |
Compress any GDAL-readable raster into .xtm |
decode_file(input, output, options) |
Decompress to GeoTIFF, optionally a bounding region |
analyze_file(input, options, analyzer_options) |
Run the selection pipeline and return the decision report |
info_file(xtm_path) |
Read the .xtm header and block index without decoding payloads |
verify_file(xtm_path, tif_path) |
Checksum-only verification (empty tif_path) or decode-vs-source comparison |
version() |
Version string |
#include <xtm/Api.hpp>
// Encode with centimeter precision.
xtm::api::EncodeResult result = xtm::api::encode_file(
"input.tif", "output.xtm",
{0.01, xtm::coding::ContextModel::Simple,
xtm::analyzer::PipelineType::Predictor, /*disable_quadtree=*/false,
/*num_threads=*/0}); // 0 = hardware concurrency
// Decompress only a bounding region (x, y, width, height).
xtm::api::decode_file("output.xtm", "region.tif",
{128, 128, 512, 512, 0});
Option structs mirror the CLI flags:
EncodeOptions—precision,context_model(Simple/Extended),pipeline_type(Predictor/Wavelet),disable_quadtree,num_threads.
DecodeOptions—region_x/region_y/region_width/region_height(width or height0= full grid),num_threads.
Results:
EncodeResult(dimensions,total_blocks,predictor_countsmapping frozen PredictorId → block count,output_bytes, per-stage ms timings),DecodeResult(blocks_decoded, dimensions),FileInfo(header + block index,block_count,total_payload_bytes),VerifyResult(passed, counts of checked/mismatched pixels).
Error contract: invalid options throw std::invalid_argument; I/O, codec, and
corrupt-file failures throw std::runtime_error.
Python Bindings
The same file-level surface is available from Python via nanobind — no numpy,
no runtime pip dependencies. The module can be built in-tree and used through
PYTHONPATH (as wired into CTest):
cmake -S . -B build/release -DXTM_BUILD_PYTHON=ON
cmake --build build/release --parallel
PYTHONPATH=build/release/lib python3 -c "import xtm; print(xtm.version())"
or installed as a wheel (build machine needs cmake, ninja, and GDAL dev headers, matching the C++ requirements):
pip install .
The artifact lands at <build>/lib/xtm.abi3.so (STABLE_ABI, portable
across CPython ≥ 3.12). A plain-assert test script
(tests/python/test_xtm_bindings.py) is wired into CTest as
python_bindings and runs automatically with ctest when the option is on.
import xtm
# Encode a raster (centimeter precision) and inspect the result.
res = xtm.encode("grand_canyon.tif", "gc.xtm", precision=0.01)
print(res.total_blocks, res.output_bytes, res.predictor_counts)
# Metadata without decoding payloads.
info = xtm.info("gc.xtm")
print(info.width, info.height, info.precision, info.transform)
# Decode a bounding region (x, y, width, height); region=None = full grid.
xtm.decode("gc.xtm", "gc_roi.tif", region=(0, 0, 512, 512))
# Checksum-only verify, or decode-vs-source comparison when tif is given.
v = xtm.verify("gc.xtm", "grand_canyon.tif")
assert v.passed
Functions (all run with the GIL released):
| Function | Signature |
|---|---|
encode |
(input, output, precision=1.0, pipeline="predictor", context="simple", disable_quadtree=False, num_threads=0) -> EncodeResult |
decode |
(input, output, region=None, num_threads=0) -> DecodeResult |
analyze |
(input, precision=1.0, wavelets=False, num_threads=0) -> AnalysisReport |
info |
(path) -> FileInfo |
verify |
(xtm, tif=None) -> VerifyResult |
version |
() -> str |
Notes:
- Predictor IDs are frozen: 0=Gradient, 1=Left, 2=JpegLs, 3=Polynomial,
4=Gap, 5=LeastSquares (
EncodeResult.predictor_countskeys). - Invalid options raise
ValueError; I/O, codec, and corrupt-file failures raiseRuntimeError(C++ exceptions mapped inbindings/xtm.cpp). - Do not build the module with the
devpreset (TSan+UBSan) — Python is not TSan-instrumented; use thereleasepreset.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file libxtm-0.2.0.tar.gz.
File metadata
- Download URL: libxtm-0.2.0.tar.gz
- Upload date:
- Size: 307.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c96a0487adf193b316f935181e2b623b00a2a6272218c0c876f88ef5495c1ab0
|
|
| MD5 |
b8123591d0f9c1bf948b4e666617dc0b
|
|
| BLAKE2b-256 |
afafdbc60eb280cc1b913383ee9754d833288be8d0e6adf0b0e9198cbd608a3f
|
Provenance
The following attestation bundles were made for libxtm-0.2.0.tar.gz:
Publisher:
release.yml on yashwk/libxtm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libxtm-0.2.0.tar.gz -
Subject digest:
c96a0487adf193b316f935181e2b623b00a2a6272218c0c876f88ef5495c1ab0 - Sigstore transparency entry: 2452328680
- Sigstore integration time:
-
Permalink:
yashwk/libxtm@8e37c10c31112f3343b3f1c6b6e702c8057d4a4f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/yashwk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8e37c10c31112f3343b3f1c6b6e702c8057d4a4f -
Trigger Event:
release
-
Statement type:
File details
Details for the file libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 55.1 MB
- Tags: CPython 3.12+, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21be703a3428b92a8cf7375dff2ed3a28d7d1146033b7b6a0752a1b5b814e2ac
|
|
| MD5 |
48d4ad25e024ef468a63ff3e2e3e02b7
|
|
| BLAKE2b-256 |
566b43f50e5d66e897021bf1933eeefbc3c5f81375a59c5e8c174b3810f54553
|
Provenance
The following attestation bundles were made for libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl:
Publisher:
release.yml on yashwk/libxtm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl -
Subject digest:
21be703a3428b92a8cf7375dff2ed3a28d7d1146033b7b6a0752a1b5b814e2ac - Sigstore transparency entry: 2452328720
- Sigstore integration time:
-
Permalink:
yashwk/libxtm@8e37c10c31112f3343b3f1c6b6e702c8057d4a4f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/yashwk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8e37c10c31112f3343b3f1c6b6e702c8057d4a4f -
Trigger Event:
release
-
Statement type: