-
-
Save urraka/685d9a6340b26b830d49 to your computer and use it in GitHub Desktop.
#define STB_IMAGE_IMPLEMENTATION | |
#define STB_IMAGE_WRITE_IMPLEMENTATION | |
#define STBI_ONLY_PNG | |
#define STBI_ONLY_JPEG | |
#define STBI_ONLY_BMP | |
#define STBI_ONLY_GIF | |
#include "stb_image.h" | |
#include "stb_image_write.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
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; | |
break; | |
} | |
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)); | |
++(*frames); | |
} | |
STBI_FREE(g.out); | |
if (gr != &head) | |
STBI_FREE(gr); | |
if (*frames > 0) | |
{ | |
*x = g.w; | |
*y = g.h; | |
} | |
result = head.data; | |
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; | |
STBI_FREE(prev->data); | |
if (prev != &head) STBI_FREE(prev); | |
} | |
} | |
} | |
else | |
{ | |
result = stbi__load_main(&s, x, y, frames, 4); | |
*frames = !!result; | |
} | |
fclose(f); | |
return result; | |
} | |
#ifdef __cplusplus | |
} | |
#endif |
Nevermind this was my mistake.
Hey @Platforming-Mayhem, looks like you got it working, good to know!
By the way, that last line you're highlighting looks suspicious to me. Isn't stbi_set_flip_vertically_on_load
a function? My C/C++ is rusty but I think that might be interpreting it as a pointer and just testing that it's not zero, so stbi__vertical_flip_slices
is always called.
@urraka I'm not sure, since I just copied it from one of the stb_load functions
@Platforming-Mayhem nevermind what I said, my bad. The function is stbi_set_flip_vertically_on_load
but you have stbi__vertically_flip_on_load
so it's all good ;D
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 :)
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.
Thanks :)
This was a big help :D
@urraka Sorry to bother you, but do u have any idea as to why this is happening when it loads the next frame?
I also get this exception thrown when loading the next frame on majority of my gifs
Some of them don't get this issue, but those are the ones where the gif is created in a specific program, I think it was Adobe Animate CC.
Animated Gifs created in Krita don't work, Animated Gifs created in Photoshop also don't work.