Show HN: Header-only GIF decoder in pure C – no malloc, easy to use
46 FerkiHN 40 7/23/2025, 11:36:33 AM
I built a lightweight GIF decoder in pure C, ideal for embedded or performance-critical environments. It’s header-only, zero dynamic memory allocations, and fully platform-independent. Supports both static and animated GIFs, with turbo and safe decoding modes. Works great on microcontrollers, IoT devices, and anything with a framebuffer. Would love feedback or ideas where this could be useful.
Github: https://github.com/Ferki-git-creator/TurboStitchGIF-HeaderOn...
I quite like the flexibility it provides in terms of making “unity builds” very easy, and scaling down quite well to small, single-TU projects with minimal build set ups.
1: https://github.com/nicbarker/clay
Don't you get linker errors when a project includes this header twice in different translation units? If not, please explain how.
I've included many single .h/.c pair libraries before in my projects and given the of simplicity that was never a pain point.
There's this bizarre cultural difference you see between people who learned to program on windows compared to people who learned to program on unix wherein the Windows crowd don't see the value of having an easily reproducible build system because. Usually this results in some combination of needlessly-complicated scripts and checking binary builds of dependencies into version-control.
Requiring you to include a header-file while also defining a specific constant in only one place that turns the header file into a c-file is actually one of the more benign workarounds you see.
As I recall I just added the files to the project, possibly configured a define or five, and then compiled.
Tedious when it's tons of directories, but a breeze with just a pair of files.
That said, I get that this buys you a bit of flexibility in build management.
Naturally people love to complain about Windows.
Also nowadays there is vcpkg and conan.
Even C++, and considering templates, if you want to use external templates optimization you need implementation files, and then there are modules (already working in clang/VC++).
Personally I would probably add a gif.c to my project which does nothing but include the header with the define set, at least if I'm going to need a gif decoder in more than one place. Probably many (most?) projects only need this library in one file anyway, in which case I'd just include it from that file and be done.
edit: Yeah, defining *_IMPLEMENTATION appropriately would address these issues.
The trickiest part wasn’t the encoder; it’s computing the palette from RGB images. To minimize the output file size, I wanted a single palette shared by all frames.
The key piece of research was in that sample code from early 90-s https://www.ece.mcmaster.ca/~xwu/cq.c However, I had to rework it heavily because global variables and C language are too old school, also because FP32 precision is insufficient for the count of input pixels in my use case. 200 FullHD frames contain approximately 400M pixels, FP32 numbers don’t have the precision to accumulate that many of them. And the number is dangerously close to int32 limit, I have also upgraded the integer counters to int64.
Ignoring the compatibility, modern video codecs like h264 or h265 are substantially better than animated GIFs, in terms of both size and quality.
BTW I supported them as well. The only target platform of that software is modern versions of Windows. It only took couple pages of straightforward C++ because the OS includes a functional equivalent of libavcodec and libavformat libraries. Moreover, GPU drivers install and register the components to leverage the codecs implemented by hardware of these GPUs. The high-level API to encode compressed video files from a sequence of frames is MFCreateSinkWriterFromURL function.
I checked the code, it gives me "LLM vibes", too. FWIW, I am not against it. Perhaps the developer was using it here and there. Personally I do not care.
LLM is also similar in that sense, so it produces the same writing. It resists personal touch without being explicitly asked.
ppl who ask qustions like this must have not worked much on codebases w/ nightmarish build setups, libraries like this are so refreshing/easier to work w/
But the core logic, turbo decoding modes, and embedded optimization — that’s all written, tested, and understood by me.
I see AI as a tool, not an author — it helps speed things up, but I still do the thinking.
I submitted a link to a project[0] with similar characteristics a few days ago, before I realized it was probably entirely made by AI. That's what got me wondering this in the first place.
[0] https://news.ycombinator.com/item?id=44642557