sarpro

Crates.iosarpro
lib.rssarpro
version0.3.2
created_at2025-08-09 00:47:31.263196+00
updated_at2025-09-01 01:55:41.938114+00
descriptionA high-performance Sentinel-1 Synthetic Aperture Radar (SAR) GRD product to image processor.
homepagehttps://github.com/bogwi/sarpro
repositoryhttps://github.com/bogwi/sarpro
max_upload_size
id1787460
size5,280,246
Dan Vi (bogwi)

documentation

https://docs.rs/sarpro

README

SARPRO

A high-performance Sentinel-1 Synthetic Aperture Radar (SAR) GRD product to image processor written in Rust. SARPRO is designed for users and organizations who need fast, hassle-free processing of Sentinel-1 GRD products into GeoTIFF or JPEG formats, delivering excellent grayscale GeoTIFFs and grayscale or synthetic RGB JPEGs with minimal setup time.

Features

  • Sentinel-1 Support: Specialized for Sentinel-1 SAR GRD products
  • Multiple Interfaces: CLI, GUI, and library APIs
  • Blazing Fast Performance: Process dual-band 400MP GRD product images and scale to 4MP (2048x2048) synthetic RGB JPEG with reprojection and padding in just ~1.5 seconds on modern laptops (since v0.2.1, see CHANGELOG for performance details)
  • Flexible Polarization: Support for VV, VH, HH, HV, multiband, and polarization operations (sum, difference, ratio, etc.)
  • Advanced Autoscaling: Multiple strategies including standard, robust, adaptive, and equalized
  • Batch Processing: Process multiple SAFE directories efficiently for ML workflows
  • Output Formats: TIFF and JPEG support with configurable bit depths
  • Memory Efficient: Optimized for processing large SAR datasets
  • I/O Optimized: Performance typically limited by disk I/O, not CPU processing
  • since v0.2.0: Can now reproject to any CRS and resample with nearest, bilinear, cubic, or lanczos algorithms
  • since v0.3.0: Can now automatically detect the target CRS from the product metadata and use it for reprojection. Also new benefit from the new CLAHE autoscale strategy which provides great layer separation in synthetic RGB JPEGs.
  • since v0.3.2: Can now process SAFE ZIPs from remote CDSE/ASF sources with full authentication flow and materialize them into cache (CLI only). See Credentials (CDSE, ASF): setup, discovery, and runtime behavior below for details.

ROADMAP and ROADMAP_explained

See ROADMAP.md for the high‑level phases and upcoming features. See ROADMAP_explained.md for the detailed technical explanation. This highlights what’s coming (COG/STAC, masking, speckle filters, DEM‑based RTC, tiling, time‑series) and expected release groupings.

Note 1: The ROADMAP and its technical explanation might change at any moment prioritizing some features over others or adding new ones and slicing some out. Yet it was created to be a minimal-refactor plan and as organic as possible, though not a contract.

Note 2: The ROADMAP and its technical explanation can have mistakes and knowledge gaps which as our understanding of the project deepens will be eliminated or treated as opinionated.

CHANGELOG

Visit CHANGELOG.md to track the changes.

Best Usage Practices

What SARPRO Can Do Now

  • CLI: Download CDSE (dataspace.copernicus.eu) and ASF (asf.alaska.edu) SAFE ZIPs: Get and process SAFE ZIPs from remote CDSE/ASF sources with full authentication flow and materialize them into cache.

    • Flags: --safe-zip-url <URL>, --remote-cache-dir <PATH/TO/CACHE>, --output <PATH/TO/OUTPUT/NAME.jpg|tiff>, --output-dir <PATH/TO/OUTPUT/>
    • Download a SAFE ZIP from CDSE and process it into a TIFF file.
CDSE_ZIP_URL="https://download.dataspace.copernicus.eu/odata/v1/Products(e1499d5b-6e3f-40c1-9c09-d6afe4fdcfeb)/$value"
cargo run --bin sarpro -- --safe-zip-url "$CDSE_ZIP_URL" \
    --remote-cache-dir /tmp/sarpro_cache \
    --output /tmp/ --format tiff --polarization vv \
    --size 1024 --log --target-crs auto
    • Download a SAFE ZIP from ASF and process it into a JPEG file.
