-
-
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 |
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
Nevermind this was my mistake.