4 releases (2 breaking)
Uses new Rust 2024
| new 0.2.1 | Mar 5, 2026 |
|---|---|
| 0.2.0 | Mar 5, 2026 |
| 0.1.0 | Mar 4, 2026 |
| 0.0.0 | Oct 23, 2024 |
#293 in Algorithms
510KB
12K
SLoC
JKL is a batteries-included Rust crate for compressing data for reduced footprint and blazing fast decompression on CPU or directly on the GPU. If you ship textures, sprite atlases, tile maps, or any bulk binary payload that must be ready the instant it hits VRAM, JKL was built for you.
Feature highlights
- GPU-oriented block texture codecs - encode and decode BC1 through BC5 blocks. Cluster-fit algorithm finds endpoints for best perceptual quality.
- Layered entropy coding - Not all data is equally compressible, stack loseless encoders such as rANS, LZ77 or simple RLE. Find the optimal combination balancing compression ratio and decompression speed.
- Bit I/O - the
bitsmodule provides bit-level IO wrapper forstd::io::Readandstd::io::Write. Bitstreams are used extensively in JKL for variable-length coding of symbols. - Jackal Image format - the
jackal::imagemodule provides API for working with Jackal Image (JKLI) file format. Write entire images and read them back as tiles, supporting parallelized decompression. - Atlas -
max_rectspacks rectangles for atlas generation
Quick orientation - "how do I …?"
| I want to … | Start here |
|---|---|
| Compress a texture to BC1–BC5 | bc1::Block::encode, bc2::Block::encode, …bc5::Block::encode |
| Decompress a BC block | bc1::Block::decode, bc2::Block::decode, …bc5::Block::decode |
| Write / read a complete Jackal Image file | jackal::image::write_image, jackal::image::JackalReader |
| Entropy-code a symbol stream | Build an ans::Context, then use ans::Encoder / ans::Decoder |
| Run-length encode an iterator | rle::rle, rle::rle_power_of_two, or rle::rle_with_cfg |
| LZ77-compress a value stream | lz77::Encoder → lz77::Token stream → lz77::Decoder |
| LZ78-compress a value stream | lz78::Encoder → lz78::Token stream → lz78::Decoder |
| Encode small unsigned ints compactly | vle::encode / vle::decode (Elias delta), or wrap with vle::Vle |
| Map signed ints for better compression | zigzaq::ZigZag::zigzag before VLE encoding |
| Read / write individual bits | bits::WriteBits, bits::ReadBits, or the bits::write_bits_scope helper |
| Bin-pack rectangles into an atlas | max_rects::MaximalRectangles::new then insert in a loop |
| Work with 2D pixel buffers | image::Image2DRef / image::Image2DMut |
| Use vector math or pixel types | math::Vec3, math::Rgb565, math::Rgba32F, etc. |
Module overview
Compression
| Module | Purpose |
|---|---|
ans |
Asymmetric Numeral Systems (ANS) entropy coder |
rle |
Run-length encoding with configurable max length and power-of-two mode |
vle |
Variable-length Elias delta coding for unsigned integers |
lz77 |
LZ77 sliding-window compressor / decompressor |
lz78 |
LZ78 dictionary compressor (GPU-friendly variant) |
zigzaq |
Zigzag signed ↔ unsigned mapping for better VLE compression |
Block-texture codecs
| Module | Format | Block size | Channels |
|---|---|---|---|
bc1 |
BC1 / DXT1 | 8 bytes | RGB + 1-bit A |
bc2 |
BC2 / DXT3 | 16 bytes | RGBA (4-bit A) |
bc3 |
BC3 / DXT5 | 16 bytes | RGBA (interp A) |
bc4 |
BC4 / RGTC1 | 8 bytes | R |
bc5 |
BC5 / RGTC2 | 16 bytes | RG |
cluster_fit |
Shared quantizer for above | – | – |
Image and math
| Module | Purpose |
|---|---|
image |
Non-owning 2D / 3D image views (Image2DRef, Image2DMut, …) |
math |
Vectors (Vec2–Vec4), pixel types, Rect, PCA, bit-interleaving |
I/O and serialization
| Module | Purpose |
|---|---|
bits |
Bit-level buffered reader / writer over byte streams |
encode |
FixedCode and VarCode serialization traits |
Packing and spatial
| Module | Purpose |
|---|---|
max_rects |
2D bin packing (maximal-rectangles algorithm) for atlas generation |
z_curve |
Z-order / Morton curve coordinate iteration |
File formats
| Module | Purpose |
|---|---|
jackal::image |
Tiled, GPU-decompressible image container format |
License
See Cargo.toml for license information.
Dependencies
~1MB
~14K SLoC