ASF_ZIP_URL="https://datapool.asf.alaska.edu/GRD_HD/SA/S1A_IW_GRDH_1SDV_20250827T225857_20250827T225922_060728_078ECD_5BCB.zip"
cargo run --bin sarpro -- --safe-zip-url "$ASF_ZIP_URL" \
    --remote-cache-dir /tmp/sarpro_cache \
    --output /tmp/asf_ok.jpg --format jpeg --polarization multiband \
    --size 1024 --log --target-crs auto
    • Note 1: Use --output /path/to/output/name.jpg|tiff to set the output filename directory and the name of the file. If the name is not set, like in the CDSE example, the default is the canonical filename of the .SAFE file.
    • Note 2: If the .SAFE.zip asset was already materialized into cache, it will be used from cache instead of downloading again. And naturally once downloaded as .zip it can be processed over again. Unpacking will dramatically reduce the processing time. This is especially valid for ASF assets as they are packed to half the size in .zip. CDSE GRD assets are typically the full size zips.

  • CLI: In addition to processing local unpacked SAFE files and directories, SARPRO can also process remote ones that do not require authentication flow (tested with nginx(recommended) and python RangeHTTPServer). Accessing remotes behind the local network should not introduce much overhead.
    • Flags you need: --input <PATH_OR_URL> and --input-dir <PATH_OR_URL>
    • Process a remote unpacked SAFE asset:
--input http://127.0.0.1:8999/GRD/...F07D.SAFE
...
    • Process a remote directory of unpacked SAFE files:
--input-dir http://127.0.0.1:8999/GRD/
...
    • Or process the entire local directory of unpacked SAFE files, which is the fastest way to process a large number of SAFE files.
--input-dir /path/to/GRD
...
    • Note: GRD is a placeholder for a directory containing unpacked SAFE files served by a server or on your local filesystem.

  • What about downloading from an assorted list of URLs, say urls.txt?
https://datapool.asf.alaska.edu/GRD_HD/SA/S1A_IW_GRDH_1SDV_20240516T225933_20240516T225958_053903_068D39_BA0C.zip
https://datapool.asf.alaska.edu/GRD_HD/SA/S1A_IW_GRDH_1SDV_20240528T225908_20240528T225933_054078_069350_95E2.zip
https://datapool.asf.alaska.edu/GRD_HD/SA/S1A_IW_GRDH_1SDV_20250411T110554_20250411T110623_058708_07455A_3328.zip
https://download.dataspace.copernicus.eu/odata/v1/Products(82fcf068-c4df-4735-87d1-7eb9aad4b231)/$value

Support for a native flag --input-list <PATH/TO/LIST/OF/URLS> is coming soon. In the meantime, see sarpro_intake_cdse_asf_urls.sh (Bash, Linux/macOS) and sarpro_intake_cdse_asf_urls.py (Python, cross-platform) for robust, parallel batch processing from a list of URLs.

