[core] update stb image lib to latest master
This commit is contained in:
parent
23640d06b1
commit
7874d2eb7e
|
@ -1,4 +1,4 @@
|
||||||
/* stb_image - v2.22 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
|
@ -48,6 +48,9 @@ LICENSE
|
||||||
|
|
||||||
RECENT REVISION HISTORY:
|
RECENT REVISION HISTORY:
|
||||||
|
|
||||||
|
2.25 (2020-02-02) fix warnings
|
||||||
|
2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
|
||||||
|
2.23 (2019-08-11) fix clang static analysis warning
|
||||||
2.22 (2019-03-04) gif fixes, fix warnings
|
2.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
|
||||||
|
@ -104,7 +107,8 @@ RECENT REVISION HISTORY:
|
||||||
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
||||||
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
||||||
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
||||||
Blazej Dariusz Roszkowski github:Michaelangel007
|
Brad Weinberger Matvey Cherevko github:Michaelangel007
|
||||||
|
Blazej Dariusz Roszkowski Alexander Veselov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||||
|
@ -433,7 +437,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 +470,11 @@ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
|
||||||
// flip the image vertically, so the first pixel in the output array is the bottom left
|
// 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 +571,17 @@ 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 (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||||
|
#define STBI_THREAD_LOCAL _Thread_local
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define STBI_THREAD_LOCAL __thread
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define STBI_THREAD_LOCAL __declspec(thread)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef unsigned short stbi__uint16;
|
typedef unsigned short stbi__uint16;
|
||||||
|
@ -872,19 +892,24 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||||
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
|
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 +948,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 +972,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 +1023,29 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
|
||||||
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
|
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 +1067,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);
|
||||||
|
@ -1476,6 +1523,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,7 +1537,11 @@ 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) {
|
if (n < 0) {
|
||||||
|
@ -1504,7 +1558,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 +1586,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 +1628,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 +1646,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;
|
||||||
|
@ -1621,12 +1694,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;
|
||||||
|
@ -1670,6 +1751,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)
|
||||||
|
@ -4941,6 +5023,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5079,7 +5163,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 +5194,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 +5204,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 +5217,7 @@ 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 (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 +5261,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) {
|
||||||
// ?!?!?
|
// ?!?!?
|
||||||
|
@ -5231,13 +5318,19 @@ 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->img_buffer - s->buffer_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +5352,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||||
if (info.hsz != 12) stbi__get8(s);
|
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 +5401,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||||
int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
|
int 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;
|
||||||
|
@ -5547,6 +5640,8 @@ 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
|
||||||
|
|
||||||
// do a tiny bit of precessing
|
// do a tiny bit of precessing
|
||||||
if ( tga_image_type >= 8 )
|
if ( tga_image_type >= 8 )
|
||||||
|
@ -5710,6 +5805,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;
|
||||||
}
|
}
|
||||||
|
@ -6603,7 +6699,15 @@ 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( out, layers * stride );
|
||||||
|
if (NULL == tmp) {
|
||||||
|
STBI_FREE(g.out);
|
||||||
|
STBI_FREE(g.history);
|
||||||
|
STBI_FREE(g.background);
|
||||||
|
return stbi__errpuc("outofmem", "Out of memory");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out = (stbi_uc*) tmp;
|
||||||
if (delays) {
|
if (delays) {
|
||||||
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
|
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
|
||||||
}
|
}
|
||||||
|
@ -6936,7 +7040,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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* stb_image_write - v1.13 - public domain - http://nothings.org/stb/stb_image_write.h
|
/* stb_image_write - v1.14 - public domain - http://nothings.org/stb
|
||||||
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
|
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
|
@ -10,11 +10,6 @@
|
||||||
|
|
||||||
Will probably not work correctly with strict-aliasing optimizations.
|
Will probably not work correctly with strict-aliasing optimizations.
|
||||||
|
|
||||||
If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
|
|
||||||
compilation warnings or even errors. To avoid this, also before #including,
|
|
||||||
|
|
||||||
#define STBI_MSC_SECURE_CRT
|
|
||||||
|
|
||||||
ABOUT:
|
ABOUT:
|
||||||
|
|
||||||
This header file is a library for writing images to C stdio or a callback.
|
This header file is a library for writing images to C stdio or a callback.
|
||||||
|
@ -252,17 +247,17 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
|
||||||
#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
|
#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
|
||||||
|
|
||||||
#ifdef STB_IMAGE_WRITE_STATIC
|
#ifdef STB_IMAGE_WRITE_STATIC
|
||||||
static int stbi__flip_vertically_on_write=0;
|
|
||||||
static int stbi_write_png_compression_level = 8;
|
static int stbi_write_png_compression_level = 8;
|
||||||
static int stbi_write_tga_with_rle = 1;
|
static int stbi_write_tga_with_rle = 1;
|
||||||
static int stbi_write_force_png_filter = -1;
|
static int stbi_write_force_png_filter = -1;
|
||||||
#else
|
#else
|
||||||
int stbi_write_png_compression_level = 8;
|
int stbi_write_png_compression_level = 8;
|
||||||
int stbi__flip_vertically_on_write=0;
|
|
||||||
int stbi_write_tga_with_rle = 1;
|
int stbi_write_tga_with_rle = 1;
|
||||||
int stbi_write_force_png_filter = -1;
|
int stbi_write_force_png_filter = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int stbi__flip_vertically_on_write = 0;
|
||||||
|
|
||||||
STBIWDEF void stbi_flip_vertically_on_write(int flag)
|
STBIWDEF void stbi_flip_vertically_on_write(int flag)
|
||||||
{
|
{
|
||||||
stbi__flip_vertically_on_write = flag;
|
stbi__flip_vertically_on_write = flag;
|
||||||
|
@ -779,7 +774,7 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
|
||||||
|
|
||||||
#ifndef STBIW_ZLIB_COMPRESS
|
#ifndef STBIW_ZLIB_COMPRESS
|
||||||
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
|
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
|
||||||
#define stbiw__sbraw(a) ((int *) (a) - 2)
|
#define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
|
||||||
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
|
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
|
||||||
#define stbiw__sbn(a) stbiw__sbraw(a)[1]
|
#define stbiw__sbn(a) stbiw__sbraw(a)[1]
|
||||||
|
|
||||||
|
@ -873,7 +868,7 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
|
||||||
unsigned int bitbuf=0;
|
unsigned int bitbuf=0;
|
||||||
int i,j, bitcount=0;
|
int i,j, bitcount=0;
|
||||||
unsigned char *out = NULL;
|
unsigned char *out = NULL;
|
||||||
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
|
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
|
||||||
if (hash_table == NULL)
|
if (hash_table == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (quality < 5) quality = 5;
|
if (quality < 5) quality = 5;
|
||||||
|
@ -1276,26 +1271,31 @@ static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
|
||||||
bits[0] = val & ((1<<bits[1])-1);
|
bits[0] = val & ((1<<bits[1])-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
|
static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, int du_stride, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
|
||||||
const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
|
const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
|
||||||
const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
|
const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
|
||||||
int dataOff, i, diff, end0pos;
|
int dataOff, i, j, n, diff, end0pos, x, y;
|
||||||
int DU[64];
|
int DU[64];
|
||||||
|
|
||||||
// DCT rows
|
// DCT rows
|
||||||
for(dataOff=0; dataOff<64; dataOff+=8) {
|
for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
|
||||||
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
|
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
|
||||||
}
|
}
|
||||||
// DCT columns
|
// DCT columns
|
||||||
for(dataOff=0; dataOff<8; ++dataOff) {
|
for(dataOff=0; dataOff<8; ++dataOff) {
|
||||||
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+8], &CDU[dataOff+16], &CDU[dataOff+24], &CDU[dataOff+32], &CDU[dataOff+40], &CDU[dataOff+48], &CDU[dataOff+56]);
|
stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
|
||||||
|
&CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
|
||||||
}
|
}
|
||||||
// Quantize/descale/zigzag the coefficients
|
// Quantize/descale/zigzag the coefficients
|
||||||
for(i=0; i<64; ++i) {
|
for(y = 0, j=0; y < 8; ++y) {
|
||||||
float v = CDU[i]*fdtbl[i];
|
for(x = 0; x < 8; ++x,++j) {
|
||||||
// DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
|
float v;
|
||||||
// ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
|
i = y*du_stride+x;
|
||||||
DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
|
v = CDU[i]*fdtbl[j];
|
||||||
|
// DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
|
||||||
|
// ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
|
||||||
|
DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode DC
|
// Encode DC
|
||||||
|
@ -1413,7 +1413,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
|
||||||
static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
|
static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
|
||||||
1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
|
1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
|
||||||
|
|
||||||
int row, col, i, k;
|
int row, col, i, k, subsample;
|
||||||
float fdtbl_Y[64], fdtbl_UV[64];
|
float fdtbl_Y[64], fdtbl_UV[64];
|
||||||
unsigned char YTable[64], UVTable[64];
|
unsigned char YTable[64], UVTable[64];
|
||||||
|
|
||||||
|
@ -1422,6 +1422,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
|
||||||
}
|
}
|
||||||
|
|
||||||
quality = quality ? quality : 90;
|
quality = quality ? quality : 90;
|
||||||
|
subsample = quality <= 90 ? 1 : 0;
|
||||||
quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
|
quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
|
||||||
quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
|
quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
|
||||||
|
|
||||||
|
@ -1444,7 +1445,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
|
||||||
static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
|
static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
|
||||||
static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
|
static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
|
||||||
const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
|
const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
|
||||||
3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
|
3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
|
||||||
s->func(s->context, (void*)head0, sizeof(head0));
|
s->func(s->context, (void*)head0, sizeof(head0));
|
||||||
s->func(s->context, (void*)YTable, sizeof(YTable));
|
s->func(s->context, (void*)YTable, sizeof(YTable));
|
||||||
stbiw__putc(s, 1);
|
stbiw__putc(s, 1);
|
||||||
|
@ -1467,36 +1468,74 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
|
||||||
// Encode 8x8 macroblocks
|
// Encode 8x8 macroblocks
|
||||||
{
|
{
|
||||||
static const unsigned short fillBits[] = {0x7F, 7};
|
static const unsigned short fillBits[] = {0x7F, 7};
|
||||||
const unsigned char *imageData = (const unsigned char *)data;
|
|
||||||
int DCY=0, DCU=0, DCV=0;
|
int DCY=0, DCU=0, DCV=0;
|
||||||
int bitBuf=0, bitCnt=0;
|
int bitBuf=0, bitCnt=0;
|
||||||
// comp == 2 is grey+alpha (alpha is ignored)
|
// comp == 2 is grey+alpha (alpha is ignored)
|
||||||
int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
|
int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
|
||||||
|
const unsigned char *dataR = (const unsigned char *)data;
|
||||||
|
const unsigned char *dataG = dataR + ofsG;
|
||||||
|
const unsigned char *dataB = dataR + ofsB;
|
||||||
int x, y, pos;
|
int x, y, pos;
|
||||||
for(y = 0; y < height; y += 8) {
|
if(subsample) {
|
||||||
for(x = 0; x < width; x += 8) {
|
for(y = 0; y < height; y += 16) {
|
||||||
float YDU[64], UDU[64], VDU[64];
|
for(x = 0; x < width; x += 16) {
|
||||||
for(row = y, pos = 0; row < y+8; ++row) {
|
float Y[256], U[256], V[256];
|
||||||
// row >= height => use last input row
|
for(row = y, pos = 0; row < y+16; ++row) {
|
||||||
int clamped_row = (row < height) ? row : height - 1;
|
// row >= height => use last input row
|
||||||
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
|
int clamped_row = (row < height) ? row : height - 1;
|
||||||
for(col = x; col < x+8; ++col, ++pos) {
|
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
|
||||||
float r, g, b;
|
for(col = x; col < x+16; ++col, ++pos) {
|
||||||
// if col >= width => use pixel from last input column
|
// if col >= width => use pixel from last input column
|
||||||
int p = base_p + ((col < width) ? col : (width-1))*comp;
|
int p = base_p + ((col < width) ? col : (width-1))*comp;
|
||||||
|
float r = dataR[p], g = dataG[p], b = dataB[p];
|
||||||
|
Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
|
||||||
|
U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
|
||||||
|
V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
||||||
|
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
||||||
|
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
||||||
|
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
||||||
|
|
||||||
r = imageData[p+0];
|
// subsample U,V
|
||||||
g = imageData[p+ofsG];
|
{
|
||||||
b = imageData[p+ofsB];
|
float subU[64], subV[64];
|
||||||
YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128;
|
int yy, xx;
|
||||||
UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b;
|
for(yy = 0, pos = 0; yy < 8; ++yy) {
|
||||||
VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b;
|
for(xx = 0; xx < 8; ++xx, ++pos) {
|
||||||
|
int j = yy*32+xx*2;
|
||||||
|
subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
|
||||||
|
subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
|
||||||
|
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(y = 0; y < height; y += 8) {
|
||||||
|
for(x = 0; x < width; x += 8) {
|
||||||
|
float Y[64], U[64], V[64];
|
||||||
|
for(row = y, pos = 0; row < y+8; ++row) {
|
||||||
|
// row >= height => use last input row
|
||||||
|
int clamped_row = (row < height) ? row : height - 1;
|
||||||
|
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
|
||||||
|
for(col = x; col < x+8; ++col, ++pos) {
|
||||||
|
// if col >= width => use pixel from last input column
|
||||||
|
int p = base_p + ((col < width) ? col : (width-1))*comp;
|
||||||
|
float r = dataR[p], g = dataG[p], b = dataB[p];
|
||||||
|
Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
|
||||||
|
U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
|
||||||
|
V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT);
|
||||||
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
|
DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
|
||||||
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
|
DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1535,6 +1574,11 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
|
||||||
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
|
||||||
/* Revision history
|
/* Revision history
|
||||||
|
1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
|
||||||
|
1.13
|
||||||
|
1.12
|
||||||
|
1.11 (2019-08-11)
|
||||||
|
|
||||||
1.10 (2019-02-07)
|
1.10 (2019-02-07)
|
||||||
support utf8 filenames in Windows; fix warnings and platform ifdefs
|
support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||||
1.09 (2018-02-11)
|
1.09 (2018-02-11)
|
||||||
|
|
Loading…
Reference in New Issue