File Format & Storage
How OpenGPEX handles image import/export across 10+ formats with full color fidelity, and how it stores project data using content-addressable immutable assets.
Storage: Content-Addressable System (CAS)
Every image asset in the editor is stored by its SHA-256 hash in IndexedDB:
Import image → SHA-256 hash → Store as {hash: Blob} in IndexedDB
│
▼
Layer references hash (metadata only)
Duplicate imports → same hash → zero extra storage
Design benefits:
- Deduplication — Identical images share a single blob regardless of how many layers reference them
- Immutability — Original pixels are never modified; edits create new derivative assets
- Non-destructive editing — Undo can always restore to any previous asset state
- Garbage collection — Unreferenced assets are periodically cleaned by the Asset Sentinel
16-bit Color Fidelity Pipeline
OpenGPEX preserves full color depth from import:
``` Import 16-bit TIFF/PNG/RAW ↓ Store original source via frame.assetId (full precision blob, skipTiling) ↓ Generate 8-bit display version for Canvas rendering ↓ Edit using 8-bit preview (real-time, native refresh rate) ↓ Export: currently 8-bit composited output (16-bit compositing planned via WebGPU) ```
The original high-precision source data is never discarded during editing — it is stored as a regular asset referenced by frame.assetId and preserved through the full project lifecycle (GC-protected, dehydrated into .gpex files, etc.).
Future: When WebGPU enables native float16/float32 compositing, the 16-bit source blob will be consumed directly by the GPU compositor for full-precision export — without the complexity of a separate vips-based composite pipeline.
Format Support
Import (10+ formats)
| Category | Formats | Technology |
|---|---|---|
| Standard web | JPEG, PNG, WebP, AVIF, BMP, GIF | Browser-native decode |
| Professional | TIFF (16-bit, CMYK, BigTIFF) | wasm-vips in Worker |
| Camera RAW | CR2, NEF, ARW, DNG | libraw-wasm in Worker |
| Vector | SVG, EPS | resvg-wasm / Ghostscript in Worker |
Export
| Format | Precision | Technology |
|---|---|---|
| JPEG, PNG, WebP, BMP | 8-bit | Browser-native encode |
| AVIF | 8-bit | wasm-vips (heifsave + libheif/libaom) |
| PNG | 16-bit | wasm-vips |
| TIFF | 8/16/32-bit | wasm-vips (LZW/ZIP/JPEG compression) |
| GIF | 8-bit (animated) | gifenc in Worker |
Metadata Round-Trip
Full preservation of image metadata across the pipeline:
| Data | Supported Formats | Behavior |
|---|---|---|
| ICC Color Profiles | JPEG, PNG, TIFF, WebP, HEIC | Extract on import, inject on export |
| EXIF | JPEG, WebP, TIFF | Preserved through edit cycle |
| DPI/Resolution | JPEG, PNG, TIFF, BMP | Dual-layer: frame-level + per-layer record |
| PNG chunks | PNG | 9 chunk types parsed (pHYs, iCCP, tEXt, gAMA, etc.) |
.gpex Project Format
The native save format is a binary container that bundles:
- Project manifest (frames, layers, state)
- All referenced image assets (by CAS hash)
- Preview thumbnail for cloud file listing
This container is what gets uploaded to GPEX-Cloud for cloud persistence.
GIF Animation
Multi-frame GIF files are decomposed into individual layers on import (linked via gifSequenceId), and reassembled into animated GIF on export — preserving frame timing and loop metadata.
Last updated: 2026-07-30