Skip to content

Instantly share code, notes, and snippets.

Last active January 21, 2024 00:20
Show Gist options
  • Save urraka/685d9a6340b26b830d49 to your computer and use it in GitHub Desktop.
Save urraka/685d9a6340b26b830d49 to your computer and use it in GitHub Desktop.
#include "stb_image.h"
#include "stb_image_write.h"
#ifdef __cplusplus
extern "C" {
typedef struct gif_result_t {
int delay;
unsigned char *data;
struct gif_result_t *next;
} gif_result;
STBIDEF unsigned char *stbi_xload(char const *filename, int *x, int *y, int *frames)
FILE *f;
stbi__context s;
unsigned char *result = 0;
if (!(f = stbi__fopen(filename, "rb")))
return stbi__errpuc("can't fopen", "Unable to open file");
stbi__start_file(&s, f);
if (stbi__gif_test(&s))
int c;
stbi__gif g;
gif_result head;
gif_result *prev = 0, *gr = &head;
memset(&g, 0, sizeof(g));
memset(&head, 0, sizeof(head));
*frames = 0;
while (gr->data = stbi__gif_load_next(&s, &g, &c, 4))
if (gr->data == (unsigned char*)&s)
gr->data = 0;
if (prev) prev->next = gr;
gr->delay = g.delay;
prev = gr;
gr = (gif_result*) stbi__malloc(sizeof(gif_result));
memset(gr, 0, sizeof(gif_result));
if (gr != &head)
if (*frames > 0)
*x = g.w;
*y = g.h;
result =;
if (*frames > 1)
unsigned int size = 4 * g.w * g.h;
unsigned char *p = 0;
result = (unsigned char*)stbi__malloc(*frames * (size + 2));
gr = &head;
p = result;
while (gr)
prev = gr;
memcpy(p, gr->data, size);
p += size;
*p++ = gr->delay & 0xFF;
*p++ = (gr->delay & 0xFF00) >> 8;
gr = gr->next;
if (prev != &head) STBI_FREE(prev);
result = stbi__load_main(&s, x, y, frames, 4);
*frames = !!result;
return result;
#ifdef __cplusplus
Copy link

Hi @urraka,
I've been using this code for a while now but recently I found out that it takes up a lot of memory. Is this normal and is there anyway to decrease the amount of memory that is used?
Thanks :)

Copy link

urraka commented Jan 4, 2024

Hi @Platforming-Mayhem. The way this works is the easy way out: load every frame into memory in RGBA format. If you have big images with many frames it will take a lot of memory (width * height * 4 * number of frames bytes). I suppose, in theory, one could load the compressed file into memory and buffer a few frames at a time (sort of like video preloading)... but that would need a lot more work.

Copy link

Thanks :)
This was a big help :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment