summaryrefslogtreecommitdiff
path: root/libs/raylib/src/external/stb_image.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/raylib/src/external/stb_image.h')
-rw-r--r--libs/raylib/src/external/stb_image.h267
1 files changed, 182 insertions, 85 deletions
diff --git a/libs/raylib/src/external/stb_image.h b/libs/raylib/src/external/stb_image.h
index 196dfd5..2857f05 100644
--- a/libs/raylib/src/external/stb_image.h
+++ b/libs/raylib/src/external/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.23 - public domain image loader - http://nothings.org/stb
+/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,10 +48,12 @@ LICENSE
RECENT REVISION HISTORY:
+ 2.25 (2020-02-02) fix warnings
+ 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
2.23 (2019-08-11) fix clang static analysis warning
2.22 (2019-03-04) gif fixes, fix warnings
2.21 (2019-02-25) fix typo in comment
- 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
+ 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
2.19 (2018-02-11) fix warning
2.18 (2018-01-30) fix warnings
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
@@ -105,7 +107,8 @@ RECENT REVISION HISTORY:
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
- Blazej Dariusz Roszkowski github:Michaelangel007
+ Brad Weinberger Matvey Cherevko github:Michaelangel007
+ Blazej Dariusz Roszkowski Alexander Veselov
*/
#ifndef STBI_INCLUDE_STB_IMAGE_H
@@ -434,7 +437,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f);
// get a VERY brief reason for failure
-// NOT THREADSAFE
+// on most compilers (and ALL modern mainstream compilers) this is threadsafe
STBIDEF const char *stbi_failure_reason (void);
// free the loaded image -- this is just free()
@@ -467,6 +470,11 @@ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
// flip the image vertically, so the first pixel in the output array is the bottom left
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
+// as above, but only applies to images loaded on the thread that calls the function
+// this function is only available if your compiler supports thread-local variables;
+// calling it will fail to link if your compiler doesn't
+STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
+
// ZLIB client - used by PNG, available for other purposes
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
@@ -563,6 +571,17 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#define stbi_inline __forceinline
#endif
+#ifndef STBI_NO_THREAD_LOCALS
+ #if defined(__cplusplus) && __cplusplus >= 201103L
+ #define STBI_THREAD_LOCAL thread_local
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+ #define STBI_THREAD_LOCAL _Thread_local
+ #elif defined(__GNUC__)
+ #define STBI_THREAD_LOCAL __thread
+ #elif defined(_MSC_VER)
+ #define STBI_THREAD_LOCAL __declspec(thread)
+#endif
+#endif
#ifdef _MSC_VER
typedef unsigned short stbi__uint16;
@@ -873,19 +892,24 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
#endif
-// this is not threadsafe
-static const char *stbi__g_failure_reason;
+static
+#ifdef STBI_THREAD_LOCAL
+STBI_THREAD_LOCAL
+#endif
+const char *stbi__g_failure_reason;
STBIDEF const char *stbi_failure_reason(void)
{
return stbi__g_failure_reason;
}
+#ifndef STBI_NO_FAILURE_STRINGS
static int stbi__err(const char *str)
{
stbi__g_failure_reason = str;
return 0;
}
+#endif
static void *stbi__malloc(size_t size)
{
@@ -924,11 +948,13 @@ static int stbi__mul2sizes_valid(int a, int b)
return a <= INT_MAX/b;
}
+#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
static int stbi__mad2sizes_valid(int a, int b, int add)
{
return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
}
+#endif
// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
static int stbi__mad3sizes_valid(int a, int b, int c, int add)
@@ -946,12 +972,14 @@ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
}
#endif
+#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
// mallocs with size overflow checking
static void *stbi__malloc_mad2(int a, int b, int add)
{
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
return stbi__malloc(a*b + add);
}
+#endif
static void *stbi__malloc_mad3(int a, int b, int c, int add)
{
@@ -995,13 +1023,29 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
#endif
-static int stbi__vertically_flip_on_load = 0;
+static int stbi__vertically_flip_on_load_global = 0;
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
{
- stbi__vertically_flip_on_load = flag_true_if_should_flip;
+ stbi__vertically_flip_on_load_global = flag_true_if_should_flip;
}
+#ifndef STBI_THREAD_LOCAL
+#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global
+#else
+static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set;
+
+STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip)
+{
+ stbi__vertically_flip_on_load_local = flag_true_if_should_flip;
+ stbi__vertically_flip_on_load_set = 1;
+}
+
+#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \
+ ? stbi__vertically_flip_on_load_local \
+ : stbi__vertically_flip_on_load_global)
+#endif // STBI_THREAD_LOCAL
+
static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
{
memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
@@ -1023,6 +1067,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
#endif
#ifndef STBI_NO_PSD
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
+ #else
+ STBI_NOTUSED(bpc);
#endif
#ifndef STBI_NO_PIC
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
@@ -1111,8 +1157,8 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt
stbi_uc *bytes = (stbi_uc *)image;
for (slice = 0; slice < z; ++slice) {
- stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
- bytes += slice_size;
+ stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
+ bytes += slice_size;
}
}
#endif
@@ -1198,7 +1244,7 @@ static FILE *stbi__fopen(char const *filename, char const *mode)
wchar_t wFilename[1024];
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
return 0;
-
+
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
return 0;
@@ -1300,15 +1346,15 @@ STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *u
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
{
unsigned char *result;
- stbi__context s;
- stbi__start_mem(&s,buffer,len);
-
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+
result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
if (stbi__vertically_flip_on_load) {
- stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
+ stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
}
- return result;
+ return result;
}
#endif
@@ -1477,6 +1523,9 @@ stbi_inline static stbi_uc stbi__get8(stbi__context *s)
return 0;
}
+#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
+// nothing
+#else
stbi_inline static int stbi__at_eof(stbi__context *s)
{
if (s->io.read) {
@@ -1488,7 +1537,11 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
return s->img_buffer >= s->img_buffer_end;
}
+#endif
+#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC)
+// nothing
+#else
static void stbi__skip(stbi__context *s, int n)
{
if (n < 0) {
@@ -1505,7 +1558,11 @@ static void stbi__skip(stbi__context *s, int n)
}
s->img_buffer += n;
}
+#endif
+#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM)
+// nothing
+#else
static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
{
if (s->io.read) {
@@ -1529,18 +1586,27 @@ static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
} else
return 0;
}
+#endif
+#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC)
+// nothing
+#else
static int stbi__get16be(stbi__context *s)
{
int z = stbi__get8(s);
return (z << 8) + stbi__get8(s);
}
+#endif
+#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC)
+// nothing
+#else
static stbi__uint32 stbi__get32be(stbi__context *s)
{
stbi__uint32 z = stbi__get16be(s);
return (z << 16) + stbi__get16be(s);
}
+#endif
#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
// nothing
@@ -1562,7 +1628,9 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
-
+#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
+// nothing
+#else
//////////////////////////////////////////////////////////////////////////////
//
// generic converter from built-in img_n to req_comp
@@ -1578,7 +1646,11 @@ static stbi_uc stbi__compute_y(int r, int g, int b)
{
return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8);
}
+#endif
+#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM)
+// nothing
+#else
static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
{
int i,j;
@@ -1622,12 +1694,20 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
STBI_FREE(data);
return good;
}
+#endif
+#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
+// nothing
+#else
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
{
return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
}
+#endif
+#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
+// nothing
+#else
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
{
int i,j;
@@ -1671,6 +1751,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
STBI_FREE(data);
return good;
}
+#endif
#ifndef STBI_NO_LINEAR
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
@@ -4942,6 +5023,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
++s->img_n;
}
STBI_FREE(z->expanded); z->expanded = NULL;
+ // end of PNG chunk, read and skip CRC
+ stbi__get32be(s);
return 1;
}
@@ -5111,7 +5194,7 @@ static int stbi__shiftsigned(unsigned int v, int shift, int bits)
v <<= -shift;
else
v >>= shift;
- STBI_ASSERT(v >= 0 && v < 256);
+ STBI_ASSERT(v < 256);
v >>= (8-bits);
STBI_ASSERT(bits >= 0 && bits <= 8);
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
@@ -5121,6 +5204,7 @@ typedef struct
{
int bpp, offset, hsz;
unsigned int mr,mg,mb,ma, all_a;
+ int extra_read;
} stbi__bmp_data;
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
@@ -5133,6 +5217,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->offset = stbi__get32le(s);
info->hsz = hsz = stbi__get32le(s);
info->mr = info->mg = info->mb = info->ma = 0;
+ info->extra_read = 14;
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) {
@@ -5176,6 +5261,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->mr = stbi__get32le(s);
info->mg = stbi__get32le(s);
info->mb = stbi__get32le(s);
+ info->extra_read += 12;
// not documented, but generated by photoshop and handled by mspaint
if (info->mr == info->mg && info->mg == info->mb) {
// ?!?!?
@@ -5232,10 +5318,13 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
if (info.hsz == 12) {
if (info.bpp < 24)
- psize = (info.offset - 14 - 24) / 3;
+ psize = (info.offset - info.extra_read - 24) / 3;
} else {
if (info.bpp < 16)
- psize = (info.offset - 14 - info.hsz) >> 2;
+ psize = (info.offset - info.extra_read - info.hsz) >> 2;
+ }
+ if (psize == 0) {
+ STBI_ASSERT(info.offset == (s->img_buffer - s->buffer_start));
}
if (info.bpp == 24 && ma == 0xff000000)
@@ -5263,7 +5352,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
if (info.hsz != 12) stbi__get8(s);
pal[i][3] = 255;
}
- stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
+ stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
if (info.bpp == 1) width = (s->img_x + 7) >> 3;
else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
else if (info.bpp == 8) width = s->img_x;
@@ -5312,7 +5401,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
int z = 0;
int easy=0;
- stbi__skip(s, info.offset - 14 - info.hsz);
+ stbi__skip(s, info.offset - info.extra_read - info.hsz);
if (info.bpp == 24) width = 3 * s->img_x;
else if (info.bpp == 16) width = 2*s->img_x;
else /* bpp = 32 and pad = 0 */ width=0;
@@ -6202,7 +6291,7 @@ typedef struct
int w,h;
stbi_uc *out; // output buffer (always 4 components)
stbi_uc *background; // The current "background" as far as a gif is concerned
- stbi_uc *history;
+ stbi_uc *history;
int flags, bgindex, ratio, transparent, eflags;
stbi_uc pal[256][4];
stbi_uc lpal[256][4];
@@ -6290,7 +6379,7 @@ static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
{
stbi_uc *p, *c;
- int idx;
+ int idx;
// recurse to decode the prefixes, since the linked-list is backwards,
// and working backwards through an interleaved image would be nasty
@@ -6299,12 +6388,12 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
if (g->cur_y >= g->max_y) return;
- idx = g->cur_x + g->cur_y;
+ idx = g->cur_x + g->cur_y;
p = &g->out[idx];
- g->history[idx / 4] = 1;
+ g->history[idx / 4] = 1;
c = &g->color_table[g->codes[code].suffix * 4];
- if (c[3] > 128) { // don't render transparent pixels;
+ if (c[3] > 128) { // don't render transparent pixels;
p[0] = c[2];
p[1] = c[1];
p[2] = c[0];
@@ -6413,14 +6502,14 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
// two back is the image from two frames ago, used for a very specific disposal format
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
{
- int dispose;
- int first_frame;
- int pi;
- int pcount;
+ int dispose;
+ int first_frame;
+ int pi;
+ int pcount;
STBI_NOTUSED(req_comp);
// on first frame, any non-written pixels get the background colour (non-transparent)
- first_frame = 0;
+ first_frame = 0;
if (g->out == 0) {
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
@@ -6432,17 +6521,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
if (!g->out || !g->background || !g->history)
return stbi__errpuc("outofmem", "Out of memory");
- // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
+ // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
// background colour is only used for pixels that are not rendered first frame, after that "background"
- // color refers to the color that was there the previous frame.
+ // color refers to the color that was there the previous frame.
memset(g->out, 0x00, 4 * pcount);
memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
- first_frame = 1;
+ first_frame = 1;
} else {
// second frame - how do we dispoase of the previous one?
- dispose = (g->eflags & 0x1C) >> 2;
- pcount = g->w * g->h;
+ dispose = (g->eflags & 0x1C) >> 2;
+ pcount = g->w * g->h;
if ((dispose == 3) && (two_back == 0)) {
dispose = 2; // if I don't have an image to revert back to, default to the old background
@@ -6451,32 +6540,32 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
if (dispose == 3) { // use previous graphic
for (pi = 0; pi < pcount; ++pi) {
if (g->history[pi]) {
- memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
+ memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
}
}
- } else if (dispose == 2) {
- // restore what was changed last frame to background before that frame;
+ } else if (dispose == 2) {
+ // restore what was changed last frame to background before that frame;
for (pi = 0; pi < pcount; ++pi) {
if (g->history[pi]) {
- memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
+ memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
}
}
} else {
- // This is a non-disposal case eithe way, so just
+ // This is a non-disposal case eithe way, so just
// leave the pixels as is, and they will become the new background
// 1: do not dispose
// 0: not specified.
}
- // background is what out is after the undoing of the previou frame;
- memcpy( g->background, g->out, 4 * g->w * g->h );
+ // background is what out is after the undoing of the previou frame;
+ memcpy( g->background, g->out, 4 * g->w * g->h );
}
- // clear my history;
+ // clear my history;
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
for (;;) {
- int tag = stbi__get8(s);
+ int tag = stbi__get8(s);
switch (tag) {
case 0x2C: /* Image Descriptor */
{
@@ -6521,19 +6610,19 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
} else if (g->flags & 0x80) {
g->color_table = (stbi_uc *) g->pal;
} else
- return stbi__errpuc("missing color table", "Corrupt GIF");
-
+ return stbi__errpuc("missing color table", "Corrupt GIF");
+
o = stbi__process_gif_raster(s, g);
if (!o) return NULL;
- // if this was the first frame,
- pcount = g->w * g->h;
+ // if this was the first frame,
+ pcount = g->w * g->h;
if (first_frame && (g->bgindex > 0)) {
// if first frame, any pixel not drawn to gets the background color
for (pi = 0; pi < pcount; ++pi) {
if (g->history[pi] == 0) {
- g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
- memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
+ g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
+ memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
}
}
}
@@ -6544,7 +6633,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
case 0x21: // Comment Extension.
{
int len;
- int ext = stbi__get8(s);
+ int ext = stbi__get8(s);
if (ext == 0xF9) { // Graphic Control Extension.
len = stbi__get8(s);
if (len == 4) {
@@ -6553,23 +6642,23 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
// unset old transparent
if (g->transparent >= 0) {
- g->pal[g->transparent][3] = 255;
- }
+ g->pal[g->transparent][3] = 255;
+ }
if (g->eflags & 0x01) {
g->transparent = stbi__get8(s);
if (g->transparent >= 0) {
- g->pal[g->transparent][3] = 0;
+ g->pal[g->transparent][3] = 0;
}
} else {
// don't need transparent
- stbi__skip(s, 1);
- g->transparent = -1;
+ stbi__skip(s, 1);
+ g->transparent = -1;
}
} else {
stbi__skip(s, len);
break;
}
- }
+ }
while ((len = stbi__get8(s)) != 0) {
stbi__skip(s, len);
}
@@ -6588,15 +6677,15 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
{
if (stbi__gif_test(s)) {
- int layers = 0;
+ int layers = 0;
stbi_uc *u = 0;
stbi_uc *out = 0;
- stbi_uc *two_back = 0;
+ stbi_uc *two_back = 0;
stbi__gif g;
- int stride;
+ int stride;
memset(&g, 0, sizeof(g));
if (delays) {
- *delays = 0;
+ *delays = 0;
}
do {
@@ -6606,44 +6695,52 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
if (u) {
*x = g.w;
*y = g.h;
- ++layers;
- stride = g.w * g.h * 4;
-
+ ++layers;
+ stride = g.w * g.h * 4;
+
if (out) {
- out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
+ void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride );
+ if (NULL == tmp) {
+ STBI_FREE(g.out);
+ STBI_FREE(g.history);
+ STBI_FREE(g.background);
+ return stbi__errpuc("outofmem", "Out of memory");
+ }
+ else
+ out = (stbi_uc*) tmp;
if (delays) {
- *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
+ *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
}
} else {
- out = (stbi_uc*)stbi__malloc( layers * stride );
+ out = (stbi_uc*)stbi__malloc( layers * stride );
if (delays) {
- *delays = (int*) stbi__malloc( layers * sizeof(int) );
+ *delays = (int*) stbi__malloc( layers * sizeof(int) );
}
}
- memcpy( out + ((layers - 1) * stride), u, stride );
+ memcpy( out + ((layers - 1) * stride), u, stride );
if (layers >= 2) {
- two_back = out - 2 * stride;
+ two_back = out - 2 * stride;
}
if (delays) {
- (*delays)[layers - 1U] = g.delay;
+ (*delays)[layers - 1U] = g.delay;
}
}
- } while (u != 0);
+ } while (u != 0);
- // free temp buffer;
- STBI_FREE(g.out);
- STBI_FREE(g.history);
- STBI_FREE(g.background);
+ // free temp buffer;
+ STBI_FREE(g.out);
+ STBI_FREE(g.history);
+ STBI_FREE(g.background);
- // do the final conversion after loading everything;
+ // do the final conversion after loading everything;
if (req_comp && req_comp != 4)
out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
- *z = layers;
+ *z = layers;
return out;
} else {
- return stbi__errpuc("not GIF", "Image was not as a gif type.");
+ return stbi__errpuc("not GIF", "Image was not as a gif type.");
}
}
@@ -6661,7 +6758,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
*y = g.h;
// moved conversion to after successful load so that the same
- // can be done for multiple frames.
+ // can be done for multiple frames.
if (req_comp && req_comp != 4)
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
} else if (g.out) {
@@ -6669,9 +6766,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
STBI_FREE(g.out);
}
- // free buffers needed for multiple frame loading;
+ // free buffers needed for multiple frame loading;
STBI_FREE(g.history);
- STBI_FREE(g.background);
+ STBI_FREE(g.background);
return u;
}
@@ -7334,7 +7431,7 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
/*
revision history:
- 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
+ 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
2.19 (2018-02-11) fix warning
2.18 (2018-01-30) fix warnings
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug