module

Quartz::PNG

Minimal 1-bit grayscale PNG encoder. Stdlib-only (Compress::Zlib + CRC32). Input is the same MSB-first, row-major, 1bpp packing as PBM P4 — 16 bytes per row, 64 rows for a Flipper screen. PNG treats 0=black, PBM treats 1=black, so we invert on the way out.

Constants

SIG = Bytes[137, 80, 78, 71, 13, 10, 26, 10]
SIGNATURE = Bytes[137, 80, 78, 71, 13, 10, 26, 10]

Instance methods

decode(bytes : Bytes) : DecodedImage
Source
decode_icon(path : String) : Tuple(Int32, Int32, Bytes)

Decode a Flipper app icon PNG and return the 1bpp packed bytes the firmware loader expects in manifest.icon[]. Pixels are MSB-first within each byte, row-major, padded to a whole byte per row. A pixel is "on" when alpha >= 128 and luminance < 128 (matches ufbt's icon pipeline).

Source
encode_1bit(pbm_packed : Bytes, width : Int32, height : Int32) : Bytes
Source
encode_icon_heatshrink(path : String) : Bytes | Nil

Encode a Flipper app icon PNG into the heatshrink2-compressed bytes the FAP manifest icon[] field expects.

Mirrors ufbt's icon.py pipeline: PNG → 1bpp → invert → XBM (LSB-first, drawing pixels = 1-bit) → heatshrink -e -w 8 -l 4

Requires heatshrink on PATH (apt install heatshrink). Returns nil when heatshrink is unavailable or compression fails.

Source

Nested types