PNG handler (pure Caspian) GitHub issue

vibecode
{"vibecode": {
    "doc": "png",
    "role": "brainstorm for a pure-Caspian PNG encoder/decoder, intended to ship as a Puck service at puck.uno; foundation for downstream image work including QR codes",
    "status": "brainstorm — no implementation yet",
    "reference_impl": "https://github.com/wvanbergen/chunky_png (pure-Ruby PNG)",
    "key_concepts": ["pure_caspian", "no_native_deps", "png_encoder_decoder",
        "drawing_primitives", "puck_uno_service"]
}}

Status: brainstorm. A pure-Caspian PNG handler available as a Puck library at puck.uno/png. Downstream applications (QR codes, badges, small charts, anything that wants to emit a PNG without pulling in libpng) layer on top.


Why pure-Caspian GitHub issue


Sketch GitHub issue

Three layers:

  1. Color. A separate library at puck.uno/color that provides the color objects PNG (and other image consumers) work with.
  2. PNG bytes ↔ Caspian image object. Encode and decode the PNG container format — signature, IHDR, IDAT (deflate-compressed pixel data), IEND, plus the optional chunks (palette, transparency, gamma). A puck.uno/png class with encode($pixels) / decode($bytes).
  3. Drawing primitives. Set/get pixel, draw rectangle, fill, line. Enough to compose simple images (QR matrices, badges, sparkline strips) without needing a full graphics library.

A QR encoder would sit on top as a separate Puck object that emits a 2D bit matrix and hands it to the drawing primitives.


Open questions GitHub issue


Reference GitHub issue

wvanbergen/chunky_png — pure-Ruby PNG. Read for chunk-handling patterns, encode/decode API shape, color-model choices, and how it handles deflate via Ruby's stdlib zlib (a dependency we won't have an exact analog to).

© 2026 Puck.uno