mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-22 14:44:34 +00:00
Update stb_image to 2.26.
This commit is contained in:
parent
2be3f1766f
commit
6866d8f429
@ -1,4 +1,4 @@
|
|||||||
/* stb_image - v2.22 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
@ -48,6 +48,10 @@ LICENSE
|
|||||||
|
|
||||||
RECENT REVISION HISTORY:
|
RECENT REVISION HISTORY:
|
||||||
|
|
||||||
|
2.26 (2020-07-13) many minor fixes
|
||||||
|
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.22 (2019-03-04) gif fixes, fix warnings
|
||||||
2.21 (2019-02-25) fix typo in comment
|
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
|
||||||
@ -90,21 +94,30 @@ RECENT REVISION HISTORY:
|
|||||||
Carmelo J Fdez-Aguera
|
Carmelo J Fdez-Aguera
|
||||||
|
|
||||||
Bug & warning fixes
|
Bug & warning fixes
|
||||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||||
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
|
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
|
||||||
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
|
Phil Jordan Dave Moore Roy Eltham
|
||||||
Won Chun Luke Graham Johan Duparc Nick Verigakis
|
Hayaki Saito Nathan Reed Won Chun
|
||||||
the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
|
Luke Graham Johan Duparc Nick Verigakis the Horde3D community
|
||||||
Janez Zemva John Bartholomew Michal Cichon github:romigrou
|
Thomas Ruf Ronny Chevalier github:rlyeh
|
||||||
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
|
Janez Zemva John Bartholomew Michal Cichon github:romigrou
|
||||||
Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
|
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
|
||||||
Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
|
Laurent Gomila Cort Stratton github:snagar
|
||||||
Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
|
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
|
||||||
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
Cass Everitt Ryamond Barbiero github:grim210
|
||||||
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
|
||||||
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
|
||||||
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
Josh Tobin Matthew Gregan github:poppolopoppo
|
||||||
Blazej Dariusz Roszkowski github:Michaelangel007
|
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
|
||||||
|
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
|
||||||
|
Brad Weinberger Matvey Cherevko [reserved]
|
||||||
|
Luca Sas Alexander Veselov Zack Middleton [reserved]
|
||||||
|
Ryan C. Gordon [reserved] [reserved]
|
||||||
|
DO NOT ADD YOUR NAME HERE
|
||||||
|
|
||||||
|
To add your name to the credits, pick a random blank space in the middle and fill it.
|
||||||
|
80% of merge conflicts on stb PRs are due to people adding their name at the end
|
||||||
|
of the credits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||||
@ -314,7 +327,14 @@ RECENT REVISION HISTORY:
|
|||||||
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
||||||
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
||||||
//
|
//
|
||||||
|
// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater
|
||||||
|
// than that size (in either width or height) without further processing.
|
||||||
|
// This is to let programs in the wild set an upper bound to prevent
|
||||||
|
// denial-of-service attacks on untrusted data, as one could generate a
|
||||||
|
// valid image of gigantic dimensions and force stb_image to allocate a
|
||||||
|
// huge block of memory and spend disproportionate time decoding it. By
|
||||||
|
// default this is set to (1 << 24), which is 16777216, but that's still
|
||||||
|
// very big.
|
||||||
|
|
||||||
#ifndef STBI_NO_STDIO
|
#ifndef STBI_NO_STDIO
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -433,7 +453,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f);
|
|||||||
|
|
||||||
|
|
||||||
// get a VERY brief reason for failure
|
// 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);
|
STBIDEF const char *stbi_failure_reason (void);
|
||||||
|
|
||||||
// free the loaded image -- this is just free()
|
// free the loaded image -- this is just free()
|
||||||
@ -466,6 +486,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
|
// 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);
|
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
|
// 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);
|
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
|
||||||
@ -562,6 +587,23 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|||||||
#define stbi_inline __forceinline
|
#define stbi_inline __forceinline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_NO_THREAD_LOCALS
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||||
|
#define STBI_THREAD_LOCAL thread_local
|
||||||
|
#elif defined(__GNUC__) && __GNUC__ < 5
|
||||||
|
#define STBI_THREAD_LOCAL __thread
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define STBI_THREAD_LOCAL __declspec(thread)
|
||||||
|
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
|
||||||
|
#define STBI_THREAD_LOCAL _Thread_local
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_THREAD_LOCAL
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define STBI_THREAD_LOCAL __thread
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef unsigned short stbi__uint16;
|
typedef unsigned short stbi__uint16;
|
||||||
@ -714,6 +756,10 @@ static int stbi__sse2_available(void)
|
|||||||
#define STBI_SIMD_ALIGN(type, name) type name
|
#define STBI_SIMD_ALIGN(type, name) type name
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_MAX_DIMENSIONS
|
||||||
|
#define STBI_MAX_DIMENSIONS (1 << 24)
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// stbi__context struct and start_xxx functions
|
// stbi__context struct and start_xxx functions
|
||||||
@ -731,6 +777,7 @@ typedef struct
|
|||||||
int read_from_callbacks;
|
int read_from_callbacks;
|
||||||
int buflen;
|
int buflen;
|
||||||
stbi_uc buffer_start[128];
|
stbi_uc buffer_start[128];
|
||||||
|
int callback_already_read;
|
||||||
|
|
||||||
stbi_uc *img_buffer, *img_buffer_end;
|
stbi_uc *img_buffer, *img_buffer_end;
|
||||||
stbi_uc *img_buffer_original, *img_buffer_original_end;
|
stbi_uc *img_buffer_original, *img_buffer_original_end;
|
||||||
@ -744,6 +791,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
|
|||||||
{
|
{
|
||||||
s->io.read = NULL;
|
s->io.read = NULL;
|
||||||
s->read_from_callbacks = 0;
|
s->read_from_callbacks = 0;
|
||||||
|
s->callback_already_read = 0;
|
||||||
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
|
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
|
||||||
s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
|
s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
|
||||||
}
|
}
|
||||||
@ -755,7 +803,8 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
|
|||||||
s->io_user_data = user;
|
s->io_user_data = user;
|
||||||
s->buflen = sizeof(s->buffer_start);
|
s->buflen = sizeof(s->buffer_start);
|
||||||
s->read_from_callbacks = 1;
|
s->read_from_callbacks = 1;
|
||||||
s->img_buffer_original = s->buffer_start;
|
s->callback_already_read = 0;
|
||||||
|
s->img_buffer = s->img_buffer_original = s->buffer_start;
|
||||||
stbi__refill_buffer(s);
|
stbi__refill_buffer(s);
|
||||||
s->img_buffer_original_end = s->img_buffer_end;
|
s->img_buffer_original_end = s->img_buffer_end;
|
||||||
}
|
}
|
||||||
@ -769,12 +818,17 @@ static int stbi__stdio_read(void *user, char *data, int size)
|
|||||||
|
|
||||||
static void stbi__stdio_skip(void *user, int n)
|
static void stbi__stdio_skip(void *user, int n)
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
fseek((FILE*) user, n, SEEK_CUR);
|
fseek((FILE*) user, n, SEEK_CUR);
|
||||||
|
ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */
|
||||||
|
if (ch != EOF) {
|
||||||
|
ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbi__stdio_eof(void *user)
|
static int stbi__stdio_eof(void *user)
|
||||||
{
|
{
|
||||||
return feof((FILE*) user);
|
return feof((FILE*) user) || ferror((FILE *) user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stbi_io_callbacks stbi__stdio_callbacks =
|
static stbi_io_callbacks stbi__stdio_callbacks =
|
||||||
@ -872,19 +926,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);
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this is not threadsafe
|
static
|
||||||
static const char *stbi__g_failure_reason;
|
#ifdef STBI_THREAD_LOCAL
|
||||||
|
STBI_THREAD_LOCAL
|
||||||
|
#endif
|
||||||
|
const char *stbi__g_failure_reason;
|
||||||
|
|
||||||
STBIDEF const char *stbi_failure_reason(void)
|
STBIDEF const char *stbi_failure_reason(void)
|
||||||
{
|
{
|
||||||
return stbi__g_failure_reason;
|
return stbi__g_failure_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef STBI_NO_FAILURE_STRINGS
|
||||||
static int stbi__err(const char *str)
|
static int stbi__err(const char *str)
|
||||||
{
|
{
|
||||||
stbi__g_failure_reason = str;
|
stbi__g_failure_reason = str;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *stbi__malloc(size_t size)
|
static void *stbi__malloc(size_t size)
|
||||||
{
|
{
|
||||||
@ -923,11 +982,13 @@ static int stbi__mul2sizes_valid(int a, int b)
|
|||||||
return a <= INT_MAX/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
|
// 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)
|
static int stbi__mad2sizes_valid(int a, int b, int add)
|
||||||
{
|
{
|
||||||
return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, 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
|
// 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)
|
static int stbi__mad3sizes_valid(int a, int b, int c, int add)
|
||||||
@ -945,12 +1006,14 @@ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
|
||||||
// mallocs with size overflow checking
|
// mallocs with size overflow checking
|
||||||
static void *stbi__malloc_mad2(int a, int b, int add)
|
static void *stbi__malloc_mad2(int a, int b, int add)
|
||||||
{
|
{
|
||||||
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
|
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
|
||||||
return stbi__malloc(a*b + add);
|
return stbi__malloc(a*b + add);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *stbi__malloc_mad3(int a, int b, int c, int add)
|
static void *stbi__malloc_mad3(int a, int b, int c, int add)
|
||||||
{
|
{
|
||||||
@ -994,13 +1057,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);
|
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
|
||||||
#endif
|
#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)
|
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)
|
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
|
memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
|
||||||
@ -1022,6 +1101,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
#endif
|
#endif
|
||||||
#ifndef STBI_NO_PSD
|
#ifndef STBI_NO_PSD
|
||||||
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
||||||
|
#else
|
||||||
|
STBI_NOTUSED(bpc);
|
||||||
#endif
|
#endif
|
||||||
#ifndef STBI_NO_PIC
|
#ifndef STBI_NO_PIC
|
||||||
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
||||||
@ -1124,8 +1205,10 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
|
||||||
|
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||||
|
|
||||||
if (ri.bits_per_channel != 8) {
|
if (ri.bits_per_channel != 8) {
|
||||||
STBI_ASSERT(ri.bits_per_channel == 16);
|
|
||||||
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||||
ri.bits_per_channel = 8;
|
ri.bits_per_channel = 8;
|
||||||
}
|
}
|
||||||
@ -1148,8 +1231,10 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
|
||||||
|
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||||
|
|
||||||
if (ri.bits_per_channel != 16) {
|
if (ri.bits_per_channel != 16) {
|
||||||
STBI_ASSERT(ri.bits_per_channel == 8);
|
|
||||||
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||||
ri.bits_per_channel = 16;
|
ri.bits_per_channel = 16;
|
||||||
}
|
}
|
||||||
@ -1452,6 +1537,7 @@ enum
|
|||||||
static void stbi__refill_buffer(stbi__context *s)
|
static void stbi__refill_buffer(stbi__context *s)
|
||||||
{
|
{
|
||||||
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
|
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
|
||||||
|
s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
// at end of file, treat same as if from memory, but need to handle case
|
// at end of file, treat same as if from memory, but need to handle case
|
||||||
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
|
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
|
||||||
@ -1476,6 +1562,9 @@ stbi_inline static stbi_uc stbi__get8(stbi__context *s)
|
|||||||
return 0;
|
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)
|
stbi_inline static int stbi__at_eof(stbi__context *s)
|
||||||
{
|
{
|
||||||
if (s->io.read) {
|
if (s->io.read) {
|
||||||
@ -1487,9 +1576,14 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
|
|||||||
|
|
||||||
return s->img_buffer >= s->img_buffer_end;
|
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)
|
static void stbi__skip(stbi__context *s, int n)
|
||||||
{
|
{
|
||||||
|
if (n == 0) return; // already there!
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
s->img_buffer = s->img_buffer_end;
|
s->img_buffer = s->img_buffer_end;
|
||||||
return;
|
return;
|
||||||
@ -1504,7 +1598,11 @@ static void stbi__skip(stbi__context *s, int n)
|
|||||||
}
|
}
|
||||||
s->img_buffer += 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)
|
static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
|
||||||
{
|
{
|
||||||
if (s->io.read) {
|
if (s->io.read) {
|
||||||
@ -1528,18 +1626,27 @@ static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
|
|||||||
} else
|
} else
|
||||||
return 0;
|
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)
|
static int stbi__get16be(stbi__context *s)
|
||||||
{
|
{
|
||||||
int z = stbi__get8(s);
|
int z = stbi__get8(s);
|
||||||
return (z << 8) + 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)
|
static stbi__uint32 stbi__get32be(stbi__context *s)
|
||||||
{
|
{
|
||||||
stbi__uint32 z = stbi__get16be(s);
|
stbi__uint32 z = stbi__get16be(s);
|
||||||
return (z << 16) + stbi__get16be(s);
|
return (z << 16) + stbi__get16be(s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
|
#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
|
||||||
// nothing
|
// nothing
|
||||||
@ -1561,7 +1668,9 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
|
|||||||
|
|
||||||
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
|
#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
|
// generic converter from built-in img_n to req_comp
|
||||||
@ -1577,7 +1686,11 @@ static stbi_uc stbi__compute_y(int r, int g, int b)
|
|||||||
{
|
{
|
||||||
return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8);
|
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)
|
static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
@ -1613,7 +1726,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||||
default: STBI_ASSERT(0);
|
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion");
|
||||||
}
|
}
|
||||||
#undef STBI__CASE
|
#undef STBI__CASE
|
||||||
}
|
}
|
||||||
@ -1621,12 +1734,20 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||||||
STBI_FREE(data);
|
STBI_FREE(data);
|
||||||
return good;
|
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)
|
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
||||||
{
|
{
|
||||||
return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
|
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)
|
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
@ -1662,7 +1783,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|||||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||||
default: STBI_ASSERT(0);
|
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion");
|
||||||
}
|
}
|
||||||
#undef STBI__CASE
|
#undef STBI__CASE
|
||||||
}
|
}
|
||||||
@ -1670,6 +1791,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|||||||
STBI_FREE(data);
|
STBI_FREE(data);
|
||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef STBI_NO_LINEAR
|
#ifndef STBI_NO_LINEAR
|
||||||
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
||||||
@ -1970,7 +2092,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
|
|||||||
|
|
||||||
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
|
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
|
||||||
k = stbi_lrot(j->code_buffer, n);
|
k = stbi_lrot(j->code_buffer, n);
|
||||||
STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
|
if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
|
||||||
j->code_buffer = k & ~stbi__bmask[n];
|
j->code_buffer = k & ~stbi__bmask[n];
|
||||||
k &= stbi__bmask[n];
|
k &= stbi__bmask[n];
|
||||||
j->code_bits -= n;
|
j->code_bits -= n;
|
||||||
@ -2081,6 +2203,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
|
|||||||
// first scan for DC coefficient, must be first
|
// first scan for DC coefficient, must be first
|
||||||
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
|
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
|
||||||
t = stbi__jpeg_huff_decode(j, hdc);
|
t = stbi__jpeg_huff_decode(j, hdc);
|
||||||
|
if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||||
diff = t ? stbi__extend_receive(j, t) : 0;
|
diff = t ? stbi__extend_receive(j, t) : 0;
|
||||||
|
|
||||||
dc = j->img_comp[b].dc_pred + diff;
|
dc = j->img_comp[b].dc_pred + diff;
|
||||||
@ -3071,6 +3194,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|||||||
p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
|
p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
|
||||||
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
|
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
|
||||||
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
c = stbi__get8(s);
|
c = stbi__get8(s);
|
||||||
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
||||||
s->img_n = c;
|
s->img_n = c;
|
||||||
@ -3951,16 +4076,23 @@ typedef struct
|
|||||||
stbi__zhuffman z_length, z_distance;
|
stbi__zhuffman z_length, z_distance;
|
||||||
} stbi__zbuf;
|
} stbi__zbuf;
|
||||||
|
|
||||||
|
stbi_inline static int stbi__zeof(stbi__zbuf *z)
|
||||||
|
{
|
||||||
|
return (z->zbuffer >= z->zbuffer_end);
|
||||||
|
}
|
||||||
|
|
||||||
stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
|
stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
|
||||||
{
|
{
|
||||||
if (z->zbuffer >= z->zbuffer_end) return 0;
|
return stbi__zeof(z) ? 0 : *z->zbuffer++;
|
||||||
return *z->zbuffer++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stbi__fill_bits(stbi__zbuf *z)
|
static void stbi__fill_bits(stbi__zbuf *z)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
|
if (z->code_buffer >= (1U << z->num_bits)) {
|
||||||
|
z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
|
z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
|
||||||
z->num_bits += 8;
|
z->num_bits += 8;
|
||||||
} while (z->num_bits <= 24);
|
} while (z->num_bits <= 24);
|
||||||
@ -3985,10 +4117,11 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
for (s=STBI__ZFAST_BITS+1; ; ++s)
|
for (s=STBI__ZFAST_BITS+1; ; ++s)
|
||||||
if (k < z->maxcode[s])
|
if (k < z->maxcode[s])
|
||||||
break;
|
break;
|
||||||
if (s == 16) return -1; // invalid code!
|
if (s >= 16) return -1; // invalid code!
|
||||||
// code size is s, so:
|
// code size is s, so:
|
||||||
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
|
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
|
||||||
STBI_ASSERT(z->size[b] == s);
|
if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
|
||||||
|
if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
|
||||||
a->code_buffer >>= s;
|
a->code_buffer >>= s;
|
||||||
a->num_bits -= s;
|
a->num_bits -= s;
|
||||||
return z->value[b];
|
return z->value[b];
|
||||||
@ -3997,7 +4130,12 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
||||||
{
|
{
|
||||||
int b,s;
|
int b,s;
|
||||||
if (a->num_bits < 16) stbi__fill_bits(a);
|
if (a->num_bits < 16) {
|
||||||
|
if (stbi__zeof(a)) {
|
||||||
|
return -1; /* report error for unexpected end of data. */
|
||||||
|
}
|
||||||
|
stbi__fill_bits(a);
|
||||||
|
}
|
||||||
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
||||||
if (b) {
|
if (b) {
|
||||||
s = b >> 9;
|
s = b >> 9;
|
||||||
@ -4011,13 +4149,16 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
||||||
{
|
{
|
||||||
char *q;
|
char *q;
|
||||||
int cur, limit, old_limit;
|
unsigned int cur, limit, old_limit;
|
||||||
z->zout = zout;
|
z->zout = zout;
|
||||||
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
||||||
cur = (int) (z->zout - z->zout_start);
|
cur = (unsigned int) (z->zout - z->zout_start);
|
||||||
limit = old_limit = (int) (z->zout_end - z->zout_start);
|
limit = old_limit = (unsigned) (z->zout_end - z->zout_start);
|
||||||
while (cur + n > limit)
|
if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory");
|
||||||
|
while (cur + n > limit) {
|
||||||
|
if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory");
|
||||||
limit *= 2;
|
limit *= 2;
|
||||||
|
}
|
||||||
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
||||||
STBI_NOTUSED(old_limit);
|
STBI_NOTUSED(old_limit);
|
||||||
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
||||||
@ -4115,11 +4256,12 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
|||||||
c = stbi__zreceive(a,2)+3;
|
c = stbi__zreceive(a,2)+3;
|
||||||
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
|
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
fill = lencodes[n-1];
|
fill = lencodes[n-1];
|
||||||
} else if (c == 17)
|
} else if (c == 17) {
|
||||||
c = stbi__zreceive(a,3)+3;
|
c = stbi__zreceive(a,3)+3;
|
||||||
else {
|
} else if (c == 18) {
|
||||||
STBI_ASSERT(c == 18);
|
|
||||||
c = stbi__zreceive(a,7)+11;
|
c = stbi__zreceive(a,7)+11;
|
||||||
|
} else {
|
||||||
|
return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
}
|
}
|
||||||
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
|
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
memset(lencodes+n, fill, c);
|
memset(lencodes+n, fill, c);
|
||||||
@ -4145,7 +4287,7 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a)
|
|||||||
a->code_buffer >>= 8;
|
a->code_buffer >>= 8;
|
||||||
a->num_bits -= 8;
|
a->num_bits -= 8;
|
||||||
}
|
}
|
||||||
STBI_ASSERT(a->num_bits == 0);
|
if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG");
|
||||||
// now fill header the normal way
|
// now fill header the normal way
|
||||||
while (k < 4)
|
while (k < 4)
|
||||||
header[k++] = stbi__zget8(a);
|
header[k++] = stbi__zget8(a);
|
||||||
@ -4167,6 +4309,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
|
|||||||
int cm = cmf & 15;
|
int cm = cmf & 15;
|
||||||
/* int cinfo = cmf >> 4; */
|
/* int cinfo = cmf >> 4; */
|
||||||
int flg = stbi__zget8(a);
|
int flg = stbi__zget8(a);
|
||||||
|
if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
||||||
if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
||||||
if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
|
if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
|
||||||
if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
|
if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
|
||||||
@ -4428,7 +4571,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
return stbi__err("invalid filter","Corrupt PNG");
|
return stbi__err("invalid filter","Corrupt PNG");
|
||||||
|
|
||||||
if (depth < 8) {
|
if (depth < 8) {
|
||||||
STBI_ASSERT(img_width_bytes <= x);
|
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
|
||||||
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
||||||
filter_bytes = 1;
|
filter_bytes = 1;
|
||||||
width = img_width_bytes;
|
width = img_width_bytes;
|
||||||
@ -4823,8 +4966,10 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
|
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
|
||||||
first = 0;
|
first = 0;
|
||||||
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
||||||
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
s->img_x = stbi__get32be(s);
|
||||||
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
s->img_y = stbi__get32be(s);
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
|
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
|
||||||
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
||||||
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
||||||
@ -4941,6 +5086,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
++s->img_n;
|
++s->img_n;
|
||||||
}
|
}
|
||||||
STBI_FREE(z->expanded); z->expanded = NULL;
|
STBI_FREE(z->expanded); z->expanded = NULL;
|
||||||
|
// end of PNG chunk, read and skip CRC
|
||||||
|
stbi__get32be(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4971,10 +5118,12 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st
|
|||||||
void *result=NULL;
|
void *result=NULL;
|
||||||
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
||||||
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
||||||
if (p->depth < 8)
|
if (p->depth <= 8)
|
||||||
ri->bits_per_channel = 8;
|
ri->bits_per_channel = 8;
|
||||||
|
else if (p->depth == 16)
|
||||||
|
ri->bits_per_channel = 16;
|
||||||
else
|
else
|
||||||
ri->bits_per_channel = p->depth;
|
return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth");
|
||||||
result = p->out;
|
result = p->out;
|
||||||
p->out = NULL;
|
p->out = NULL;
|
||||||
if (req_comp && req_comp != p->s->img_out_n) {
|
if (req_comp && req_comp != p->s->img_out_n) {
|
||||||
@ -5079,7 +5228,7 @@ static int stbi__high_bit(unsigned int z)
|
|||||||
if (z >= 0x00100) { n += 8; z >>= 8; }
|
if (z >= 0x00100) { n += 8; z >>= 8; }
|
||||||
if (z >= 0x00010) { n += 4; z >>= 4; }
|
if (z >= 0x00010) { n += 4; z >>= 4; }
|
||||||
if (z >= 0x00004) { n += 2; z >>= 2; }
|
if (z >= 0x00004) { n += 2; z >>= 2; }
|
||||||
if (z >= 0x00002) { n += 1; z >>= 1; }
|
if (z >= 0x00002) { n += 1;/* >>= 1;*/ }
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5110,7 +5259,7 @@ static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
|||||||
v <<= -shift;
|
v <<= -shift;
|
||||||
else
|
else
|
||||||
v >>= shift;
|
v >>= shift;
|
||||||
STBI_ASSERT(v >= 0 && v < 256);
|
STBI_ASSERT(v < 256);
|
||||||
v >>= (8-bits);
|
v >>= (8-bits);
|
||||||
STBI_ASSERT(bits >= 0 && bits <= 8);
|
STBI_ASSERT(bits >= 0 && bits <= 8);
|
||||||
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
||||||
@ -5120,6 +5269,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
int bpp, offset, hsz;
|
int bpp, offset, hsz;
|
||||||
unsigned int mr,mg,mb,ma, all_a;
|
unsigned int mr,mg,mb,ma, all_a;
|
||||||
|
int extra_read;
|
||||||
} stbi__bmp_data;
|
} stbi__bmp_data;
|
||||||
|
|
||||||
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
||||||
@ -5132,6 +5282,9 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|||||||
info->offset = stbi__get32le(s);
|
info->offset = stbi__get32le(s);
|
||||||
info->hsz = hsz = stbi__get32le(s);
|
info->hsz = hsz = stbi__get32le(s);
|
||||||
info->mr = info->mg = info->mb = info->ma = 0;
|
info->mr = info->mg = info->mb = info->ma = 0;
|
||||||
|
info->extra_read = 14;
|
||||||
|
|
||||||
|
if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP");
|
||||||
|
|
||||||
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
||||||
if (hsz == 12) {
|
if (hsz == 12) {
|
||||||
@ -5175,6 +5328,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|||||||
info->mr = stbi__get32le(s);
|
info->mr = stbi__get32le(s);
|
||||||
info->mg = stbi__get32le(s);
|
info->mg = stbi__get32le(s);
|
||||||
info->mb = stbi__get32le(s);
|
info->mb = stbi__get32le(s);
|
||||||
|
info->extra_read += 12;
|
||||||
// not documented, but generated by photoshop and handled by mspaint
|
// not documented, but generated by photoshop and handled by mspaint
|
||||||
if (info->mr == info->mg && info->mg == info->mb) {
|
if (info->mr == info->mg && info->mg == info->mb) {
|
||||||
// ?!?!?
|
// ?!?!?
|
||||||
@ -5223,6 +5377,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
flip_vertically = ((int) s->img_y) > 0;
|
flip_vertically = ((int) s->img_y) > 0;
|
||||||
s->img_y = abs((int) s->img_y);
|
s->img_y = abs((int) s->img_y);
|
||||||
|
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
mr = info.mr;
|
mr = info.mr;
|
||||||
mg = info.mg;
|
mg = info.mg;
|
||||||
mb = info.mb;
|
mb = info.mb;
|
||||||
@ -5231,13 +5388,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
|
|
||||||
if (info.hsz == 12) {
|
if (info.hsz == 12) {
|
||||||
if (info.bpp < 24)
|
if (info.bpp < 24)
|
||||||
psize = (info.offset - 14 - 24) / 3;
|
psize = (info.offset - info.extra_read - 24) / 3;
|
||||||
} else {
|
} else {
|
||||||
if (info.bpp < 16)
|
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->callback_already_read + (int) (s->img_buffer - s->img_buffer_original));
|
||||||
|
if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
|
||||||
|
return stbi__errpuc("bad offset", "Corrupt BMP");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->img_n = ma ? 4 : 3;
|
if (info.bpp == 24 && ma == 0xff000000)
|
||||||
|
s->img_n = 3;
|
||||||
|
else
|
||||||
|
s->img_n = ma ? 4 : 3;
|
||||||
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
||||||
target = req_comp;
|
target = req_comp;
|
||||||
else
|
else
|
||||||
@ -5259,7 +5425,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
if (info.hsz != 12) stbi__get8(s);
|
if (info.hsz != 12) stbi__get8(s);
|
||||||
pal[i][3] = 255;
|
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;
|
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 == 4) width = (s->img_x + 1) >> 1;
|
||||||
else if (info.bpp == 8) width = s->img_x;
|
else if (info.bpp == 8) width = s->img_x;
|
||||||
@ -5308,7 +5474,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 rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
|
||||||
int z = 0;
|
int z = 0;
|
||||||
int easy=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;
|
if (info.bpp == 24) width = 3 * s->img_x;
|
||||||
else if (info.bpp == 16) width = 2*s->img_x;
|
else if (info.bpp == 16) width = 2*s->img_x;
|
||||||
else /* bpp = 32 and pad = 0 */ width=0;
|
else /* bpp = 32 and pad = 0 */ width=0;
|
||||||
@ -5326,6 +5492,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
|
gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
|
||||||
bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
|
bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
|
||||||
ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
|
ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
|
||||||
|
if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
|
||||||
}
|
}
|
||||||
for (j=0; j < (int) s->img_y; ++j) {
|
for (j=0; j < (int) s->img_y; ++j) {
|
||||||
if (easy) {
|
if (easy) {
|
||||||
@ -5547,6 +5714,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
int RLE_repeating = 0;
|
int RLE_repeating = 0;
|
||||||
int read_next_pixel = 1;
|
int read_next_pixel = 1;
|
||||||
STBI_NOTUSED(ri);
|
STBI_NOTUSED(ri);
|
||||||
|
STBI_NOTUSED(tga_x_origin); // @TODO
|
||||||
|
STBI_NOTUSED(tga_y_origin); // @TODO
|
||||||
|
|
||||||
|
if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
// do a tiny bit of precessing
|
// do a tiny bit of precessing
|
||||||
if ( tga_image_type >= 8 )
|
if ( tga_image_type >= 8 )
|
||||||
@ -5587,6 +5759,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
// do I need to load a palette?
|
// do I need to load a palette?
|
||||||
if ( tga_indexed)
|
if ( tga_indexed)
|
||||||
{
|
{
|
||||||
|
if (tga_palette_len == 0) { /* you have to have at least one entry! */
|
||||||
|
STBI_FREE(tga_data);
|
||||||
|
return stbi__errpuc("bad palette", "Corrupt TGA");
|
||||||
|
}
|
||||||
|
|
||||||
// any data to skip? (offset usually = 0)
|
// any data to skip? (offset usually = 0)
|
||||||
stbi__skip(s, tga_palette_start );
|
stbi__skip(s, tga_palette_start );
|
||||||
// load the palette
|
// load the palette
|
||||||
@ -5710,6 +5887,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
// Microsoft's C compilers happy... [8^(
|
// Microsoft's C compilers happy... [8^(
|
||||||
tga_palette_start = tga_palette_len = tga_palette_bits =
|
tga_palette_start = tga_palette_len = tga_palette_bits =
|
||||||
tga_x_origin = tga_y_origin = 0;
|
tga_x_origin = tga_y_origin = 0;
|
||||||
|
STBI_NOTUSED(tga_palette_start);
|
||||||
// OK, done
|
// OK, done
|
||||||
return tga_data;
|
return tga_data;
|
||||||
}
|
}
|
||||||
@ -5794,6 +5972,9 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
h = stbi__get32be(s);
|
h = stbi__get32be(s);
|
||||||
w = stbi__get32be(s);
|
w = stbi__get32be(s);
|
||||||
|
|
||||||
|
if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
// Make sure the depth is 8 bits.
|
// Make sure the depth is 8 bits.
|
||||||
bitdepth = stbi__get16be(s);
|
bitdepth = stbi__get16be(s);
|
||||||
if (bitdepth != 8 && bitdepth != 16)
|
if (bitdepth != 8 && bitdepth != 16)
|
||||||
@ -6148,6 +6329,10 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
|
|||||||
|
|
||||||
x = stbi__get16be(s);
|
x = stbi__get16be(s);
|
||||||
y = stbi__get16be(s);
|
y = stbi__get16be(s);
|
||||||
|
|
||||||
|
if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
|
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
|
||||||
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
|
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
|
||||||
|
|
||||||
@ -6256,6 +6441,9 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
|
|||||||
g->ratio = stbi__get8(s);
|
g->ratio = stbi__get8(s);
|
||||||
g->transparent = -1;
|
g->transparent = -1;
|
||||||
|
|
||||||
|
if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
|
if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
|
||||||
|
|
||||||
if (is_info) return 1;
|
if (is_info) return 1;
|
||||||
@ -6433,7 +6621,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|||||||
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
||||||
first_frame = 1;
|
first_frame = 1;
|
||||||
} else {
|
} else {
|
||||||
// second frame - how do we dispoase of the previous one?
|
// second frame - how do we dispose of the previous one?
|
||||||
dispose = (g->eflags & 0x1C) >> 2;
|
dispose = (g->eflags & 0x1C) >> 2;
|
||||||
pcount = g->w * g->h;
|
pcount = g->w * g->h;
|
||||||
|
|
||||||
@ -6587,6 +6775,8 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||||||
stbi_uc *two_back = 0;
|
stbi_uc *two_back = 0;
|
||||||
stbi__gif g;
|
stbi__gif g;
|
||||||
int stride;
|
int stride;
|
||||||
|
int out_size = 0;
|
||||||
|
int delays_size = 0;
|
||||||
memset(&g, 0, sizeof(g));
|
memset(&g, 0, sizeof(g));
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = 0;
|
*delays = 0;
|
||||||
@ -6603,14 +6793,28 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||||||
stride = g.w * g.h * 4;
|
stride = g.w * g.h * 4;
|
||||||
|
|
||||||
if (out) {
|
if (out) {
|
||||||
out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
|
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, 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;
|
||||||
|
out_size = layers * stride;
|
||||||
|
}
|
||||||
|
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
|
*delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
|
||||||
|
delays_size = layers * sizeof(int);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out = (stbi_uc*)stbi__malloc( layers * stride );
|
out = (stbi_uc*)stbi__malloc( layers * stride );
|
||||||
|
out_size = layers * stride;
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
||||||
|
delays_size = layers * sizeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy( out + ((layers - 1) * stride), u, stride );
|
memcpy( out + ((layers - 1) * stride), u, stride );
|
||||||
@ -6789,6 +6993,9 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
token += 3;
|
token += 3;
|
||||||
width = (int) strtol(token, NULL, 10);
|
width = (int) strtol(token, NULL, 10);
|
||||||
|
|
||||||
|
if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
|
||||||
|
if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
*x = width;
|
*x = width;
|
||||||
*y = height;
|
*y = height;
|
||||||
|
|
||||||
@ -6936,7 +7143,12 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
return 0;
|
return 0;
|
||||||
if (x) *x = s->img_x;
|
if (x) *x = s->img_x;
|
||||||
if (y) *y = s->img_y;
|
if (y) *y = s->img_y;
|
||||||
if (comp) *comp = info.ma ? 4 : 3;
|
if (comp) {
|
||||||
|
if (info.bpp == 24 && info.ma == 0xff000000)
|
||||||
|
*comp = 3;
|
||||||
|
else
|
||||||
|
*comp = info.ma ? 4 : 3;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7098,6 +7310,9 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
*x = s->img_x;
|
*x = s->img_x;
|
||||||
*y = s->img_y;
|
*y = s->img_y;
|
||||||
if (comp) *comp = s->img_n;
|
if (comp) *comp = s->img_n;
|
||||||
|
335
test/stb_image.h
335
test/stb_image.h
@ -1,4 +1,4 @@
|
|||||||
/* stb_image - v2.22 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
@ -48,6 +48,10 @@ LICENSE
|
|||||||
|
|
||||||
RECENT REVISION HISTORY:
|
RECENT REVISION HISTORY:
|
||||||
|
|
||||||
|
2.26 (2020-07-13) many minor fixes
|
||||||
|
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.22 (2019-03-04) gif fixes, fix warnings
|
||||||
2.21 (2019-02-25) fix typo in comment
|
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
|
||||||
@ -90,21 +94,30 @@ RECENT REVISION HISTORY:
|
|||||||
Carmelo J Fdez-Aguera
|
Carmelo J Fdez-Aguera
|
||||||
|
|
||||||
Bug & warning fixes
|
Bug & warning fixes
|
||||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||||
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
|
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
|
||||||
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
|
Phil Jordan Dave Moore Roy Eltham
|
||||||
Won Chun Luke Graham Johan Duparc Nick Verigakis
|
Hayaki Saito Nathan Reed Won Chun
|
||||||
the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
|
Luke Graham Johan Duparc Nick Verigakis the Horde3D community
|
||||||
Janez Zemva John Bartholomew Michal Cichon github:romigrou
|
Thomas Ruf Ronny Chevalier github:rlyeh
|
||||||
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
|
Janez Zemva John Bartholomew Michal Cichon github:romigrou
|
||||||
Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
|
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
|
||||||
Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
|
Laurent Gomila Cort Stratton github:snagar
|
||||||
Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
|
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
|
||||||
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
Cass Everitt Ryamond Barbiero github:grim210
|
||||||
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
|
||||||
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
|
||||||
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
Josh Tobin Matthew Gregan github:poppolopoppo
|
||||||
Blazej Dariusz Roszkowski github:Michaelangel007
|
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
|
||||||
|
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
|
||||||
|
Brad Weinberger Matvey Cherevko [reserved]
|
||||||
|
Luca Sas Alexander Veselov Zack Middleton [reserved]
|
||||||
|
Ryan C. Gordon [reserved] [reserved]
|
||||||
|
DO NOT ADD YOUR NAME HERE
|
||||||
|
|
||||||
|
To add your name to the credits, pick a random blank space in the middle and fill it.
|
||||||
|
80% of merge conflicts on stb PRs are due to people adding their name at the end
|
||||||
|
of the credits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||||
@ -314,7 +327,14 @@ RECENT REVISION HISTORY:
|
|||||||
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
||||||
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
||||||
//
|
//
|
||||||
|
// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater
|
||||||
|
// than that size (in either width or height) without further processing.
|
||||||
|
// This is to let programs in the wild set an upper bound to prevent
|
||||||
|
// denial-of-service attacks on untrusted data, as one could generate a
|
||||||
|
// valid image of gigantic dimensions and force stb_image to allocate a
|
||||||
|
// huge block of memory and spend disproportionate time decoding it. By
|
||||||
|
// default this is set to (1 << 24), which is 16777216, but that's still
|
||||||
|
// very big.
|
||||||
|
|
||||||
#ifndef STBI_NO_STDIO
|
#ifndef STBI_NO_STDIO
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -433,7 +453,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f);
|
|||||||
|
|
||||||
|
|
||||||
// get a VERY brief reason for failure
|
// 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);
|
STBIDEF const char *stbi_failure_reason (void);
|
||||||
|
|
||||||
// free the loaded image -- this is just free()
|
// free the loaded image -- this is just free()
|
||||||
@ -466,6 +486,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
|
// 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);
|
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
|
// 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);
|
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
|
||||||
@ -562,6 +587,23 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|||||||
#define stbi_inline __forceinline
|
#define stbi_inline __forceinline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_NO_THREAD_LOCALS
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||||
|
#define STBI_THREAD_LOCAL thread_local
|
||||||
|
#elif defined(__GNUC__) && __GNUC__ < 5
|
||||||
|
#define STBI_THREAD_LOCAL __thread
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define STBI_THREAD_LOCAL __declspec(thread)
|
||||||
|
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
|
||||||
|
#define STBI_THREAD_LOCAL _Thread_local
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_THREAD_LOCAL
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define STBI_THREAD_LOCAL __thread
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef unsigned short stbi__uint16;
|
typedef unsigned short stbi__uint16;
|
||||||
@ -714,6 +756,10 @@ static int stbi__sse2_available(void)
|
|||||||
#define STBI_SIMD_ALIGN(type, name) type name
|
#define STBI_SIMD_ALIGN(type, name) type name
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBI_MAX_DIMENSIONS
|
||||||
|
#define STBI_MAX_DIMENSIONS (1 << 24)
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// stbi__context struct and start_xxx functions
|
// stbi__context struct and start_xxx functions
|
||||||
@ -731,6 +777,7 @@ typedef struct
|
|||||||
int read_from_callbacks;
|
int read_from_callbacks;
|
||||||
int buflen;
|
int buflen;
|
||||||
stbi_uc buffer_start[128];
|
stbi_uc buffer_start[128];
|
||||||
|
int callback_already_read;
|
||||||
|
|
||||||
stbi_uc *img_buffer, *img_buffer_end;
|
stbi_uc *img_buffer, *img_buffer_end;
|
||||||
stbi_uc *img_buffer_original, *img_buffer_original_end;
|
stbi_uc *img_buffer_original, *img_buffer_original_end;
|
||||||
@ -744,6 +791,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
|
|||||||
{
|
{
|
||||||
s->io.read = NULL;
|
s->io.read = NULL;
|
||||||
s->read_from_callbacks = 0;
|
s->read_from_callbacks = 0;
|
||||||
|
s->callback_already_read = 0;
|
||||||
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
|
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
|
||||||
s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
|
s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
|
||||||
}
|
}
|
||||||
@ -755,7 +803,8 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
|
|||||||
s->io_user_data = user;
|
s->io_user_data = user;
|
||||||
s->buflen = sizeof(s->buffer_start);
|
s->buflen = sizeof(s->buffer_start);
|
||||||
s->read_from_callbacks = 1;
|
s->read_from_callbacks = 1;
|
||||||
s->img_buffer_original = s->buffer_start;
|
s->callback_already_read = 0;
|
||||||
|
s->img_buffer = s->img_buffer_original = s->buffer_start;
|
||||||
stbi__refill_buffer(s);
|
stbi__refill_buffer(s);
|
||||||
s->img_buffer_original_end = s->img_buffer_end;
|
s->img_buffer_original_end = s->img_buffer_end;
|
||||||
}
|
}
|
||||||
@ -769,12 +818,17 @@ static int stbi__stdio_read(void *user, char *data, int size)
|
|||||||
|
|
||||||
static void stbi__stdio_skip(void *user, int n)
|
static void stbi__stdio_skip(void *user, int n)
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
fseek((FILE*) user, n, SEEK_CUR);
|
fseek((FILE*) user, n, SEEK_CUR);
|
||||||
|
ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */
|
||||||
|
if (ch != EOF) {
|
||||||
|
ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbi__stdio_eof(void *user)
|
static int stbi__stdio_eof(void *user)
|
||||||
{
|
{
|
||||||
return feof((FILE*) user);
|
return feof((FILE*) user) || ferror((FILE *) user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stbi_io_callbacks stbi__stdio_callbacks =
|
static stbi_io_callbacks stbi__stdio_callbacks =
|
||||||
@ -872,19 +926,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);
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this is not threadsafe
|
static
|
||||||
static const char *stbi__g_failure_reason;
|
#ifdef STBI_THREAD_LOCAL
|
||||||
|
STBI_THREAD_LOCAL
|
||||||
|
#endif
|
||||||
|
const char *stbi__g_failure_reason;
|
||||||
|
|
||||||
STBIDEF const char *stbi_failure_reason(void)
|
STBIDEF const char *stbi_failure_reason(void)
|
||||||
{
|
{
|
||||||
return stbi__g_failure_reason;
|
return stbi__g_failure_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef STBI_NO_FAILURE_STRINGS
|
||||||
static int stbi__err(const char *str)
|
static int stbi__err(const char *str)
|
||||||
{
|
{
|
||||||
stbi__g_failure_reason = str;
|
stbi__g_failure_reason = str;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *stbi__malloc(size_t size)
|
static void *stbi__malloc(size_t size)
|
||||||
{
|
{
|
||||||
@ -923,11 +982,13 @@ static int stbi__mul2sizes_valid(int a, int b)
|
|||||||
return a <= INT_MAX/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
|
// 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)
|
static int stbi__mad2sizes_valid(int a, int b, int add)
|
||||||
{
|
{
|
||||||
return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, 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
|
// 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)
|
static int stbi__mad3sizes_valid(int a, int b, int c, int add)
|
||||||
@ -945,12 +1006,14 @@ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
|
||||||
// mallocs with size overflow checking
|
// mallocs with size overflow checking
|
||||||
static void *stbi__malloc_mad2(int a, int b, int add)
|
static void *stbi__malloc_mad2(int a, int b, int add)
|
||||||
{
|
{
|
||||||
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
|
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
|
||||||
return stbi__malloc(a*b + add);
|
return stbi__malloc(a*b + add);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *stbi__malloc_mad3(int a, int b, int c, int add)
|
static void *stbi__malloc_mad3(int a, int b, int c, int add)
|
||||||
{
|
{
|
||||||
@ -994,13 +1057,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);
|
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
|
||||||
#endif
|
#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)
|
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)
|
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
|
memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
|
||||||
@ -1022,6 +1101,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
#endif
|
#endif
|
||||||
#ifndef STBI_NO_PSD
|
#ifndef STBI_NO_PSD
|
||||||
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
||||||
|
#else
|
||||||
|
STBI_NOTUSED(bpc);
|
||||||
#endif
|
#endif
|
||||||
#ifndef STBI_NO_PIC
|
#ifndef STBI_NO_PIC
|
||||||
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
||||||
@ -1124,8 +1205,10 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
|
||||||
|
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||||
|
|
||||||
if (ri.bits_per_channel != 8) {
|
if (ri.bits_per_channel != 8) {
|
||||||
STBI_ASSERT(ri.bits_per_channel == 16);
|
|
||||||
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||||
ri.bits_per_channel = 8;
|
ri.bits_per_channel = 8;
|
||||||
}
|
}
|
||||||
@ -1148,8 +1231,10 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
|
||||||
|
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||||
|
|
||||||
if (ri.bits_per_channel != 16) {
|
if (ri.bits_per_channel != 16) {
|
||||||
STBI_ASSERT(ri.bits_per_channel == 8);
|
|
||||||
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||||
ri.bits_per_channel = 16;
|
ri.bits_per_channel = 16;
|
||||||
}
|
}
|
||||||
@ -1452,6 +1537,7 @@ enum
|
|||||||
static void stbi__refill_buffer(stbi__context *s)
|
static void stbi__refill_buffer(stbi__context *s)
|
||||||
{
|
{
|
||||||
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
|
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
|
||||||
|
s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
// at end of file, treat same as if from memory, but need to handle case
|
// at end of file, treat same as if from memory, but need to handle case
|
||||||
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
|
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
|
||||||
@ -1476,6 +1562,9 @@ stbi_inline static stbi_uc stbi__get8(stbi__context *s)
|
|||||||
return 0;
|
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)
|
stbi_inline static int stbi__at_eof(stbi__context *s)
|
||||||
{
|
{
|
||||||
if (s->io.read) {
|
if (s->io.read) {
|
||||||
@ -1487,9 +1576,14 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
|
|||||||
|
|
||||||
return s->img_buffer >= s->img_buffer_end;
|
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)
|
static void stbi__skip(stbi__context *s, int n)
|
||||||
{
|
{
|
||||||
|
if (n == 0) return; // already there!
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
s->img_buffer = s->img_buffer_end;
|
s->img_buffer = s->img_buffer_end;
|
||||||
return;
|
return;
|
||||||
@ -1504,7 +1598,11 @@ static void stbi__skip(stbi__context *s, int n)
|
|||||||
}
|
}
|
||||||
s->img_buffer += 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)
|
static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
|
||||||
{
|
{
|
||||||
if (s->io.read) {
|
if (s->io.read) {
|
||||||
@ -1528,18 +1626,27 @@ static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
|
|||||||
} else
|
} else
|
||||||
return 0;
|
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)
|
static int stbi__get16be(stbi__context *s)
|
||||||
{
|
{
|
||||||
int z = stbi__get8(s);
|
int z = stbi__get8(s);
|
||||||
return (z << 8) + 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)
|
static stbi__uint32 stbi__get32be(stbi__context *s)
|
||||||
{
|
{
|
||||||
stbi__uint32 z = stbi__get16be(s);
|
stbi__uint32 z = stbi__get16be(s);
|
||||||
return (z << 16) + stbi__get16be(s);
|
return (z << 16) + stbi__get16be(s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
|
#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
|
||||||
// nothing
|
// nothing
|
||||||
@ -1561,7 +1668,9 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
|
|||||||
|
|
||||||
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
|
#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
|
// generic converter from built-in img_n to req_comp
|
||||||
@ -1577,7 +1686,11 @@ static stbi_uc stbi__compute_y(int r, int g, int b)
|
|||||||
{
|
{
|
||||||
return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8);
|
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)
|
static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
@ -1613,7 +1726,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||||
default: STBI_ASSERT(0);
|
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion");
|
||||||
}
|
}
|
||||||
#undef STBI__CASE
|
#undef STBI__CASE
|
||||||
}
|
}
|
||||||
@ -1621,12 +1734,20 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||||||
STBI_FREE(data);
|
STBI_FREE(data);
|
||||||
return good;
|
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)
|
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
||||||
{
|
{
|
||||||
return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
|
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)
|
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
@ -1662,7 +1783,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|||||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||||
default: STBI_ASSERT(0);
|
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion");
|
||||||
}
|
}
|
||||||
#undef STBI__CASE
|
#undef STBI__CASE
|
||||||
}
|
}
|
||||||
@ -1670,6 +1791,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|||||||
STBI_FREE(data);
|
STBI_FREE(data);
|
||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef STBI_NO_LINEAR
|
#ifndef STBI_NO_LINEAR
|
||||||
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
||||||
@ -1970,7 +2092,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
|
|||||||
|
|
||||||
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
|
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
|
||||||
k = stbi_lrot(j->code_buffer, n);
|
k = stbi_lrot(j->code_buffer, n);
|
||||||
STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
|
if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
|
||||||
j->code_buffer = k & ~stbi__bmask[n];
|
j->code_buffer = k & ~stbi__bmask[n];
|
||||||
k &= stbi__bmask[n];
|
k &= stbi__bmask[n];
|
||||||
j->code_bits -= n;
|
j->code_bits -= n;
|
||||||
@ -2081,6 +2203,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
|
|||||||
// first scan for DC coefficient, must be first
|
// first scan for DC coefficient, must be first
|
||||||
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
|
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
|
||||||
t = stbi__jpeg_huff_decode(j, hdc);
|
t = stbi__jpeg_huff_decode(j, hdc);
|
||||||
|
if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||||
diff = t ? stbi__extend_receive(j, t) : 0;
|
diff = t ? stbi__extend_receive(j, t) : 0;
|
||||||
|
|
||||||
dc = j->img_comp[b].dc_pred + diff;
|
dc = j->img_comp[b].dc_pred + diff;
|
||||||
@ -3071,6 +3194,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|||||||
p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
|
p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
|
||||||
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
|
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
|
||||||
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
c = stbi__get8(s);
|
c = stbi__get8(s);
|
||||||
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
||||||
s->img_n = c;
|
s->img_n = c;
|
||||||
@ -3951,16 +4076,23 @@ typedef struct
|
|||||||
stbi__zhuffman z_length, z_distance;
|
stbi__zhuffman z_length, z_distance;
|
||||||
} stbi__zbuf;
|
} stbi__zbuf;
|
||||||
|
|
||||||
|
stbi_inline static int stbi__zeof(stbi__zbuf *z)
|
||||||
|
{
|
||||||
|
return (z->zbuffer >= z->zbuffer_end);
|
||||||
|
}
|
||||||
|
|
||||||
stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
|
stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
|
||||||
{
|
{
|
||||||
if (z->zbuffer >= z->zbuffer_end) return 0;
|
return stbi__zeof(z) ? 0 : *z->zbuffer++;
|
||||||
return *z->zbuffer++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stbi__fill_bits(stbi__zbuf *z)
|
static void stbi__fill_bits(stbi__zbuf *z)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
|
if (z->code_buffer >= (1U << z->num_bits)) {
|
||||||
|
z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
|
z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
|
||||||
z->num_bits += 8;
|
z->num_bits += 8;
|
||||||
} while (z->num_bits <= 24);
|
} while (z->num_bits <= 24);
|
||||||
@ -3985,10 +4117,11 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
for (s=STBI__ZFAST_BITS+1; ; ++s)
|
for (s=STBI__ZFAST_BITS+1; ; ++s)
|
||||||
if (k < z->maxcode[s])
|
if (k < z->maxcode[s])
|
||||||
break;
|
break;
|
||||||
if (s == 16) return -1; // invalid code!
|
if (s >= 16) return -1; // invalid code!
|
||||||
// code size is s, so:
|
// code size is s, so:
|
||||||
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
|
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
|
||||||
STBI_ASSERT(z->size[b] == s);
|
if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
|
||||||
|
if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
|
||||||
a->code_buffer >>= s;
|
a->code_buffer >>= s;
|
||||||
a->num_bits -= s;
|
a->num_bits -= s;
|
||||||
return z->value[b];
|
return z->value[b];
|
||||||
@ -3997,7 +4130,12 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
||||||
{
|
{
|
||||||
int b,s;
|
int b,s;
|
||||||
if (a->num_bits < 16) stbi__fill_bits(a);
|
if (a->num_bits < 16) {
|
||||||
|
if (stbi__zeof(a)) {
|
||||||
|
return -1; /* report error for unexpected end of data. */
|
||||||
|
}
|
||||||
|
stbi__fill_bits(a);
|
||||||
|
}
|
||||||
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
||||||
if (b) {
|
if (b) {
|
||||||
s = b >> 9;
|
s = b >> 9;
|
||||||
@ -4011,13 +4149,16 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
||||||
{
|
{
|
||||||
char *q;
|
char *q;
|
||||||
int cur, limit, old_limit;
|
unsigned int cur, limit, old_limit;
|
||||||
z->zout = zout;
|
z->zout = zout;
|
||||||
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
||||||
cur = (int) (z->zout - z->zout_start);
|
cur = (unsigned int) (z->zout - z->zout_start);
|
||||||
limit = old_limit = (int) (z->zout_end - z->zout_start);
|
limit = old_limit = (unsigned) (z->zout_end - z->zout_start);
|
||||||
while (cur + n > limit)
|
if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory");
|
||||||
|
while (cur + n > limit) {
|
||||||
|
if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory");
|
||||||
limit *= 2;
|
limit *= 2;
|
||||||
|
}
|
||||||
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
||||||
STBI_NOTUSED(old_limit);
|
STBI_NOTUSED(old_limit);
|
||||||
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
||||||
@ -4115,11 +4256,12 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
|||||||
c = stbi__zreceive(a,2)+3;
|
c = stbi__zreceive(a,2)+3;
|
||||||
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
|
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
fill = lencodes[n-1];
|
fill = lencodes[n-1];
|
||||||
} else if (c == 17)
|
} else if (c == 17) {
|
||||||
c = stbi__zreceive(a,3)+3;
|
c = stbi__zreceive(a,3)+3;
|
||||||
else {
|
} else if (c == 18) {
|
||||||
STBI_ASSERT(c == 18);
|
|
||||||
c = stbi__zreceive(a,7)+11;
|
c = stbi__zreceive(a,7)+11;
|
||||||
|
} else {
|
||||||
|
return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
}
|
}
|
||||||
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
|
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
|
||||||
memset(lencodes+n, fill, c);
|
memset(lencodes+n, fill, c);
|
||||||
@ -4145,7 +4287,7 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a)
|
|||||||
a->code_buffer >>= 8;
|
a->code_buffer >>= 8;
|
||||||
a->num_bits -= 8;
|
a->num_bits -= 8;
|
||||||
}
|
}
|
||||||
STBI_ASSERT(a->num_bits == 0);
|
if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG");
|
||||||
// now fill header the normal way
|
// now fill header the normal way
|
||||||
while (k < 4)
|
while (k < 4)
|
||||||
header[k++] = stbi__zget8(a);
|
header[k++] = stbi__zget8(a);
|
||||||
@ -4167,6 +4309,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
|
|||||||
int cm = cmf & 15;
|
int cm = cmf & 15;
|
||||||
/* int cinfo = cmf >> 4; */
|
/* int cinfo = cmf >> 4; */
|
||||||
int flg = stbi__zget8(a);
|
int flg = stbi__zget8(a);
|
||||||
|
if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
||||||
if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
|
||||||
if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
|
if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
|
||||||
if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
|
if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
|
||||||
@ -4428,7 +4571,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
return stbi__err("invalid filter","Corrupt PNG");
|
return stbi__err("invalid filter","Corrupt PNG");
|
||||||
|
|
||||||
if (depth < 8) {
|
if (depth < 8) {
|
||||||
STBI_ASSERT(img_width_bytes <= x);
|
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
|
||||||
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
||||||
filter_bytes = 1;
|
filter_bytes = 1;
|
||||||
width = img_width_bytes;
|
width = img_width_bytes;
|
||||||
@ -4823,8 +4966,10 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
|
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
|
||||||
first = 0;
|
first = 0;
|
||||||
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
||||||
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
s->img_x = stbi__get32be(s);
|
||||||
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
s->img_y = stbi__get32be(s);
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
|
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
|
||||||
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
||||||
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
||||||
@ -4941,6 +5086,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
++s->img_n;
|
++s->img_n;
|
||||||
}
|
}
|
||||||
STBI_FREE(z->expanded); z->expanded = NULL;
|
STBI_FREE(z->expanded); z->expanded = NULL;
|
||||||
|
// end of PNG chunk, read and skip CRC
|
||||||
|
stbi__get32be(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4971,10 +5118,12 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st
|
|||||||
void *result=NULL;
|
void *result=NULL;
|
||||||
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
||||||
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
||||||
if (p->depth < 8)
|
if (p->depth <= 8)
|
||||||
ri->bits_per_channel = 8;
|
ri->bits_per_channel = 8;
|
||||||
|
else if (p->depth == 16)
|
||||||
|
ri->bits_per_channel = 16;
|
||||||
else
|
else
|
||||||
ri->bits_per_channel = p->depth;
|
return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth");
|
||||||
result = p->out;
|
result = p->out;
|
||||||
p->out = NULL;
|
p->out = NULL;
|
||||||
if (req_comp && req_comp != p->s->img_out_n) {
|
if (req_comp && req_comp != p->s->img_out_n) {
|
||||||
@ -5079,7 +5228,7 @@ static int stbi__high_bit(unsigned int z)
|
|||||||
if (z >= 0x00100) { n += 8; z >>= 8; }
|
if (z >= 0x00100) { n += 8; z >>= 8; }
|
||||||
if (z >= 0x00010) { n += 4; z >>= 4; }
|
if (z >= 0x00010) { n += 4; z >>= 4; }
|
||||||
if (z >= 0x00004) { n += 2; z >>= 2; }
|
if (z >= 0x00004) { n += 2; z >>= 2; }
|
||||||
if (z >= 0x00002) { n += 1; z >>= 1; }
|
if (z >= 0x00002) { n += 1;/* >>= 1;*/ }
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5110,7 +5259,7 @@ static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
|||||||
v <<= -shift;
|
v <<= -shift;
|
||||||
else
|
else
|
||||||
v >>= shift;
|
v >>= shift;
|
||||||
STBI_ASSERT(v >= 0 && v < 256);
|
STBI_ASSERT(v < 256);
|
||||||
v >>= (8-bits);
|
v >>= (8-bits);
|
||||||
STBI_ASSERT(bits >= 0 && bits <= 8);
|
STBI_ASSERT(bits >= 0 && bits <= 8);
|
||||||
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
||||||
@ -5120,6 +5269,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
int bpp, offset, hsz;
|
int bpp, offset, hsz;
|
||||||
unsigned int mr,mg,mb,ma, all_a;
|
unsigned int mr,mg,mb,ma, all_a;
|
||||||
|
int extra_read;
|
||||||
} stbi__bmp_data;
|
} stbi__bmp_data;
|
||||||
|
|
||||||
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
||||||
@ -5132,6 +5282,9 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|||||||
info->offset = stbi__get32le(s);
|
info->offset = stbi__get32le(s);
|
||||||
info->hsz = hsz = stbi__get32le(s);
|
info->hsz = hsz = stbi__get32le(s);
|
||||||
info->mr = info->mg = info->mb = info->ma = 0;
|
info->mr = info->mg = info->mb = info->ma = 0;
|
||||||
|
info->extra_read = 14;
|
||||||
|
|
||||||
|
if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP");
|
||||||
|
|
||||||
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
||||||
if (hsz == 12) {
|
if (hsz == 12) {
|
||||||
@ -5175,6 +5328,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|||||||
info->mr = stbi__get32le(s);
|
info->mr = stbi__get32le(s);
|
||||||
info->mg = stbi__get32le(s);
|
info->mg = stbi__get32le(s);
|
||||||
info->mb = stbi__get32le(s);
|
info->mb = stbi__get32le(s);
|
||||||
|
info->extra_read += 12;
|
||||||
// not documented, but generated by photoshop and handled by mspaint
|
// not documented, but generated by photoshop and handled by mspaint
|
||||||
if (info->mr == info->mg && info->mg == info->mb) {
|
if (info->mr == info->mg && info->mg == info->mb) {
|
||||||
// ?!?!?
|
// ?!?!?
|
||||||
@ -5223,6 +5377,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
flip_vertically = ((int) s->img_y) > 0;
|
flip_vertically = ((int) s->img_y) > 0;
|
||||||
s->img_y = abs((int) s->img_y);
|
s->img_y = abs((int) s->img_y);
|
||||||
|
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
mr = info.mr;
|
mr = info.mr;
|
||||||
mg = info.mg;
|
mg = info.mg;
|
||||||
mb = info.mb;
|
mb = info.mb;
|
||||||
@ -5231,13 +5388,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
|
|
||||||
if (info.hsz == 12) {
|
if (info.hsz == 12) {
|
||||||
if (info.bpp < 24)
|
if (info.bpp < 24)
|
||||||
psize = (info.offset - 14 - 24) / 3;
|
psize = (info.offset - info.extra_read - 24) / 3;
|
||||||
} else {
|
} else {
|
||||||
if (info.bpp < 16)
|
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->callback_already_read + (int) (s->img_buffer - s->img_buffer_original));
|
||||||
|
if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
|
||||||
|
return stbi__errpuc("bad offset", "Corrupt BMP");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->img_n = ma ? 4 : 3;
|
if (info.bpp == 24 && ma == 0xff000000)
|
||||||
|
s->img_n = 3;
|
||||||
|
else
|
||||||
|
s->img_n = ma ? 4 : 3;
|
||||||
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
||||||
target = req_comp;
|
target = req_comp;
|
||||||
else
|
else
|
||||||
@ -5259,7 +5425,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
if (info.hsz != 12) stbi__get8(s);
|
if (info.hsz != 12) stbi__get8(s);
|
||||||
pal[i][3] = 255;
|
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;
|
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 == 4) width = (s->img_x + 1) >> 1;
|
||||||
else if (info.bpp == 8) width = s->img_x;
|
else if (info.bpp == 8) width = s->img_x;
|
||||||
@ -5308,7 +5474,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 rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
|
||||||
int z = 0;
|
int z = 0;
|
||||||
int easy=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;
|
if (info.bpp == 24) width = 3 * s->img_x;
|
||||||
else if (info.bpp == 16) width = 2*s->img_x;
|
else if (info.bpp == 16) width = 2*s->img_x;
|
||||||
else /* bpp = 32 and pad = 0 */ width=0;
|
else /* bpp = 32 and pad = 0 */ width=0;
|
||||||
@ -5326,6 +5492,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
|
gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
|
||||||
bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
|
bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
|
||||||
ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
|
ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
|
||||||
|
if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
|
||||||
}
|
}
|
||||||
for (j=0; j < (int) s->img_y; ++j) {
|
for (j=0; j < (int) s->img_y; ++j) {
|
||||||
if (easy) {
|
if (easy) {
|
||||||
@ -5547,6 +5714,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
int RLE_repeating = 0;
|
int RLE_repeating = 0;
|
||||||
int read_next_pixel = 1;
|
int read_next_pixel = 1;
|
||||||
STBI_NOTUSED(ri);
|
STBI_NOTUSED(ri);
|
||||||
|
STBI_NOTUSED(tga_x_origin); // @TODO
|
||||||
|
STBI_NOTUSED(tga_y_origin); // @TODO
|
||||||
|
|
||||||
|
if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
// do a tiny bit of precessing
|
// do a tiny bit of precessing
|
||||||
if ( tga_image_type >= 8 )
|
if ( tga_image_type >= 8 )
|
||||||
@ -5587,6 +5759,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
// do I need to load a palette?
|
// do I need to load a palette?
|
||||||
if ( tga_indexed)
|
if ( tga_indexed)
|
||||||
{
|
{
|
||||||
|
if (tga_palette_len == 0) { /* you have to have at least one entry! */
|
||||||
|
STBI_FREE(tga_data);
|
||||||
|
return stbi__errpuc("bad palette", "Corrupt TGA");
|
||||||
|
}
|
||||||
|
|
||||||
// any data to skip? (offset usually = 0)
|
// any data to skip? (offset usually = 0)
|
||||||
stbi__skip(s, tga_palette_start );
|
stbi__skip(s, tga_palette_start );
|
||||||
// load the palette
|
// load the palette
|
||||||
@ -5710,6 +5887,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
// Microsoft's C compilers happy... [8^(
|
// Microsoft's C compilers happy... [8^(
|
||||||
tga_palette_start = tga_palette_len = tga_palette_bits =
|
tga_palette_start = tga_palette_len = tga_palette_bits =
|
||||||
tga_x_origin = tga_y_origin = 0;
|
tga_x_origin = tga_y_origin = 0;
|
||||||
|
STBI_NOTUSED(tga_palette_start);
|
||||||
// OK, done
|
// OK, done
|
||||||
return tga_data;
|
return tga_data;
|
||||||
}
|
}
|
||||||
@ -5794,6 +5972,9 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
h = stbi__get32be(s);
|
h = stbi__get32be(s);
|
||||||
w = stbi__get32be(s);
|
w = stbi__get32be(s);
|
||||||
|
|
||||||
|
if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
// Make sure the depth is 8 bits.
|
// Make sure the depth is 8 bits.
|
||||||
bitdepth = stbi__get16be(s);
|
bitdepth = stbi__get16be(s);
|
||||||
if (bitdepth != 8 && bitdepth != 16)
|
if (bitdepth != 8 && bitdepth != 16)
|
||||||
@ -6148,6 +6329,10 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
|
|||||||
|
|
||||||
x = stbi__get16be(s);
|
x = stbi__get16be(s);
|
||||||
y = stbi__get16be(s);
|
y = stbi__get16be(s);
|
||||||
|
|
||||||
|
if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
|
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
|
||||||
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
|
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
|
||||||
|
|
||||||
@ -6256,6 +6441,9 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
|
|||||||
g->ratio = stbi__get8(s);
|
g->ratio = stbi__get8(s);
|
||||||
g->transparent = -1;
|
g->transparent = -1;
|
||||||
|
|
||||||
|
if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
|
if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
|
||||||
|
|
||||||
if (is_info) return 1;
|
if (is_info) return 1;
|
||||||
@ -6433,7 +6621,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|||||||
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
||||||
first_frame = 1;
|
first_frame = 1;
|
||||||
} else {
|
} else {
|
||||||
// second frame - how do we dispoase of the previous one?
|
// second frame - how do we dispose of the previous one?
|
||||||
dispose = (g->eflags & 0x1C) >> 2;
|
dispose = (g->eflags & 0x1C) >> 2;
|
||||||
pcount = g->w * g->h;
|
pcount = g->w * g->h;
|
||||||
|
|
||||||
@ -6587,6 +6775,8 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||||||
stbi_uc *two_back = 0;
|
stbi_uc *two_back = 0;
|
||||||
stbi__gif g;
|
stbi__gif g;
|
||||||
int stride;
|
int stride;
|
||||||
|
int out_size = 0;
|
||||||
|
int delays_size = 0;
|
||||||
memset(&g, 0, sizeof(g));
|
memset(&g, 0, sizeof(g));
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = 0;
|
*delays = 0;
|
||||||
@ -6603,14 +6793,28 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||||||
stride = g.w * g.h * 4;
|
stride = g.w * g.h * 4;
|
||||||
|
|
||||||
if (out) {
|
if (out) {
|
||||||
out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
|
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, 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;
|
||||||
|
out_size = layers * stride;
|
||||||
|
}
|
||||||
|
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
|
*delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
|
||||||
|
delays_size = layers * sizeof(int);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out = (stbi_uc*)stbi__malloc( layers * stride );
|
out = (stbi_uc*)stbi__malloc( layers * stride );
|
||||||
|
out_size = layers * stride;
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
||||||
|
delays_size = layers * sizeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy( out + ((layers - 1) * stride), u, stride );
|
memcpy( out + ((layers - 1) * stride), u, stride );
|
||||||
@ -6789,6 +6993,9 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
token += 3;
|
token += 3;
|
||||||
width = (int) strtol(token, NULL, 10);
|
width = (int) strtol(token, NULL, 10);
|
||||||
|
|
||||||
|
if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
|
||||||
|
if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
*x = width;
|
*x = width;
|
||||||
*y = height;
|
*y = height;
|
||||||
|
|
||||||
@ -6936,7 +7143,12 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
return 0;
|
return 0;
|
||||||
if (x) *x = s->img_x;
|
if (x) *x = s->img_x;
|
||||||
if (y) *y = s->img_y;
|
if (y) *y = s->img_y;
|
||||||
if (comp) *comp = info.ma ? 4 : 3;
|
if (comp) {
|
||||||
|
if (info.bpp == 24 && info.ma == 0xff000000)
|
||||||
|
*comp = 3;
|
||||||
|
else
|
||||||
|
*comp = info.ma ? 4 : 3;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7098,6 +7310,9 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||||||
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
|
||||||
|
|
||||||
*x = s->img_x;
|
*x = s->img_x;
|
||||||
*y = s->img_y;
|
*y = s->img_y;
|
||||||
if (comp) *comp = s->img_n;
|
if (comp) *comp = s->img_n;
|
||||||
|
Loading…
Reference in New Issue
Block a user