Skip to main content

geozl

License: BSD-3-Clause Coverage Platform C11 Built on OpenZL

What is OpenZL and GeoZL?

OpenZL is a new compression framework that treats compression as a graph of codecs. Each frame carries the recipe needed to decode it, which lets a universal OpenZL decoder follow the graph without knowing how the data was originally encoded.

That model works well for one-dimensional streams, but it does not know that a raster has spatial structure. geozl adds that missing spatial layer.

A geozl codec is an OpenZL graph node that understands raster tiles. It transforms a typed numeric stream, stores the metadata needed to reverse that transform in the codec header, and lets the rest of the OpenZL graph continue as usual.

If you want to implement a new codec, see docs/adding-a-codec.md.

Status

geozl is experimental.

[!WARNING] geozl codecs are not part of OpenZL.

They are registered at runtime as OpenZL custom transforms and use CTids in the 0x72D700-0x72D7FF range. A frame that uses geozl codecs can only be decoded by a reader that has geozl registered. Frames that use only built-in OpenZL codecs remain portable OpenZL frames.

Install

pip install geozl

Example

geozl has two entry points: a high-level API that compresses a tile in one call, and a low-level API that places individual codecs in an OpenZL graph.

High-level API

Three calls. geozl.profile measures a set of candidate graph on your tile and ranks them; geozl.compress runs the one you name and returns the frame. It never searches, so the slow call happens once and the fast one happens on every tile after that. Finally, geozl.decompress reverses the frame back to a tile.

import numpy as np
import geozl

tile = np.random.randint(0, 4096, (1024, 1024), dtype=np.uint16)

rows = geozl.profile(tile)                        # the slow call, run once
best = rows[0]["graph"]                           # e.g. "planar>zigzag>transpose>entropy"

frame = geozl.compress(tile, method=best)         # the fast call, run always
frame = geozl.compress(tile, method=best, max_error=2)  # near-lossless, absolute bound

back = geozl.decompress(frame, dtype="uint16", width=1024)

Low-level API

For anything else, place the codecs in an openzl.ext graph yourself, alongside regular OpenZL nodes.

import openzl.ext as zl
import geozl

c = zl.Compressor()
g = zl.graphs.Compress()

g = zl.nodes.Zigzag()(c, g)
g = geozl.lossless.Planar(width=512)(c, g)

c.select_starting_graph(g)

Decoding

Either way, a reader has to register the geozl decoders before it can follow the frame.

import openzl.ext as zl
import geozl

d = zl.DCtx()
geozl.register_decoders(d)
tile = d.decompress(frame)[0].content.as_nparray()

Codecs

geozl currently provides two codec families:

  • near-lossless codecs, under geozl.lossy
  • lossless codecs, under geozl.lossless

Both families are registered as OpenZL custom codecs and can be chained with other OpenZL graph nodes.

The call column shows the Python call used to place the codec in a graph.

Near-lossless codecs

Near-lossless codecs quantize the tile once, then store enough information in the frame to report and bound the reconstruction error. A near-lossless frame is no longer bit-exact, it declares the bound it holds to instead.

A frame carries at most one near-lossless codec, as the head transform, so the loss happens once and every stage after it is lossless.

codec call CTid error
quant_linear geozl.lossy.QuantLinear(max_error, dtype) 0x72D780 every value reconstructs within max_error, an absolute tolerance

Lossless codecs

Lossless codecs are bit-exact transforms over a raster tile. After decoding, the reconstructed tile is identical to the original input.

Predictors replace each sample with its residual against a prediction from neighbours the decoder already holds. They take the row width, and one successor.

codec call CTid what it does
delta_w geozl.lossless.DeltaW(width) 0x72D701 stores each value as a difference from its west neighbour
delta_n geozl.lossless.DeltaN(width) 0x72D702 stores each value as a difference from its north neighbour
planar geozl.lossless.Planar(width) 0x72D703 predicts each pixel from W + N - NW
med geozl.lossless.Med(width) 0x72D705 uses the median edge detector predictor
average geozl.lossless.Average(width) 0x72D706 predicts from the floor average of west and north neighbours
wp_static geozl.lossless.WpStatic(width) 0x72D707 fits a static weighted predictor and stores the weights in the frame

Splits cut one stream into two lanes, so they take two successors, one per lane, and each lane can go on to its own graph.

codec call CTid lanes what it does
deinterleave geozl.lossless.Deinterleave() 0x72D704 both to one successor separates a two-lane interleaved stream; for complex, view the tile through geozl.lossless.component_dtype first, OpenZL has no complex type
nodata geozl.lossless.Nodata(width, value=None, dtype=None) 0x72D70C raster, then mask pulls missing samples into a validity mask and fills the holes; value=None takes the tile's NaN

License

BSD-3-Clause


Made with ♥ by

Asterisk Labs

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

geozl-0.7.10-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (8.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

geozl-0.7.10-py3-none-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file geozl-0.7.10-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for geozl-0.7.10-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cd2392075c6fbf3a9ecfcc191a7a2a82bc675a9749d8c95c98ae5639a1b67706
MD5 937d639f5aaccf56159727c3649ad943
BLAKE2b-256 281d448712e7ac49c54d8eade2e88e3a6e33c3ee39b82809b15686a7b8b29aef

See more details on using hashes here.

Provenance

The following attestation bundles were made for geozl-0.7.10-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on asterisk-labs/geozl

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

File details

Details for the file geozl-0.7.10-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for geozl-0.7.10-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 83ec61d2dfcd48f2c282ae737e5dbdcad903519ece62e024e987f0b0dbc7d33f
MD5 d99b3f134481e355a72cc56d342a9c3b
BLAKE2b-256 79f9602877ec60efd84ccfae8d54085c55fff3473a613efa0227290e2e46329e

See more details on using hashes here.

Provenance

The following attestation bundles were made for geozl-0.7.10-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on asterisk-labs/geozl

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page