|
|
@ -5448,8 +5448,8 @@ typedef struct |
|
|
|
typedef struct |
|
|
|
typedef struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
int w,h; |
|
|
|
int w,h; |
|
|
|
stbi_uc *out; // output buffer (always 4 components)
|
|
|
|
stbi_uc *out, *old_out; // output buffer (always 4 components)
|
|
|
|
int flags, bgindex, ratio, transparent, eflags; |
|
|
|
int flags, bgindex, ratio, transparent, eflags, delay; |
|
|
|
stbi_uc pal[256][4]; |
|
|
|
stbi_uc pal[256][4]; |
|
|
|
stbi_uc lpal[256][4]; |
|
|
|
stbi_uc lpal[256][4]; |
|
|
|
stbi__gif_lzw codes[4096]; |
|
|
|
stbi__gif_lzw codes[4096]; |
|
|
@ -5644,17 +5644,18 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void stbi__fill_gif_background(stbi__gif *g) |
|
|
|
static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int x, y; |
|
|
|
stbi_uc *c = g->pal[g->bgindex]; |
|
|
|
stbi_uc *c = g->pal[g->bgindex]; |
|
|
|
// @OPTIMIZE: write a dword at a time
|
|
|
|
for (y = y0; y < y1; y += 4 * g->w) { |
|
|
|
for (i = 0; i < g->w * g->h * 4; i += 4) { |
|
|
|
for (x = x0; x < x1; x += 4) { |
|
|
|
stbi_uc *p = &g->out[i]; |
|
|
|
stbi_uc *p = &g->out[y + x]; |
|
|
|
p[0] = c[2]; |
|
|
|
p[0] = c[2]; |
|
|
|
p[1] = c[1]; |
|
|
|
p[1] = c[1]; |
|
|
|
p[2] = c[0]; |
|
|
|
p[2] = c[0]; |
|
|
|
p[3] = c[3]; |
|
|
|
p[3] = 0; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -5662,27 +5663,40 @@ static void stbi__fill_gif_background(stbi__gif *g) |
|
|
|
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) |
|
|
|
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
stbi_uc *old_out = 0; |
|
|
|
stbi_uc *prev_out = 0; |
|
|
|
|
|
|
|
|
|
|
|
if (g->out == 0) { |
|
|
|
if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) |
|
|
|
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
|
|
|
return 0; // stbi__g_failure_reason set by stbi__gif_header
|
|
|
|
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); |
|
|
|
|
|
|
|
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
prev_out = g->out; |
|
|
|
stbi__fill_gif_background(g); |
|
|
|
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); |
|
|
|
} else { |
|
|
|
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
// animated-gif-only path
|
|
|
|
|
|
|
|
if (((g->eflags & 0x1C) >> 2) == 3) { |
|
|
|
switch ((g->eflags & 0x1C) >> 2) { |
|
|
|
old_out = g->out; |
|
|
|
case 0: // unspecified (also always used on 1st frame)
|
|
|
|
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); |
|
|
|
stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); |
|
|
|
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
break; |
|
|
|
memcpy(g->out, old_out, g->w*g->h*4); |
|
|
|
case 1: // do not dispose
|
|
|
|
} |
|
|
|
if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); |
|
|
|
|
|
|
|
g->old_out = prev_out; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 2: // dispose to background
|
|
|
|
|
|
|
|
if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); |
|
|
|
|
|
|
|
stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 3: // dispose to previous
|
|
|
|
|
|
|
|
if (g->old_out) { |
|
|
|
|
|
|
|
for (i = g->start_y; i < g->max_y; i += 4 * g->w) |
|
|
|
|
|
|
|
memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
switch (stbi__get8(s)) { |
|
|
|
switch (stbi__get8(s)) { |
|
|
|
case 0x2C: /* Image Descriptor */ |
|
|
|
case 0x2C: /* Image Descriptor */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
int prev_trans = -1; |
|
|
|
stbi__int32 x, y, w, h; |
|
|
|
stbi__int32 x, y, w, h; |
|
|
|
stbi_uc *o; |
|
|
|
stbi_uc *o; |
|
|
|
|
|
|
|
|
|
|
@ -5715,10 +5729,10 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); |
|
|
|
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); |
|
|
|
g->color_table = (stbi_uc *) g->lpal; |
|
|
|
g->color_table = (stbi_uc *) g->lpal; |
|
|
|
} else if (g->flags & 0x80) { |
|
|
|
} else if (g->flags & 0x80) { |
|
|
|
for (i=0; i < 256; ++i) // @OPTIMIZE: stbi__jpeg_reset only the previous transparent
|
|
|
|
if (g->transparent >= 0 && (g->eflags & 0x01)) { |
|
|
|
g->pal[i][3] = 255; |
|
|
|
prev_trans = g->pal[g->transparent][3]; |
|
|
|
if (g->transparent >= 0 && (g->eflags & 0x01)) |
|
|
|
|
|
|
|
g->pal[g->transparent][3] = 0; |
|
|
|
g->pal[g->transparent][3] = 0; |
|
|
|
|
|
|
|
} |
|
|
|
g->color_table = (stbi_uc *) g->pal; |
|
|
|
g->color_table = (stbi_uc *) g->pal; |
|
|
|
} else |
|
|
|
} else |
|
|
|
return stbi__errpuc("missing color table", "Corrupt GIF"); |
|
|
|
return stbi__errpuc("missing color table", "Corrupt GIF"); |
|
|
@ -5726,8 +5740,9 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
o = stbi__process_gif_raster(s, g); |
|
|
|
o = stbi__process_gif_raster(s, g); |
|
|
|
if (o == NULL) return NULL; |
|
|
|
if (o == NULL) return NULL; |
|
|
|
|
|
|
|
|
|
|
|
if (req_comp && req_comp != 4) |
|
|
|
if (prev_trans != -1) |
|
|
|
o = stbi__convert_format(o, 4, req_comp, g->w, g->h); |
|
|
|
g->pal[g->transparent][3] = prev_trans; |
|
|
|
|
|
|
|
|
|
|
|
return o; |
|
|
|
return o; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -5738,7 +5753,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
len = stbi__get8(s); |
|
|
|
len = stbi__get8(s); |
|
|
|
if (len == 4) { |
|
|
|
if (len == 4) { |
|
|
|
g->eflags = stbi__get8(s); |
|
|
|
g->eflags = stbi__get8(s); |
|
|
|
stbi__get16le(s); // delay
|
|
|
|
g->delay = stbi__get16le(s); |
|
|
|
g->transparent = stbi__get8(s); |
|
|
|
g->transparent = stbi__get8(s); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
stbi__skip(s, len); |
|
|
|
stbi__skip(s, len); |
|
|
@ -5770,7 +5785,11 @@ static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
if (u) { |
|
|
|
if (u) { |
|
|
|
*x = g.w; |
|
|
|
*x = g.w; |
|
|
|
*y = g.h; |
|
|
|
*y = g.h; |
|
|
|
|
|
|
|
if (req_comp && req_comp != 4) |
|
|
|
|
|
|
|
u = stbi__convert_format(u, 4, req_comp, g.w, g.h); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else if (g.out) |
|
|
|
|
|
|
|
STBI_FREE(g.out); |
|
|
|
|
|
|
|
|
|
|
|
return u; |
|
|
|
return u; |
|
|
|
} |
|
|
|
} |
|
|
|