chmod +x sarpro_intake_cdse_asf_urls.sh
./sarpro_intake_cdse_asf_urls.sh
python sarpro_intake_cdse_asf_urls.py
    • Note: The urls.txt can have GRD assets to be downloaded, resumed, or already materialized into cache. SARPRO will process them all.
    • Important! ASF assets can be resumed at any time, CDSE assets cannot (at least not with the current implementation) and will be re-downloaded after an interruption.

  • Convert Sentinel‑1 GRD .SAFE to map‑ready GeoTIFFs (u8/u16): Single‑band VV/VH/HH/HV or dual‑band multiband TIFFs with embedded geotransform/projection. Optional reprojection to a target CRS (e.g., EPSG:4326, EPSG:32633) with --target-crs and resampling (--resample-alg nearest|bilinear|cubic|lanczos).
  • Produce high‑quality quicklooks (JPEG) with sidecars: Grayscale or synthetic RGB JPEGs, plus .json metadata, .jgw/.wld worldfile, and .prj projection. Great for catalogs and reports.
  • Generate synthetic RGB from dual‑pol scenes: Combine co‑pol and cross‑pol pairs (VV+VH or HH+HV) into visually compelling composites for exploration and communication.
  • Run polarization math for feature exploration: Output SAR‑specific gray products from sum, diff, ratio, n-diff, and log-ratio on available pairs (VV/VH or HH/HV) to emphasize scattering differences.
  • Batch‑process folders of SAFE robustly: Convert many products in one run with --batch and --input-dir/--output-dir, continue on errors, and get per‑run summaries.
  • Downsample huge rasters on read efficiently: Read bands directly at the requested output size (long‑side --size), minimizing I/O and memory. Choose resampling quality; Lanczos and Average are used appropriately when shrinking (v0.2.3+).
  • Resize/pad to consistent shapes for ML: Standardize outputs to 512/1024/2048 (or custom) and --pad to square for CNN‑friendly datasets.
  • Preserve native geometry when needed: Skip reprojection with --target-crs none to avoid any resampling (better for quantitative pixel comparisons and downstream co‑registration pipelines).
  • Embed and export georeferencing correctly: TIFFs carry affine transform and projection; JPEGs ship with world/projection files and JSON metadata.
  • Use a GUI for local, interactive runs: Select SAFE folders, tweak parameters, monitor progress, and auto‑generate equivalent CLI commands.
  • Integrate as a Rust library: Call the typed API to get in‑memory buffers or write outputs directly from your application, reusing SARPRO’s autoscaling and writers.

Where SARPRO v0.3.2 fits today (GRD):

  • Exploratory analysis and visualization: Rapidly turn SAFE into publication‑quality figures and synRGB quicklooks for urban, agriculture, water, and disaster contexts.
  • Internal data catalogs: Generate standardized JPEG quicklooks and GeoTIFFs with consistent sizing for fast browsing and indexing.
  • ML dataset preparation: Create reproducible grayscale or multiband inputs with fixed sizes/padding, ready for training/evaluation.
  • Map overlays and GIS: Reproject to a target CRS for drop‑in alignment in QGIS or web maps; or keep native geometry for quantitative pipelines.
  • Polarization‑based feature engineering: Produce ratio/log‑ratio/n‑diff layers to prototype features for downstream models.

When to Use Each Interface

  • CLI: Ideal for server environments and remote processing. Perfect for batch processing large datasets ready for machine learning workflows. Connect remotely and process images in bulk with consistent, automated results.

  • GUI: Best for local work and interactive processing. Use when you need visual feedback, parameter experimentation, or one-off processing tasks on your local machine.

  • Library: For experimentation and when you need direct access to core processing functions. Integrate SARPRO capabilities into your own Rust applications.

Credentials (CDSE, ASF): setup, discovery, and runtime behavior

Purpose

  • Document exactly how SARPRO discovers and applies credentials per provider, for both materialized and streaming I/O, including file precedence, env vars, cookies, and progress preflight.

Credential discovery (runtime precedence)

  • CDSE (dataspace.copernicus.eu)
    • Env: CDSE_CLIENT_ID, CDSE_CLIENT_SECRET (OAuth2 client_credentials)
    • On first use, SARPRO exchanges for a bearer token at .../openid-connect/token and injects Authorization: Bearer <token> into HTTP requests.
    • Token is cached in‑process with expiry; on 401 it is refreshed and the request retried.
    • For streaming via GDAL, the same Authorization can be applied through GDAL config (GDAL_HTTP_HEADERS) when needed.
  • ASF (asf.alaska.edu)
    • Netrc precedence (first found is used):
      1. SARPRO_NETRC (absolute path you provide)
      2. Repo‑local sarpro/.netrc
      3. User ~/.netrc
    • Required entry: machine urs.earthdata.nasa.gov login <username> password <password>; file must be chmod 600.
    • Cookies: persisted under ~/.sarpro/asf_cookies.txt and applied to both curl and GDAL (GDAL_HTTP_COOKIEFILE/JAR).

