# How GeoLibre's Browser-Based COG Conversion Works: Client-Side Cloud-Optimized GeoTIFF Processing

> Discover how GeoLibre's browser-based tools convert GeoTIFFs to COGs client-side using WebAssembly. Achieve serverless processing and immediate streaming for your geospatial data.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: how-to-guide
- Published: 2026-07-31

---

**GeoLibre converts standard GeoTIFF rasters to Cloud-Optimized GeoTIFFs (COGs) entirely within the browser using the `geolibre-wasm` WebAssembly module**, eliminating server dependencies and enabling immediate streaming to MapLibre layers.

GeoLibre delivers **browser-based COG conversion** through its `@geolibre/processing` package, allowing users to transform massive geospatial rasters without uploading data to a server. This client-side architecture leverages a Rust-compiled WebAssembly module to handle the computationally intensive tasks of re-tiling and overview generation that traditionally require Python GDAL bindings.

## WebAssembly Initialization and Setup

The conversion pipeline begins with a one-time initialization of the `geolibre-wasm` module. In [`packages/processing/src/cog-convert.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/cog-convert.ts), the `initCogWasm` helper wraps the WebAssembly loader, ensuring the `init` function runs only once per page session.

This initialization accepts an optional WASM binary or URL parameter, enabling the same code to function in non-browser hosts like Tauri desktop applications or Jupyter embeddings. Once loaded, the module exposes `GeoTiffReader` and `CogBuilder` classes that handle the heavy lifting of TIFF parsing and reconstruction.

## The Five-Stage COG Conversion Pipeline

### Stage 1: Lightweight Metadata Extraction

Before processing pixels, GeoLibre extracts critical metadata using `readGeoTiffInfo` from the WASM module. This function parses the TIFF header via `geotiff_info` without loading the actual raster data, making it safe for large files.

The resulting `GeoTiffInfo` object contains dimensions, band count, EPSG code, nodata values, and whether the source is already tiled. This metadata drives all downstream configuration decisions.

### Stage 2: Tiling Verification

The `isTiledGeoTiff` function checks the `info.tiled` boolean. If the source raster already uses internal tiling—meaning it is a valid COG— GeoLibre bypasses the conversion entirely and streams the file directly to the MapLibre raster source. This short-circuit prevents unnecessary re-encoding of already-optimized data.

### Stage 3: Overview Pyramid Calculation

For non-tiled sources, `overviewLevels` calculates the decimation factors needed for fast multi-resolution rendering. The algorithm generates powers of 2 (1, 2, 4, 8...) until the largest image dimension falls below 256 pixels.

These factors determine the number of overview layers embedded in the output COG, ensuring smooth zooming performance from full resolution down to thumbnail scale.

### Stage 4: Core Re-encoding with CogBuilder

The `convertGeoTiffToCog` function in [`packages/processing/src/cog-convert.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/cog-convert.ts) orchestrates the heavy processing:

1. **Normalization**: Calls `reader.read_all_f64()` to normalize any source data type (Int16, Float32, etc.) to 64-bit floating point.
2. **Builder Setup**: Instantiates a `CogBuilder` with source width, height, and band count.
3. **Metadata Transfer**: Copies geospatial metadata—including EPSG code, GeoTransform, and nodata values—from the reader to the builder.
4. **Configuration**: Sets the **tile size to 512 pixels** (`COG_TILE_SIZE`), selects compression from `COG_WASM_COMPRESSIONS` (defaulting to `"deflate"`), and applies the calculated overview levels.
5. **Type-Specific Writing**: If the source is 8-bit unsigned (`sample_format === "uint"` and `bits_per_sample ≤ 8`), the builder uses `write_u8`. Otherwise, it outputs 32-bit float using `write_f32`.

### Stage 5: Output Generation

The function returns a `Uint8Array` containing the fully-formed COG. This byte array can be wrapped in a Blob and converted to an object URL for immediate consumption by MapLibre's raster layer, requiring zero server round-trips.

## Configuration Options and Compression Settings

GeoLibre fixes the **COG tile size at 512 pixels** (`COG_TILE_SIZE`) for optimal browser rendering performance. Users can select compression algorithms via the UI dropdown bound to the `COG_WASM_COMPRESSIONS` array, which supports:

- **"deflate"** (default)
- **"lzw"**
- **"packbits"**
- **"none"**

The compression selection passes directly to the WASM layer during the `CogBuilder` configuration phase.

## UI Integration and MapLibre Consumption

The raster panel UI (typically found in the plugins package) wires the conversion workflow to user interactions. When a user selects a file and clicks "Convert to COG":

1. The `FileReader` API loads the source as bytes
2. `convertGeoTiffToCog` processes the buffer with the selected compression
3. The resulting `Uint8Array` becomes a Blob URL via `URL.createObjectURL`
4. MapLibre consumes this blob URL as a raster layer source

Because the conversion runs entirely client-side, the same implementation works across web builds, Tauri desktop applications, and Jupyter embedded widgets.

## Python Side-Car Fallback

When browser security policies (CSP) or unsupported browsers block WebAssembly loading, GeoLibre falls back to the `backend/geolibre_server` Python side-car. This backend uses `rio-cogeo` to perform the conversion, though this path is rarely triggered for typical web users with modern browsers.

## Summary

- **Zero-server processing**: GeoLibre's `@geolibre/processing` package converts GeoTIFFs to COGs entirely in the browser using the `geolibre-wasm` WebAssembly module.
- **Smart optimization**: The pipeline checks existing tiling status, calculates overview pyramids down to 256px, and configures 512px tiles with configurable compression.
- **Type-aware output**: The system automatically selects 8-bit unsigned or 32-bit float output based on source data characteristics.
- **Universal compatibility**: The same conversion code runs in web browsers, desktop apps, and Jupyter notebooks, with a Python fallback for restricted environments.

## Frequently Asked Questions

### Does GeoLibre require Python or GDAL installed locally for COG conversion?

No. The browser-based conversion runs entirely client-side using the `geolibre-wasm` WebAssembly module. While GeoLibre includes a Python side-car that uses `rio-cogeo` as a fallback for restricted environments, typical users convert Cloud-Optimized GeoTIFFs without any server dependencies or local GDAL installations.

### What compression algorithms does GeoLibre support for browser-based COG creation?

GeoLibre supports `"deflate"` (default), `"lzw"`, `"packbits"`, and `"none"` through the `COG_WASM_COMPRESSIONS` array defined in the processing package. Users select their preferred compression via the UI dropdown, and the value passes directly to the `CogBuilder` configuration before writing the output tiles.

### Why does GeoLibre normalize raster data to 64-bit floating point during conversion?

The `read_all_f64()` method normalizes Int16, Float32, and other source formats to 64-bit floating point for consistent internal processing within the WebAssembly module. After processing, the `CogBuilder` writes the final output as either 8-bit unsigned (via `write_u8`) for compatible sources or 32-bit float (via `write_f32`) for higher bit-depth data, ensuring the COG maintains appropriate precision while optimizing file size.

### Can GeoLibre convert GeoTIFFs that are already Cloud-Optimized?

Yes. The `isTiledGeoTiff` function checks the `info.tiled` property during the metadata extraction phase. If the source is already internally tiled and structured as a valid COG, GeoLibre bypasses the re-encoding process entirely and creates a raster layer pointing directly to the original file, avoiding unnecessary computation and quality degradation.