MCPcopy Create free account
hub / github.com/OpenFodder/openfodder / stbi__gif_load_next

Function stbi__gif_load_next

Source/Utils/stb_image.h:6775–6947  ·  view source on GitHub ↗

this function is designed to support animated gifs, although stb_image doesn't support it two back is the image from two frames ago, used for a very specific disposal format

Source from the content-addressed store, hash-verified

6773// this function is designed to support animated gifs, although stb_image doesn't support it
6774// two back is the image from two frames ago, used for a very specific disposal format
6775static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
6776{
6777 int dispose;
6778 int first_frame;
6779 int pi;
6780 int pcount;
6781 STBI_NOTUSED(req_comp);
6782
6783 // on first frame, any non-written pixels get the background colour (non-transparent)
6784 first_frame = 0;
6785 if (g->out == 0) {
6786 if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
6787 if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
6788 return stbi__errpuc("too large", "GIF image is too large");
6789 pcount = g->w * g->h;
6790 g->out = (stbi_uc *) stbi__malloc(4 * pcount);
6791 g->background = (stbi_uc *) stbi__malloc(4 * pcount);
6792 g->history = (stbi_uc *) stbi__malloc(pcount);
6793 if (!g->out || !g->background || !g->history)
6794 return stbi__errpuc("outofmem", "Out of memory");
6795
6796 // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
6797 // background colour is only used for pixels that are not rendered first frame, after that "background"
6798 // color refers to the color that was there the previous frame.
6799 memset(g->out, 0x00, 4 * pcount);
6800 memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
6801 memset(g->history, 0x00, pcount); // pixels that were affected previous frame
6802 first_frame = 1;
6803 } else {
6804 // second frame - how do we dispose of the previous one?
6805 dispose = (g->eflags & 0x1C) >> 2;
6806 pcount = g->w * g->h;
6807
6808 if ((dispose == 3) && (two_back == 0)) {
6809 dispose = 2; // if I don't have an image to revert back to, default to the old background
6810 }
6811
6812 if (dispose == 3) { // use previous graphic
6813 for (pi = 0; pi < pcount; ++pi) {
6814 if (g->history[pi]) {
6815 memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
6816 }
6817 }
6818 } else if (dispose == 2) {
6819 // restore what was changed last frame to background before that frame;
6820 for (pi = 0; pi < pcount; ++pi) {
6821 if (g->history[pi]) {
6822 memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
6823 }
6824 }
6825 } else {
6826 // This is a non-disposal case eithe way, so just
6827 // leave the pixels as is, and they will become the new background
6828 // 1: do not dispose
6829 // 0: not specified.
6830 }
6831
6832 // background is what out is after the undoing of the previou frame;

Callers 2

stbi__load_gif_mainFunction · 0.85
stbi__gif_loadFunction · 0.85

Calls 8

stbi__gif_headerFunction · 0.85
stbi__mad3sizes_validFunction · 0.85
stbi__mallocFunction · 0.85
stbi__get8Function · 0.85
stbi__get16leFunction · 0.85
stbi__process_gif_rasterFunction · 0.85
stbi__skipFunction · 0.85

Tested by

no test coverage detected