Materialize vs stream (ZIP handling)

  • Materialize (--remote-cache-dir is set)
    • CDSE: downloaded with reqwest using Authorization; canonical filename is resolved via Content‑Disposition or OData ?$select=Name and cached.
    • ASF: downloaded with curl using --netrc-file and cookie jar; resume enabled with -C -, retries and backoff configured; canonical filename comes from the URL tail.
  • Stream (no cache dir)
    • Both providers use GDAL VSI paths (/vsizip//vsicurl/...); CDSE headers/cookies and ASF cookies are applied via GDAL config so range requests and auth flow through GDAL.

Preflight and progress (provider‑agnostic)

  • Before download SARPRO attempts to determine size and filename:
    1. Authenticated HEAD (via curl for ASF, reqwest for CDSE) → parse Content‑Length and Content‑Disposition.
    2. If size unknown, authenticated Range: bytes=0-0 → parse Content‑Range total.
    3. CDSE only (fallback): OData ?$select=Name,ContentLength.
  • The resolved content_length drives a determinate progress bar; if unavailable, progress is shown as indeterminate.

Security & operational notes

  • No credentials are ever embedded in input URLs; all auth is via env variables, netrc, and cookies.
  • Ensure .netrc is chmod 600; otherwise servers may ignore it and GDAL/curl may refuse to use it.
  • CDSE $value endpoints may not support HTTP Range; resume is therefore best‑effort. ASF datapool supports Range and robust resume.

Troubleshooting

  • 401/403 (ASF): verify .netrc host is exactly urs.earthdata.nasa.gov and permissions are 600; remove stale cookies if needed.
  • 401/403 (CDSE): verify CDSE_CLIENT_ID/SECRET; re‑try after token refresh; confirm the product UUID is accessible.
  • Missing progress size: some origins suppress Content‑Length; the Range preflight or OData fallback should populate it when possible.

Examples

# Point SARPRO to a custom netrc file for ASF
export SARPRO_NETRC=/secure/path/earthdata.netrc
chmod 600 "$SARPRO_NETRC"

# CDSE OAuth2
export CDSE_CLIENT_ID=...
export CDSE_CLIENT_SECRET=...

That's it!

Acceptance

  • With valid credentials, both providers work in materialized and streaming modes; size/name preflight is populated in logs; ASF downloads are resumable.

Performance Expectations

SARPRO is optimized for bulk processing with exceptional performance:

  • Performance: Starting from v0.2.1 dramatic optimizations were made to the processing pipeline which you can see in the CHANGELOG. Now processing a dual-band 400MP SAR GRD product image and scaling it to 4MP (2048x2048) synthetic RGB JPEG with padding and reprojection takes approximately ~1.5 seconds on a modern laptop (Apple M4Pro12) with Tamed db autoscale strategy and cubic resampling. Setting reprojection to none will reduce the time to ~348.21 ms. And you might as well expect N x performance improvement in the cloud. Warping to the native resolution same dual-band 400MP SAR GRD product and into synthetic RGB JPEG takes x 12-14 or around 55 seconds. Non warping on the same product peaks around 40 seconds.
  • CPU vs I/O: Debug and release builds show negligible performance differences on the latest Apple Silicon laptops, indicating that your performance will typically be limited by I/O, not CPU
  • Scalability: Run multiple SARPRO or SARPRO UI instances in parallel — limited only by your system’s resources — to handle different workflows simultaneously.
  • Memory Usage: The memory impact is staged sequentially.
  • Error Resilience: The CLI and UI versions are made Error SAFE, which means it will not crash on errors (like no data available or data is corrupted, or wrong GRD product) no matter what.

Mount Fuji synthetic RGB crop example from the full 26544 × 26544px resolution processed by SARPRO in 50 seconds. Data: dataspace.copernicus.eu

Name: S1A_IW_GRDH_1SDV_20250706T204346_20250706T204411_059968_07730F_F70D.SAFE
Size: 1893MB
Sensing time: 2025-07-06T20:39:57.839576
Platform short name: SENTINEL-1
Instrument short name: SAR

Mount Fuji crop example

Layer Separation in synthetic RGB

SARPRO delivers excellent layer separation in synthetic RGB JPEGs, even in highly complex scenes and at extreme zoom levels. The example shown uses the handcrafted Default preset with the new CLAHE autoscale strategy. Speckle is minimal and unobtrusive, despite no speckle filtering being applied. Speckle filtering will be introduced as an optional feature in v0.3.x to further enhance synthetic RGB quality and leverage workstation performance as needed. Layer Separation in synthetic RGB

Recommended Workflows

  1. ML Pipeline Preparation: Use CLI batch mode to process large collections of Sentinel-1 data into consistent formats
  2. Quality Assessment: Use GUI for initial data exploration and parameter tuning
  3. Custom Integration: Use the library API for specialized processing chains or integration with existing systems

About using reprojection or not

Setting reprojection to --target-crs none or omitting it preserves native geometry just as it is packed in the SAFE product.

When native/no-reprojection is useful:

  • Quantitative workflows that avoid resampling:
    • Change detection/ratios on same-orbit, same-processing GRDs handled by an external co-registration/RDTC step.
    • Preserving radiometry/speckle statistics (no interpolation).
  • Downstream processing that performs proper RDTC later (don’t warp twice).
  • Performance/throughput and reproducibility of pixel values for ML feature engineering.
  • Quicklooks where map-accurate alignment is not required.

Requirements

System Dependencies

SARPRO depends on GDAL (Geospatial Data Abstraction Library) for reading and processing geospatial data. This is the only critical dependency to install correctly.

macOS (using Homebrew)

# Install GDAL via Homebrew
brew install gdal

# Verify installation
gdalinfo --version

Environment Variables Setup:

After installing GDAL with Homebrew, you need to set up environment variables for the Rust build process:

# Add to your ~/.zshrc or ~/.bashrc
export GDAL_HOME=$(brew --prefix gdal)
export GDAL_INCLUDE_DIR=$GDAL_HOME/include
export GDAL_LIB_DIR=$GDAL_HOME/lib
export PKG_CONFIG_PATH=$GDAL_HOME/lib/pkgconfig:$PKG_CONFIG_PATH

# For Apple Silicon Macs, you might also need:
export LIBRARY_PATH=$GDAL_HOME/lib:$LIBRARY_PATH
export CPATH=$GDAL_HOME/include:$CPATH

Linux (Ubuntu/Debian)

# Install GDAL development packages
sudo apt update
sudo apt install libgdal-dev gdal-bin pkg-config

# Verify installation
gdalinfo --version

Other Platforms

For other platforms or custom installations, ensure:

  • GDAL development headers are available
  • pkg-config can find GDAL
  • Set GDAL_HOME, GDAL_LIB_DIR, and GDAL_INCLUDE_DIR environment variables if needed

Rust Toolchain

SARPRO requires Rust 2024 edition. Install Rust using rustup:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Installation

From Source

# Clone the repository
git clone https://github.com/bogwi/sarpro.git
cd sarpro

# Build the project
cargo build --release --features full

# The CLI binary will be available at target/release/sarpro
# The GUI binary will be available at target/release/sarproUI

Via Cargo (prebuilt install)

# Install CLI only (default features)
cargo install sarpro

# Install GUI binary (requires GDAL and GUI deps)
cargo install sarpro --features gui --bin sarproUI

Note: Installing the GUI requires the GDAL runtime and GUI dependencies to be available on your system.

Build profiles

  • Default release (recommended for most users): Uses Cargo’s standard release settings with lightweight debug info (debug=1) and panic=abort for useful backtraces. Fast to compile; suitable for cargo install and typical Linux/Windows source installs.
  • Opt‑in LTO (maximum size squeeze): A separate release-lto profile enables fat LTO and codegen-units=1. It produces smaller binaries on many platforms at the cost of significantly longer compile times.

Build examples:

# Fast build (default release)
cargo build --release --features full

# Opt-in fat LTO build
cargo build --profile release-lto --features full

Notes:

  • The default remains optimized for compile time because SARPRO workloads are typically I/O‑bound.
  • Use the LTO profile for published artifacts or when disk size is a priority.

Usage

Command Line Interface (CLI)

The CLI provides powerful batch processing capabilities for SAR imagery, optimized for cloud environments and ML pipeline preparation. Perfect for remote processing and bulk operations.

Usage Examples


# Batch process a directory
cargo run --release --bin sarpro -- --input-dir /path/to/safe/directories --output-dir /path/to/output --batch --log --format jpeg --polarization multiband --size 1024 --autoscale tamed --target-crs auto --resample-alg lanczos --synrgb-mode default

# Process a .SAFE file with specific parameters
cargo run --release --bin sarpro -- -i data.SAFE -o output.tiff \
    --polarization multiband \
    --format tiff \
    --bit-depth u16 \
    --size 1024 \
    --autoscale tamed \
    --target-crs auto \
    --resample-alg lanczos \
    --log

Available Options

  • --input, -i: Input SAFE local path or remote non-authenticated HTTP(S) URL (single file mode)

  • --input-dir: Input local path or remote non-authenticated HTTP(S) URL directory containing SAFE files (batch mode)

  • --output, -o: Output filename (single file mode)

  • --output-dir: Output directory for batch processing

  • --format, -f: Output format (tiff or jpeg)

  • --bit-depth: Output bit depth (8 or 16)

  • --polarization: Polarization mode (vv, vh, hh, hv, multiband, sum, diff, ratio, n-diff, log-ratio)

  • --autoscale: Autoscaling strategy (standard, robust, adaptive, equalized, tamed, default, clahe)

  • --synrgb-mode: Synthetic RGB mode, for JPEG outputs (default, rgb-ratio, sar-urban, enhanced)

  • --size: Output image size (predefined: 512, 1024, 2048, or custom number, or original)

  • --pad: Add padding to make square images

  • --batch: Enable batch mode with error resilience

  • --log: Enable detailed logging

  • --target-crs: Optional target CRS for map reprojection (e.g., EPSG:4326, EPSG:32633). Special values: auto (detect UTM zone from metadata), none (disable reprojection)

  • --resample-alg: Resampling algorithm for reprojection (nearest, bilinear, cubic, lanczos) — default: lanczos

  • --safe-zip-url: Optional remote CDSE(dataspace.copernicus.eu) or ASF(asf.alaska.edu) SAFE ZIP URL to download and process with full authentication flow.

  • --remote-cache-dir: Remote cache directory to materialize the SAFE ZIP (mandatory for remote ZIPs).

Graphical User Interface (GUI)

Launch the GUI application for interactive local processing and experimentation:

  • Start the GUI from the command line:
cargo run --release --bin sarproUI --features gui

or double click the executable here: target/release/sarproUI if you have built the project with the full feature.

The GUI is ideal for local work and provides:

  • File browser for selecting SAFE directories
  • Interactive parameter adjustment
  • Real-time preview and visual feedback
  • Progress monitoring
  • Export/import of configuration presets
  • CLI command generation
  • TRACE, DEBUG, INFO, WARN, ERROR, logging levels
  • System CPU and memory usage monitoring

Screenshots and examples

SARPRO GUI

The GUI is the easiest way to get started with SARPRO locally.

SARPRO GUI

Render example of Sentinel-1 SAR GRD product downloaded from dataspace.copernicus.eu. The 25192 × 19614px (~500MP) reprojected, dual-band image scaled and padded to 3024px on the long side and carrying metadata took just ~2 seconds on Apple M4Pro12 with minimal CPU usage. (see CHANGELOG from v0.2.1 for performance details). Warping it at 25192 × 19614px, and autocaling, padding and into synthetic RGB JPEG takes around 70 seconds.

Name: S1C_IW_GRDH_1SDV_20250730T142348_20250730T142417_003451_006EEA_895D.SAFE
Size: 1893MB
Sensing time: 2025-07-30T14:23:48.452000Z
Platform short name: SENTINEL-1
Instrument short name: SAR

Synthetic RGB

Create good lookers using synthetic RGB JPEGs in a few clicks.

synRGB

Multiband

Get what you need in classic multi-band Grayscale TIFFs, quickly.

multiband

As a Library

SARPRO provides a typed, ergonomic Rust API for integrating Sentinel-1 GRD processing into your applications. The API is built on top of the working MVP used by the CLI/GUI and is robust, but still early and may evolve.

Note on stability: the public API is experimental in initial releases. Expect incremental improvements as the project stabilizes. Breaking changes may occur; consult the changelog and docs.

Add dependency

[dependencies]
sarpro = { version = "0.3", features = ["full"] }

High-level processing to a file

use std::path::Path;
use sarpro::{
    api::process_safe_to_path,
    ProcessingParams,
    AutoscaleStrategy, BitDepthArg, OutputFormat, Polarization,
    InputFormat, SyntheticRgbMode
};

let params = ProcessingParams {
        format: OutputFormat::TIFF,
        input_format: InputFormat::Safe,
        bit_depth: BitDepthArg::U16,
        polarization: Polarization::Multiband,
        autoscale: AutoscaleStrategy::Clahe,
        target_crs: Some("auto".to_string()),
        resample_alg: Some("lanczos".to_string()),
        synrgb_mode: SyntheticRgbMode::Default,
        size: Some(2048),
        pad: true,
    };

    process_safe_to_path(
        Path::new("/data/S1A_example.SAFE"),
        Path::new("/out/product.tiff"),
        &params,
    )?;

In-memory processing to raw buffers

use std::path::Path;
use sarpro::{
    api::process_safe_to_buffer_with_mode,
    AutoscaleStrategy, BitDepth, OutputFormat, Polarization, SyntheticRgbMode,
};

let img = process_safe_to_buffer_with_mode(
    Path::new("/data/S1A_xxx.SAFE"),
    Polarization::Multiband,
    AutoscaleStrategy::Tamed,
    BitDepth::U8,            // Controls buffer bit depth for TIFF paths
    Some(1024),              // Resize target
    true,                    // Pad to square
    OutputFormat::JPEG,      // JPEG for synthetic RGB; TIFF for grayscale/multiband
    SyntheticRgbMode::Default,
)?;

match (img.format, img.bit_depth) {
    (OutputFormat::JPEG, _) => {
        // Synthetic RGB (interleaved RGB u8)
        let rgb: &[u8] = img.rgb.as_ref().unwrap();
        // Use in your pipeline...
    }
    (OutputFormat::TIFF, sarpro::BitDepth::U8) => {
        // Single-band or multiband u8
        let band1 = img.gray.as_ref();
        let band2 = img.gray_band2.as_ref();
    }
    (OutputFormat::TIFF, sarpro::BitDepth::U16) => {
        // Single-band or multiband u16
        let band1 = img.gray16.as_ref();
        let band2 = img.gray16_band2.as_ref();
    }
}

Typed save helpers (when you already have processed intensity arrays)

use std::path::Path;
use ndarray::Array2;
use sarpro::{
    api::{save_image, save_multiband_image},
    AutoscaleStrategy, BitDepth, OutputFormat, ProcessingOperation,
};

fn save_single(processed: &Array2<f32>) -> sarpro::Result<()> {
    save_image(
        processed,
        Path::new("/out/single.tiff"),
        OutputFormat::TIFF,
        BitDepth::U16,
        Some(2048),
        None, // Optional SAFE metadata if available
        true,
        AutoscaleStrategy::Tamed,
        ProcessingOperation::SingleBand,
    )
}

fn save_dual(vv: &Array2<f32>, vh: &Array2<f32>) -> sarpro::Result<()> {
    save_multiband_image(
        vv,
        vh,
        Path::new("/out/multiband.tiff"),
        OutputFormat::TIFF,
        BitDepth::U8,
        Some(1024),
        None,
        true,
        AutoscaleStrategy::Tamed,
        ProcessingOperation::MultibandVvVh,
    )
}

Batch helpers

use std::path::Path;
use sarpro::{
    api::process_directory_to_path,
    ProcessingParams, AutoscaleStrategy, BitDepthArg, OutputFormat, Polarization, InputFormat, SyntheticRgbMode,
};

let params = ProcessingParams {
    format: OutputFormat::JPEG,
    input_format: InputFormat::Safe,
    bit_depth: BitDepthArg::U8,
    polarization: Polarization::Multiband,
    autoscale: AutoscaleStrategy::Tamed,
    synrgb_mode: SyntheticRgbMode::Default,
    size: Some(1024),
    pad: true,
    target_crs: Some("auto".to_string()),
    resample_alg: Some("lanczos".to_string()),
};

let report = process_directory_to_path(
    Path::new("/data/safe_dir"),
    Path::new("/out"),
    &params,
    true, // continue_on_error
)?;

println!("processed={}, skipped={}, errors={}", report.processed, report.skipped, report.errors);

Supported Data

  • Input Formats: Sentinel-1 SAFE directories (GRD products)
  • Polarizations: VV, VH, HH, HV, and combinations
  • Product Types: Ground Range Detected (GRD)
  • Output Formats: GeoTIFF, JPEG

Product assumptions and processing pipeline

What official Sentinel‑1 GRD already includes

  • Radiometric calibration: Yes — DN values are converted to backscatter coefficients (σ⁰/β⁰/γ⁰) in ESA’s GRD chain
  • Thermal noise removal: Yes — applied since IPF 2.9 (2018+)
  • Multilooking & ground‑range projection: Yes — GRD is multilooked and in ground‑range geometry
  • Range‑Doppler Terrain Correction (orthorectification): No — GRD remains in radar geometry without RDTC

What SARPRO does and does not do

  • SARPRO does not perform RDTC/orthorectification or DEM‑based terrain correction
  • Optional map reprojection: If --target-crs is set, SARPRO uses GDAL gdalwarp to reproject using the product’s georeferencing (and falls back to GCP + -tps if needed). This improves map alignment in many cases but is not a substitute for full RDTC
  • Core image steps: magnitude→dB conversion, SAR‑tuned autoscaling, optional resize/pad, then write GeoTIFF or JPEG with metadata. TIFF embeds georeferencing; JPEG is accompanied by .json, .jgw/.wld, and .prj sidecars

Processing flow

flowchart TB
  A["Input: Sentinel-1 SAFE (GRD)"] --> B["Parse manifest.safe + annotation XMLs\nExtract product & georef metadata"]
  A --> C["Identify polarization measurement TIFFs (VV/VH/HH/HV)"]
  C --> D["Read TIFF via GDAL\narray + geotransform + projection/GCP"]
  D --> E{"Target CRS"}
  E -- "none" --> G["Use native georeferencing"]
  E -- "auto" --> Ea["Resolve UTM/UPS from metadata/GCPs\n(e.g., EPSG:326xx/327xx)"] --> F["Warp with gdalwarp to target CRS\n-r nearest/bilinear/cubic/lanczos\nIf no SRS: use GCP + -tps"]
  E -- "custom EPSG" --> F
  F --> H["Optional polarization ops\nsum/diff/ratio/n-diff/log-ratio or pair for synRGB"]
  G --> H
  H --> I["Convert magnitude to dB\n10·log10(|x|) and mask invalid"]
  I --> J["Autoscale to U8/U16 using strategy\nstandard/robust/adaptive/equalized/tamed/clahe"]
  J --> K["Optional resize (long side)"]
  K --> L["Optional pad to square"]
  L --> M{"Output format"}
  M -- "TIFF (u8/u16)" --> N["Write GeoTIFF bands"]
  N --> O["Embed metadata (geotransform/projection + attributes)"]
  M -- "JPEG (gray/synRGB)" --> P["Write JPEG (gray or synthetic RGB)\nmode: default/rgb-ratio/sar-urban/enhanced"]
  P --> Q["Sidecars: .json (metadata), .jgw/.wld, .prj"]

Troubleshooting (GDAL)

  • If the build fails to find GDAL, ensure pkg-config locates it (pkg-config --libs gdal) and the environment variables in this README are exported in your shell.
  • On macOS, confirm brew --prefix gdal resolves and paths are set for both compile and runtime (DYLD_LIBRARY_PATH may also be needed when running outside Cargo).
  • On Linux, verify libgdal-dev and gdal-bin are installed and the GDAL version is supported by the crate.

License

This project is dual-licensed under MIT OR Apache-2.0.

Support

Acknowledgments

SARPRO is built with:

  • GDAL for geospatial data processing
  • ndarray for numerical computing
  • eframe for the GUI
  • clap for command-line parsing
Commit count: 60

cargo fmt