Show HN: Header-only GIF decoder in pure C – no malloc, easy to use

47 points by FerkiHN ↗ HN
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...

11 comments

[ 2.8 ms ] story [ 41.9 ms ] thread
Please share your thoughts.
How is this a header-only? It contains non-static, non-inline functions in the .h file...
It's header-only in the sense that you cut everything that normally goes in the .c file and pasted it in the .h file.

Don't you get linker errors when a project includes this header twice in different translation units? If not, please explain how.

Great question! It works the same way as stb-style libs: you only #define GIF_IMPLEMENTATION in one .c file (one translation unit). In all other files, you just #include "gif.h" without the define. The header uses #ifdef GIF_IMPLEMENTATION to include implementation code only once. So no linker errors — everything compiles cleanly as long as that rule is followed. I’ll make this clearer in the README too, thanks!
Why would you want another gif decoder, in C, in 2025? What's the point of cramming everything in a single file?
There are multiple comments remarking on the header-only implementation, confused regarding linker errors and why this is desirable. Look into stb lib, which in my opinion popularized this idea: https://github.com/nothings/stb?tab=readme-ov-file#how-do-i-...
Thanks! Yes, stb-style header-only libs were definitely an inspiration. I know some devs find the approach confusing, especially with linker errors if *_IMPLEMENTATION isn't handled correctly. I tried to keep it simple and clearly documented, but feedback like this helps improve it.
I once did it for a closed-source CAM/CAE software. We wanted to generate high resolution and decent quality GIFs visualizing a progress of a numerical optimization in a few hundred animation frames. I wasn’t able to find a library which would deliver both reasonable size and good quality, so I made my own.

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.

I wonder if the README.md of this project has been generated by an LLM, or if LLMs output such READMEs mainly because of their training data and thus mistakenly gets identified as LLM-generated README. The two are not mutually exclusive I suppose.

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.

Statistically so far 100% of header only C libraries that require you to define XXX_IMPLEMENTATION are fantastic, so this is probably a good library.