Educational Python implementation of the GFWX wavelet codec
Project description
PyGFWX
A Python implementation of the GFWX (Good, Fast Wavelet Codec) for educational purposes.
Test image: "Orange tabby cat sitting on fallen leaves" by Hisashi (derivative work: Caspian blue), CC BY-SA 2.0
Overview
PyGFWX is an educational implementation of the GFWX wavelet codec, created to learn and understand wavelet-based image compression. The implementation prioritizes readability over performance - it's written in pure Python with NumPy for data structures, but no optimized libraries for the core algorithms.
Note: This is a learning tool, not a production codec. For high-performance encoding, use the reference C++ SDK. PyGFWX is useful for understanding how wavelet compression works, experimenting with the algorithm, and educational purposes.
Compression Demo
Using the cat image above (768×1024 RGB), here are compression results at different quality levels:
| Quality | Compressed Size | Compression Ratio | PSNR |
|---|---|---|---|
| 64 (high compression) | 64 KB | 36:1 | 37.4 dB |
| 256 (medium) | 246 KB | 9.4:1 | 43.9 dB |
| 512 (high quality) | 483 KB | 4.8:1 | 47.6 dB |
| 1024 (lossless) | 847 KB | 2.7:1 | ∞ |
Original uncompressed size: 2.25 MB (768×1024×3 bytes)
Features
- Wavelet compression using lifting scheme (5/3 and 9/7 wavelets)
- Golomb-Rice entropy coding with context-adaptive modeling
- Progressive decoding with downsampling support
- Multiple color modes: Mono, RGB, RGBA, Bayer patterns
- Quality range: Lossy (1) to lossless (1024)
- Multi-layer support: Stereo images, depth maps, animation frames
- Custom color transforms: Programmable UYV, A710, and custom transforms
- Metadata support: JSON, key-value, or binary metadata blocks
Why Pure Python?
This project implements the full codec in readable Python to make it easy to:
- Step through the compression pipeline with a debugger
- Understand each stage: wavelets, quantization, entropy coding
- Experiment with modifications to the algorithm
- Learn wavelet compression without deciphering optimized C++
The code is validated against the reference SDK to ensure correctness, but runs significantly slower (expect 100x+ slower than the C++ implementation).
Installation
This project uses uv for dependency management.
# Clone the repository
git clone https://github.com/chiplukes/pygfwx.git
cd pygfwx
# Install dependencies
uv sync
# Install with development dependencies
uv sync --all-extras
Quick Start
from pygfwx import encode, decode
import numpy as np
# Create or load an image (numpy array)
image = np.random.randint(0, 256, (256, 256), dtype=np.uint8)
# Encode (compress)
compressed = encode(image, quality=512)
# Decode (decompress)
decoded = decode(compressed)
# Verify
assert np.array_equal(image, decoded) # True for lossless (quality=1024)
Project Structure
pygfwx/
├── src/pygfwx/ # Main Python package
│ ├── core/ # Core codec implementation
│ │ ├── bitstream.py # Bit-level I/O
│ │ ├── header.py # GFWX header parsing
│ │ ├── lifting.py # Wavelet transforms
│ │ ├── golomb_rice.py # Entropy coding
│ │ ├── context.py # Context modeling
│ │ ├── encoder.py # Coefficient encoding
│ │ ├── decoder.py # Coefficient decoding
│ │ ├── transforms.py # Color transforms
│ │ ├── bayer.py # Bayer/RAW support
│ │ ├── multi_layer.py # Multi-layer images
│ │ └── metadata.py # Metadata utilities
│ ├── streaming/ # Progressive/streaming support
│ └── utils/ # Helper functions
├── cross_codec/ # SDK wrapper and validation tools
├── tests/ # Test suite (385+ tests)
├── examples/ # Example scripts
├── notes/ # Documentation
└── gfwx-sdk/ # Reference C++ SDK
Documentation
- Compression Overview - How GFWX compression works
- Bitstream Format - GFWX file format specification
- Lifting Scheme - Wavelet transform details
- Golomb-Rice Coding - Entropy coding explanation
- Project Plan - Development roadmap
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=pygfwx
# Run specific test file
uv run pytest tests/test_bitstream.py
# Run SDK comparison tests (requires built SDK)
uv run pytest -m sdk
Development
Code Quality
# Check linting
uv run ruff check src tests
# Format code
uv run ruff format src tests
Building the SDK
The reference SDK is needed for validation tests:
cd gfwx-sdk/build
cmake ..
cmake --build . --config Release
Quality Levels
| Quality | Description | Use Case |
|---|---|---|
| 1-64 | High compression | Thumbnails, previews |
| 64-256 | Medium-high | Web images |
| 256-512 | Medium | General photography |
| 512-1000 | Low compression | High quality |
| 1024 | Lossless | Archival, masters |
How It Works
GFWX uses a wavelet-based compression pipeline:
- Color Transform - Convert RGB to decorrelated color space (UYV)
- Wavelet Transform - Apply lifting-based wavelet decomposition
- Quantization - Scale coefficients based on quality setting
- Entropy Coding - Golomb-Rice coding with context modeling
┌─────────┐ ┌─────────┐ ┌────────┐ ┌─────────┐
│ Image │ -> │ Color │ -> │Wavelet │ -> │Quantize │ -> ┌──────────┐
│ RGB │ │Transform│ │ Lift │ │ Scale │ │ Entropy │
└─────────┘ └─────────┘ └────────┘ └─────────┘ │ Code │
└────┬─────┘
│
v
┌──────────┐
│Compressed│
│ Data │
└──────────┘
References
License
BSD 3-Clause License (same as GFWX)
Acknowledgments
- Graham Fyffe for creating GFWX
- USC Institute for Creative Technologies
- GFWX is "thoroughly tested using several pictures of cats" 🐱
This is an educational project focused on understanding wavelet-based image compression.
Project details
Release history Release notifications | RSS feed
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 pygfwx-0.1.0.tar.gz.
File metadata
- Download URL: pygfwx-0.1.0.tar.gz
- Upload date:
- Size: 5.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f58eaa8d2b939cf8ac8221d966fd32d0155919a82463a6f90a2a49b16347290e
|
|
| MD5 |
521c0ea87d36169c233ba30331da7c73
|
|
| BLAKE2b-256 |
91cb5a386265cf416cbb7c61419e886b68821a5c1a8ae2c807e16948736581cf
|
Provenance
The following attestation bundles were made for pygfwx-0.1.0.tar.gz:
Publisher:
publish.yml on chiplukes/pygfwx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pygfwx-0.1.0.tar.gz -
Subject digest:
f58eaa8d2b939cf8ac8221d966fd32d0155919a82463a6f90a2a49b16347290e - Sigstore transparency entry: 1683613920
- Sigstore integration time:
-
Permalink:
chiplukes/pygfwx@24a855009ee9844cbe785952777f7a9865859e89 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/chiplukes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@24a855009ee9844cbe785952777f7a9865859e89 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pygfwx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pygfwx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 76.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12d8a6ffa9523127a8105288da322cca3e775b620aa64316b18ed1f7c4af18d9
|
|
| MD5 |
943c52a3b8e25a408654d41348bd4c7f
|
|
| BLAKE2b-256 |
d5cb05e9bac3c65f9d9f4655d2cc5b0f53bc5cbfd03e91d2dd44adb3534e427e
|
Provenance
The following attestation bundles were made for pygfwx-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on chiplukes/pygfwx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pygfwx-0.1.0-py3-none-any.whl -
Subject digest:
12d8a6ffa9523127a8105288da322cca3e775b620aa64316b18ed1f7c4af18d9 - Sigstore transparency entry: 1683614073
- Sigstore integration time:
-
Permalink:
chiplukes/pygfwx@24a855009ee9844cbe785952777f7a9865859e89 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/chiplukes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@24a855009ee9844cbe785952777f7a9865859e89 -
Trigger Event:
push
-
Statement type: