#pragma once #include #include #include // A PNG of the screen, written a row at a time with almost no memory (issue #67, Q209): 8-bit // indexed colour with the 256 colours of RGB332 as its palette, and the pixels stored, not // compressed (a "stored" deflate block), so there is nothing to compress with and nothing to buffer. // One block holds at most 65,535 bytes: enough for the 240 x 135 screen (32,535 with its row bytes). namespace roro::png { uint32_t crc32(uint32_t crc, const uint8_t* data, size_t len); // running; start from 0 uint32_t adler32(uint32_t adler, const uint8_t* data, size_t len); // running; start from 1 class Rgb332Writer { public: using Sink = std::function; // false: writing failed Rgb332Writer(int width, int height, Sink sink) : w_(width), h_(height), sink_(std::move(sink)) {} // The file's size, known before a byte is written. static size_t fileSize(int width, int height); bool begin(); // false: too big for one block, or the sink refused bool row(const uint8_t* pixels); // `width` bytes, RRRGGGBB each bool end(); private: bool put(const uint8_t* data, size_t len, bool inIdat); bool put32(uint32_t value, bool inIdat); int w_, h_, rows_ = 0; Sink sink_; uint32_t crc_ = 0, adler_ = 1; }; } // namespace roro::png