JKL is a batteries-included Rust crate for compressing, encoding and
packing data that needs to travel fast and decompress even faster — on the
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 with cluster-fit quality.
- Layered entropy coding — stack LZ77 or RLE with ANS for
near-optimal compression ratios while keeping decompression blazingly fast
— simple enough for a GPU compute shader.
- Bit-perfect I/O — the
bits module reads and writes individual bits
so every encoder can squeeze out every last fraction of a byte.
- Jackal Image format — the
jackal::image module ties everything together
into a tiled, mip-mapped, GPU-ready image container.
- Packing and spatial indexing —
max_rects bin-packs rectangles for
atlas generation; z_curve provides Morton-order iteration for
cache-friendly traversal.
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
I/O and serialization
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.