Skip to content

Repository files navigation

kiyo

Pure Zig JPEG encoder/decoder. Zero dependencies.

zig build -Doptimize=ReleaseFast

Quick Start

CLI

zig build run -- encode input.ppm output.jpg --quality 85
zig build run -- encode input.ppm output.jpg --preset web
zig build run -- decode input.jpg output.ppm

Input/output uses PPM (P6) format. Convert with ImageMagick or ffmpeg:

convert photo.png photo.ppm    # ImageMagick
ffmpeg -i photo.png photo.ppm  # ffmpeg

Zig API

const kiyo = @import("kiyo");

const jpeg = try kiyo.encodeJPEG(allocator, &image_data, .{
    .quality = 75,
    .fast_mode = false,
});
defer jpeg.deinit(allocator);

const image = try kiyo.decodeJPEG(allocator, jpeg.buffer, .{});
defer image.deinit(allocator);

Project Layout

src/
    root.zig                    public API
    main.zig                    CLI entry point
    types.zig                   pixel and block types
    encoder.zig                 JPEG encoder
    decoder.zig                 JPEG decoder
    io.zig                      file I/O
    presets.zig                 quality presets

    core/
        color_space.zig         RGB <-> YCbCr
        block_processor.zig     8x8 block splitting
        dct.zig                 DCT / IDCT / fast DCT
        quantization.zig        quantize / dequantize
        zigzag.zig              zigzag reorder + RLE

    encoding/
        bitstream.zig           bit-level writer
        huffman.zig             Huffman tables + encode
        jpeg_writer.zig         JPEG marker assembly

    integration_tests.zig       227 tests

test/
    benchmark.zig               benchmarks
    bench_pro.zig               advanced benchmarks
    verify.zig                  end-to-end validation
    fuzz_encoder.zig            encoder fuzz testing
    fuzz_decoder.zig            decoder fuzz testing

Encode

    RGBA pixels
        |
        v
    +--------------+
    | RGB to YCbCr |   256-entry LUT, no f64 math
    +--------------+
        |
        v
    +--------------+
    | Block Split  |   image into 8x8 blocks
    +--------------+
        |
        v
    +--------------+
    |    DCT       |   standard or fast (17x)
    +--------------+
        |
        v
    +--------------+
    |  Quantize    |   multiply by 1/q (no division)
    +--------------+
        |
        v
    +--------------+
    | Zigzag + RLE |   i16 path (no f64)
    +--------------+
        |
        v
    +--------------+
    |   Huffman    |   precomputed tables
    +--------------+
        |
        v
    +--------------+
    | JPEG Write   |   markers + stuffed data
    +--------------+
        |
        v
    .jpg file

Decode

    .jpg file
        |
        v
    +--------------+
    | Parse Header |   SOI, DQT, SOF0, DHT, SOS
    +--------------+
        |
        v
    +--------------+
    | Huffman Dec  |   bit reader + lookup
    +--------------+
        |
        v
    +--------------+
    | Dequantize   |   scale back
    +--------------+
        |
        v
    +--------------+
    |    IDCT      |   frequency to spatial
    +--------------+
        |
        v
    +--------------+
    | YCbCr to RGB |   color reconversion
    +--------------+
        |
        v
    RGBA pixels

Chroma Subsampling

  4:4:4                      4:2:0

  +------+------+------+------+      +------+------+------+------+
  |  Y   |  Y   |  Y   |  Y   |      |  Y   |  Y   |  Y   |  Y   |
  +------+------+------+------+      |  Y   |  Y   |  Y   |  Y   |
  |  Y   |  Y   |  Y   |  Y   |      +------+------+------+------+
  +------+------+------+------+      |  Y   |  Y   |  Y   |  Y   |
  |  Y   |  Y   |  Y   |  Y   |      |  Y   |  Y   |  Y   |  Y   |
  +------+------+------+------+      +------+------+------+------+

  Cb = 1 block per Y block            Cb = 1 block per 4 Y blocks
  Cr = 1 block per Y block            Cr = 1 block per 4 Y blocks

Benchmarks

DCT standard       2.8 us/block
DCT fast           0.2 us/block       17.2x faster
Quantize           0.1 us/block
Color convert      1.5 ms / 256x256
Full encode        19 ms / 256x256    3.3 Mpixels/s

Presets

name         quality   fast
---------------------------
thumbnail      30      yes
web            60      no
balanced       75      no
high           90      no
maximum       100      no

Testing

zig build test       unit tests
zig build bench      benchmarks
zig build verify     end-to-end validation
zig build            build CLI
zig build run -- help    CLI usage

License

MIT

About

rawdog jpeg-encoder , demonstrating the full compression pipeline including DCT, quantization, and Huffman coding.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages