:INFO [align:center] stipple A single-file C library for 1-bit dithering. Five algorithms, no dependencies, no allocation you did not ask for, about 600 lines. Four of those five algorithms were written by somebody other than the author. This page is about them, because in a library this small you are not depending on a project. You are depending on five people. | :GALLERY [displaystyle:grid] | :INFO Those Are Real Outputs Every image above came out of the library, run on the generated source in the first tile. Nothing was retouched and nothing was chosen for flattery. The Atkinson sample loses detail in the bright half and that is left in, because the whole reason to ship five algorithms is that they fail differently and you need to see how before you pick one. | :INFO Ren Okabe, who wrote the file that became this one Started it as a 40 line threshold function inside a Game Boy emulator in 2017, pulled it out when a second project needed it, and has since written almost none of the algorithms in it. Owns the API, the single-header build, and the decision that the library never allocates. Reviews everything. Describes the role as mostly saying no. | :INFO.half Dilnoza Rakhimova Wrote the Floyd-Steinberg implementation and then rewrote it twice. The second rewrite removed the serpentine option after demonstrating in a 900 word issue comment that it was producing worse results than the plain scan for every input anyone could produce. | :INFO.half Marcus Feld Contributed Atkinson in 2019 and the ordered Bayer matrices in 2020. Also wrote the only documentation anyone reads: a comment block above each kernel explaining what the algorithm is for rather than what it does. | :INFO.half Sofia Almeida Found and fixed the off-by-one that misaligned every ordered dither by one pixel on images whose width was not a multiple of four. It had been there for three years and was visible in every tiled output, which is how it was finally spotted. | :INFO.half Tobi Adeyemi Ported the whole library to fixed-point arithmetic so it runs on hardware without an FPU, and did it without changing a single output byte on the floating-point path. That constraint was self-imposed and it took nine months. | :STATS | :QUOTE [quotetype:plain, subtitle:Ren Okabe] I wrote the first forty lines and the word no about four hundred times. Everything anyone actually uses this library for was written by somebody else. | :INFO Why Naming People Matters Here Six hundred lines is small enough that every algorithm has exactly one author and everyone knows who it is. When the fixed-point path misbehaves on some embedded target, the useful information is not that stipple has a bug. It is that Tobi wrote that path, deliberately, under a constraint, and the issue should say so. Credit and accountability are the same list read in two directions. | :CHECKLIST Getting it into your build [ ] Copy stipple.h into your source tree. That is the install [ ] Define STIPPLE_IMPLEMENTATION in exactly one translation unit before including it [ ] C99 or newer. No build system, no package manager, nothing to configure [ ] Define STIPPLE_FIXED_POINT if your target has no FPU [ ] Pick an algorithm by looking at the samples above rather than by name | :LINK https://github.com/renokabe/stipple Source and issue tracker