Skip to main content

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 .xtm file without uncompressing the dataset.
  • Comprehensive Analyzer: terrain statistics, predictor performance, and compression diagnostics via xtm analyze.

Architecture

  • apps/xtm/ CLI — encode, decode, analyze, info, verify
  • include/ public API
  • src/
    • terrain quantization, NoData inpainting
    • partition quadtree 512→64 partitioning, block views
    • predictor predictor models (Left, Gradient, JpegLs, Gap, Polynomial, LeastSquares)
    • analyzer per-block predictor selection + statistics
    • transform CDF 5/3 integer wavelet
    • coding arithmetic coder, context modeling, pipeline
    • container .xtm format (header, block index, CRC32)
    • io GDAL 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: Release if none is specified.
  • Warnings as errors: -Wall -Wextra -Wpedantic + -Werror (GCC, via XTM_WERROR) or /W4 /WX (MSVC).
  • Release optimizations: -O3 -march=native -mtune=native -ftree-vectorize plus LTO when supported (GCC).
  • ccache is used automatically when detected (zero-config; skipped silently otherwise).
  • Output layout: executables in build/bin (xtm), libraries in build/lib (libxtm_core).
  • Compile database: with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (on in both presets), compile_commands.json is symlinked to the project root for IDE/clangd.
  • Install: cmake --install build (GNUInstallDirs; installs xtm_core, the xtm binary, 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 height 0 = full grid),
    • num_threads.

Results:

  • EncodeResult (dimensions, total_blocks, predictor_counts mapping 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_counts keys).
  • Invalid options raise ValueError; I/O, codec, and corrupt-file failures raise RuntimeError (C++ exceptions mapped in bindings/xtm.cpp).
  • Do not build the module with the dev preset (TSan+UBSan) — Python is not TSan-instrumented; use the release preset.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

libxtm-0.2.0.tar.gz (307.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl (55.1 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.39+ x86-64

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

Hashes for libxtm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c96a0487adf193b316f935181e2b623b00a2a6272218c0c876f88ef5495c1ab0
MD5 b8123591d0f9c1bf948b4e666617dc0b
BLAKE2b-256 afafdbc60eb280cc1b913383ee9754d833288be8d0e6adf0b0e9198cbd608a3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for libxtm-0.2.0.tar.gz:

Publisher: release.yml on yashwk/libxtm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for libxtm-0.2.0-cp312-abi3-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 21be703a3428b92a8cf7375dff2ed3a28d7d1146033b7b6a0752a1b5b814e2ac
MD5 48d4ad25e024ef468a63ff3e2e3e02b7
BLAKE2b-256 566b43f50e5d66e897021bf1933eeefbc3c5f81375a59c5e8c174b3810f54553

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page