Project Nayuki


Tiny PNG Output

Tiny PNG Output is a small standalone library, available in C and C++, which takes RGB8.8.8 pixels and writes a PNG file. The image data can be fed to the writer one pixel at a time, a row at a time, or the complete image at once. Licensed as LGPLv3+.

In ~260 lines of C++ code or ~260 lines of C code, this library implements these key components: PNG header writer, PNG chunk writer, DEFLATE uncompressed encoder, CRC-32, Adler-32. The library is entirely self-contained, avoiding the typical PNG tools like libpng and zlib.

The code has been tested on x86 and x86-64, and is expected to work on other platforms as well. It should work on 32-bit embedded microcontrollers but might not work on 8-bit CPUs. Applications for this library include writing PNG files to disk, and generating PNG files on the fly to write to a network socket (e.g. HTTP connection).

The algorithms are carefully designed to behave correctly for all inputs that are below the image size limit of ~700 megapixels. Specifically: Let m = (3 × width + 1) × height. Let n = m + ceil(m / 65535) × 5 + 6. The algorithm requires width and height to satisfy n < 231.

Remember, this library optimizes for simplicity, low line count, absolute correctness, and platform portability. It does not optimize for having many features (such as palette, transparency, interlacing, gamma, etc.) or for file size (in fact it writes uncompressed PNG files). The files generated by Tiny PNG Output are always correct, but inefficient in storage space.

Source code

Complete package: TinyPngOut-c.zip / TinyPngOut-cpp.zip

Contains all the source files listed below for one language, plus the license text files.

Core library: TinyPngOut.h / TinyPngOut.hpp

The header code file. The C version contains a data structure, enum of status codes, and public function prototypes. The C++ version contains a single class with a few members. Both contain documentation for the important public functions.

Core library: TinyPngOut.c / TinyPngOut.cpp

The source code file containing the implementations of the functions/methods (both public and private ones).

Sample application: SimplePng.c / SimplePng.cpp

A simple demo program that writes a hard-coded 3×2 image, which shows the primary and secondary RGB colors.

To compile and run: cc -o SimplePng TinyPngOut.c SimplePng.c && ./SimplePng

Sample application: MandelbrotPng.c / MandelbrotPng.cpp

A demo program that computes an image of the Mandelbrot set on the fly, buffering and writing one line at a time. (This shows that it’s not necessary to produce the whole image before starting to write the output PNG file.)

To compile and run: cc -o MandelbrotPng TinyPngOut.c MandelbrotPng.c -lm && ./MandelbrotPng

Test application: TestSplitPng.c / TestSplitPng.cpp

A runnable self-test program that splits pixel data into different chunk sizes for writing and compares the output PNG files’ data for equality.

The C code requires C99 and cannot be compiled in C++ mode. The C++ code requires C++11.

License: GNU Lesser General Public License v3.0+