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
Instance methods
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).
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.