MCPcopy Create free account
hub / github.com/ARM-software/ComputeLibrary / stbi__gif_load_next

Function stbi__gif_load_next

include/stb/stb_image.h:6778–6950  ·  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

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