From b372a1f86c7cf11a9b0023c06a51b90037781c70 Mon Sep 17 00:00:00 2001 From: Sergio Gonzalez Date: Mon, 21 Sep 2015 12:18:18 -0500 Subject: [PATCH 01/42] Avoid macro redefinition in Win32 --- stb_image_write.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..b963604 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -98,12 +98,12 @@ CREDITS: github:Chribba Guillaume Chereau github:jry2 - + LICENSE This software is in the public domain. Where that dedication is not recognized, you are granted a perpetual, irrevocable license to copy, -distribute, and modify this file as you see fit. +distribute, and modify this file as you see fit. */ @@ -144,8 +144,12 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, #ifdef STB_IMAGE_WRITE_IMPLEMENTATION #ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE #define _CRT_NONSTDC_NO_DEPRECATE + #endif #endif #ifndef STBI_WRITE_NO_STDIO From 232927699c692be310af8252e64c43a73fcd0c17 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Wed, 23 Sep 2015 05:03:26 -0700 Subject: [PATCH 02/42] Vita warning fix --- stb_truetype.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index 00d22eb..bf546c3 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v1.08 - public domain +// stb_truetype.h - v1.09 - public domain // authored from 2009-2015 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -42,12 +42,14 @@ // Sergey Popov // Giumo X. Clanjor // Higor Euripedes +// Thomas Fields // // Misc other: // Ryan Gordon // // VERSION HISTORY // +// 1.09 (????-??-??) warning fix // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; // variant PackFontRanges to pack and render in separate phases; @@ -1556,7 +1558,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { - int x0,y0,x1,y1; + int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { // e.g. space character if (ix0) *ix0 = 0; From 007c850b485823cd66439133f9a79ad295464198 Mon Sep 17 00:00:00 2001 From: Rasmus Christian Pedersen Date: Fri, 25 Sep 2015 19:46:27 +0200 Subject: [PATCH 03/42] nobug: removed unused variable 'k' --- stb_image_write.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..ecc285f 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -795,7 +795,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l { // compute adler32 on input - unsigned int k=0, s1=1, s2=0; + unsigned int s1=1, s2=0; int blocklen = (int) (data_len % 5552); j=0; while (j < data_len) { From 35fcd0817fe192941a8840365bb783314b435667 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Fri, 9 Oct 2015 20:46:59 -0500 Subject: [PATCH 04/42] stb_vorbis.c: Silence -pedantic warning. --- stb_vorbis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 98e96fb..dded3c6 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -367,7 +367,7 @@ enum STBVorbisError VORBIS_invalid_first_page, VORBIS_bad_packet_type, VORBIS_cant_find_last_page, - VORBIS_seek_failed, + VORBIS_seek_failed }; @@ -1576,7 +1576,7 @@ enum { VORBIS_packet_id = 1, VORBIS_packet_comment = 3, - VORBIS_packet_setup = 5, + VORBIS_packet_setup = 5 }; static int codebook_decode_scalar_raw(vorb *f, Codebook *c) From f1d401845ff937207772b10917713abfac25e911 Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Sat, 17 Oct 2015 17:33:00 +0200 Subject: [PATCH 05/42] Fix race condition in static crc_table If calling stbi_write_png concurrently the static array crc_table would be shared between threads causing data-races. --- stb_image_write.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..6f440c1 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -817,14 +817,76 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l unsigned int stbiw__crc32(unsigned char *buffer, int len) { - static unsigned int crc_table[256]; + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + unsigned int crc = ~0u; - int i,j; - if (crc_table[1] == 0) - for(i=0; i < 256; i++) - for (crc_table[i]=i, j=0; j < 8; ++j) - crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0); - for (i=0; i < len; ++i) + for (int i=0; i < len; ++i) crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; return ~crc; } From 22dd50f25653944863898601ee66bdef121fd51a Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Tue, 20 Oct 2015 22:03:50 +0200 Subject: [PATCH 06/42] Fix documentation error --- stb_image_write.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..6014164 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -34,7 +34,7 @@ USAGE: int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); - int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); There are also four equivalent functions that use an arbitrary write function. You are expected to open/close your file-equivalent before and after calling these: From b95858a2f772c83421f02ef2e3352d737f78178e Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Tue, 20 Oct 2015 23:22:27 +0200 Subject: [PATCH 07/42] Add bitmask to unsigned char casts to fix MSVC runtime checks --- stb_image_write.h | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..2036c83 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -180,6 +180,8 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, #define STBIW_ASSERT(x) assert(x) #endif +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + typedef struct { stbi_write_func *func; @@ -228,21 +230,21 @@ static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) while (*fmt) { switch (*fmt++) { case ' ': break; - case '1': { unsigned char x = (unsigned char) va_arg(v, int); + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); s->func(s->context,&x,1); break; } case '2': { int x = va_arg(v,int); unsigned char b[2]; - b[0] = (unsigned char) x; - b[1] = (unsigned char) (x>>8); + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); s->func(s->context,b,2); break; } case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; - b[0]=(unsigned char)x; - b[1]=(unsigned char)(x>>8); - b[2]=(unsigned char)(x>>16); - b[3]=(unsigned char)(x>>24); + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); s->func(s->context,b,4); break; } default: @@ -419,13 +421,13 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v } if (diff) { - unsigned char header = (unsigned char) (len - 1); + unsigned char header = STBIW_UCHAR(len - 1); s->func(s->context, &header, 1); for (k = 0; k < len; ++k) { stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); } } else { - unsigned char header = (unsigned char) (len - 129); + unsigned char header = STBIW_UCHAR(len - 129); s->func(s->context, &header, 1); stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); } @@ -481,7 +483,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) { - unsigned char lengthbyte = (unsigned char) (length+128); + unsigned char lengthbyte = STBIW_UCHAR(length+128); STBIW_ASSERT(length+128 <= 255); s->func(s->context, &lengthbyte, 1); s->func(s->context, &databyte, 1); @@ -489,7 +491,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) { - unsigned char lengthbyte = (unsigned char )(length & 0xff); + unsigned char lengthbyte = STBIW_UCHAR(length); STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code s->func(s->context, &lengthbyte, 1); s->func(s->context, data, length); @@ -660,7 +662,7 @@ static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) { while (*bitcount >= 8) { - stbiw__sbpush(data, (unsigned char) *bitbuffer); + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); *bitbuffer >>= 8; *bitcount -= 8; } @@ -804,10 +806,10 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l j += blocklen; blocklen = 5552; } - stbiw__sbpush(out, (unsigned char) (s2 >> 8)); - stbiw__sbpush(out, (unsigned char) s2); - stbiw__sbpush(out, (unsigned char) (s1 >> 8)); - stbiw__sbpush(out, (unsigned char) s1); + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); } *out_len = stbiw__sbn(out); // make returned pointer freeable @@ -829,7 +831,7 @@ unsigned int stbiw__crc32(unsigned char *buffer, int len) return ~crc; } -#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4) +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) @@ -842,9 +844,9 @@ static void stbiw__wpcrc(unsigned char **data, int len) static unsigned char stbiw__paeth(int a, int b, int c) { int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); - if (pa <= pb && pa <= pc) return (unsigned char) a; - if (pb <= pc) return (unsigned char) b; - return (unsigned char) c; + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); } unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) @@ -917,7 +919,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in stbiw__wp32(o, x); stbiw__wp32(o, y); *o++ = 8; - *o++ = (unsigned char) ctype[n]; + *o++ = STBIW_UCHAR(ctype[n]); *o++ = 0; *o++ = 0; *o++ = 0; From 8cea0090b2fcb193b32d9c33a5ee0155f23dfa64 Mon Sep 17 00:00:00 2001 From: Filip Wasil Date: Thu, 29 Oct 2015 16:09:21 +0100 Subject: [PATCH 08/42] Removie implicit cast to float When compiling with more restrictive compiler options such casting from double to float will cause a warning. Ex. GCC -Wdouble-promotion Signed-off-by: Filip Wasil --- stb_image_write.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..6c241ea 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -467,7 +467,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) int exponent; float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); - if (maxcomp < 1e-32) { + if (maxcomp < 1e-32f) { rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; } else { float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; From 8603c6e8095e1a10a2855c6029ba4bf65d77e827 Mon Sep 17 00:00:00 2001 From: svdijk Date: Thu, 5 Nov 2015 23:32:40 +0100 Subject: [PATCH 09/42] stb_image.h: Only define stbi__l2h_{gamme,scale} when needed. This fixes a (well, actually the only) compiler warning. --- stb_image.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stb_image.h b/stb_image.h index 0a9de39..0fcf37a 100644 --- a/stb_image.h +++ b/stb_image.h @@ -1186,14 +1186,15 @@ STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void #endif } -static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; +#ifndef STBI_NO_LINEAR static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; -#ifndef STBI_NO_LINEAR STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } #endif +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } From 9f1a587d22e8a11f7ce2b00dcc9699520343daf3 Mon Sep 17 00:00:00 2001 From: svdijk Date: Thu, 5 Nov 2015 23:34:44 +0100 Subject: [PATCH 10/42] stb_image.h: Fix/add some comments. --- stb_image.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stb_image.h b/stb_image.h index 0fcf37a..b9a6d64 100644 --- a/stb_image.h +++ b/stb_image.h @@ -461,12 +461,12 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, #ifndef STBI_NO_HDR STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); STBIDEF void stbi_hdr_to_ldr_scale(float scale); -#endif +#endif // STBI_NO_HDR #ifndef STBI_NO_LINEAR STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); STBIDEF void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_HDR +#endif // STBI_NO_LINEAR // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); From 0615df6c9b1eadfcbd0e65a6ca1f4ae3947919ee Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 00:45:17 -0800 Subject: [PATCH 11/42] allows comments in pgm/ppm headers --- stb_image.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/stb_image.h b/stb_image.h index 0a9de39..354807b 100644 --- a/stb_image.h +++ b/stb_image.h @@ -195,7 +195,7 @@ Omar Cornut (1/2/4-bit PNG) Ken Hamada Nicolas Guillemot (vertical flip) Cort Stratton Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski - Thibault Reuille + Junggon Kim (PNM comments) Thibault Reuille Paul Du Bois Guillaume George Jerry Jansson @@ -6222,8 +6222,16 @@ static int stbi__pnm_isspace(char c) static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) { - while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char) stbi__get8(s); + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } } static int stbi__pnm_isdigit(char c) From 6382e49063dd302785bf1d0055fdf15bc65f6359 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 00:54:49 -0800 Subject: [PATCH 12/42] don't crash if out of memory allocating a new active edge (assert in debug) --- stb_truetype.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index bf546c3..b57043e 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -49,7 +49,7 @@ // // VERSION HISTORY // -// 1.09 (????-??-??) warning fix +// 1.09 (????-??-??) warning fix; avoid crash on outofmem // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; // variant PackFontRanges to pack and render in separate phases; @@ -1674,6 +1674,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i { stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); if (!z) return z; // round dx down to avoid overshooting @@ -1695,6 +1696,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i { stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); //STBTT_assert(e->y0 <= start_point); if (!z) return z; z->fdx = dxdy; @@ -1819,21 +1821,23 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, while (e->y0 <= scan_y) { if (e->y1 > scan_y) { stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); - // find insertion point - if (active == NULL) - active = z; - else if (z->x < active->x) { - // insert at front - z->next = active; - active = z; - } else { - // find thing to insert AFTER - stbtt__active_edge *p = active; - while (p->next && p->next->x < z->x) - p = p->next; - // at this point, p->next->x is NOT < z->x - z->next = p->next; - p->next = z; + if (z != NULL) { + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } } } ++e; @@ -2103,10 +2107,12 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, while (e->y0 <= scan_y_bottom) { if (e->y0 != e->y1) { stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); - STBTT_assert(z->ey >= scan_y_top); - // insert at front - z->next = active; - active = z; + if (z != NULL) { + STBTT_assert(z->ey >= scan_y_top); + // insert at front + z->next = active; + active = z; + } } ++e; } From 16fc63404d5b9256564feb54bcb44f255a6efdda Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 01:03:37 -0800 Subject: [PATCH 13/42] suppress bogus static analysis warning --- stb_truetype.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stb_truetype.h b/stb_truetype.h index b57043e..0b1e3b5 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -43,6 +43,7 @@ // Giumo X. Clanjor // Higor Euripedes // Thomas Fields +// Derek Vinyard // // Misc other: // Ryan Gordon @@ -2714,6 +2715,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i unsigned char buffer[STBTT_MAX_OVERSAMPLE]; int safe_w = w - kernel_width; int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze for (j=0; j < h; ++j) { int i; unsigned int total; @@ -2775,6 +2777,7 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i unsigned char buffer[STBTT_MAX_OVERSAMPLE]; int safe_h = h - kernel_width; int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze for (j=0; j < w; ++j) { int i; unsigned int total; From 876aea3dbe0e56984f7336e55698c06c9346c8e8 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 01:22:30 -0800 Subject: [PATCH 14/42] refactor bmp header parser for sharing with stbi_info --- stb_image.h | 136 +++++++++++++++++++++++++++++++++-------------------- tests/image_test.c | 4 +- 2 files changed, 87 insertions(+), 53 deletions(-) diff --git a/stb_image.h b/stb_image.h index 354807b..df78c2f 100644 --- a/stb_image.h +++ b/stb_image.h @@ -4598,19 +4598,22 @@ static int stbi__shiftsigned(int v, int shift, int bits) return result; } -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +typedef struct { - stbi_uc *out; - unsigned int mr=0,mg=0,mb=0,ma=0, all_a=255; - stbi_uc pal[256][4]; - int psize=0,i,j,compress=0,width; - int bpp, flip_vertically, pad, target, offset, hsz; + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); stbi__get32le(s); // discard filesize stbi__get16le(s); // discard reserved stbi__get16le(s); // discard reserved - offset = stbi__get32le(s); - hsz = stbi__get32le(s); + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); if (hsz == 12) { s->img_x = stbi__get16le(s); @@ -4620,15 +4623,10 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int s->img_y = stbi__get32le(s); } if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); - bpp = stbi__get16le(s); - if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - if (hsz == 12) { - if (bpp < 24) - psize = (offset - 14 - 24) / 3; - } else { - compress = stbi__get32le(s); + info->bpp = stbi__get16le(s); + if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); + if (hsz != 12) { + int compress = stbi__get32le(s); if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); stbi__get32le(s); // discard sizeof stbi__get32le(s); // discard hres @@ -4642,26 +4640,26 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int stbi__get32le(s); stbi__get32le(s); } - if (bpp == 16 || bpp == 32) { - mr = mg = mb = 0; + if (info->bpp == 16 || info->bpp == 32) { + info->mr = info->mg = info->mb = 0; if (compress == 0) { - if (bpp == 32) { - mr = 0xffu << 16; - mg = 0xffu << 8; - mb = 0xffu << 0; - ma = 0xffu << 24; - all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 } else { - mr = 31u << 10; - mg = 31u << 5; - mb = 31u << 0; + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; } } else if (compress == 3) { - mr = stbi__get32le(s); - mg = stbi__get32le(s); - mb = stbi__get32le(s); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); // not documented, but generated by photoshop and handled by mspaint - if (mr == mg && mg == mb) { + if (info->mr == info->mg && info->mg == info->mb) { // ?!?!? return stbi__errpuc("bad BMP", "bad BMP"); } @@ -4669,11 +4667,13 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int return stbi__errpuc("bad BMP", "bad BMP"); } } else { - STBI_ASSERT(hsz == 108 || hsz == 124); - mr = stbi__get32le(s); - mg = stbi__get32le(s); - mb = stbi__get32le(s); - ma = stbi__get32le(s); + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); stbi__get32le(s); // discard color space for (i=0; i < 12; ++i) stbi__get32le(s); // discard color space parameters @@ -4684,35 +4684,68 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int stbi__get32le(s); // discard reserved } } - if (bpp < 16) - psize = (offset - 14 - hsz) >> 2; } + return (void *) 1; +} + + +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - 14 - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - 14 - info.hsz) >> 2; + } + s->img_n = ma ? 4 : 3; if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 target = req_comp; else target = s->img_n; // if they want monochrome, we'll post-convert + out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (bpp < 16) { + if (info.bpp < 16) { int z=0; if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } for (i=0; i < psize; ++i) { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); - if (hsz != 12) stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); pal[i][3] = 255; } - stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); - if (bpp == 4) width = (s->img_x + 1) >> 1; - else if (bpp == 8) width = s->img_x; + stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } pad = (-width)&3; for (j=0; j < (int) s->img_y; ++j) { for (i=0; i < (int) s->img_x; i += 2) { int v=stbi__get8(s),v2=0; - if (bpp == 4) { + if (info.bpp == 4) { v2 = v & 15; v >>= 4; } @@ -4721,7 +4754,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int out[z++] = pal[v][2]; if (target == 4) out[z++] = 255; if (i+1 == (int) s->img_x) break; - v = (bpp == 8) ? stbi__get8(s) : v2; + v = (info.bpp == 8) ? stbi__get8(s) : v2; out[z++] = pal[v][0]; out[z++] = pal[v][1]; out[z++] = pal[v][2]; @@ -4733,14 +4766,14 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; int z = 0; int easy=0; - stbi__skip(s, offset - 14 - hsz); - if (bpp == 24) width = 3 * s->img_x; - else if (bpp == 16) width = 2*s->img_x; + stbi__skip(s, info.offset - 14 - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; else /* bpp = 32 and pad = 0 */ width=0; pad = (-width) & 3; - if (bpp == 24) { + if (info.bpp == 24) { easy = 1; - } else if (bpp == 32) { + } else if (info.bpp == 32) { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) easy = 2; } @@ -4765,6 +4798,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int if (target == 4) out[z++] = a; } } else { + int bpp = info.bpp; for (i=0; i < (int) s->img_x; ++i) { stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); int a; diff --git a/tests/image_test.c b/tests/image_test.c index 9bb1832..86d3b46 100644 --- a/tests/image_test.c +++ b/tests/image_test.c @@ -7,7 +7,7 @@ #define STB_DEFINE #include "stb.h" -#define PNGSUITE_PRIMARY +//#define PNGSUITE_PRIMARY #if 0 void test_ycbcr(void) @@ -65,7 +65,7 @@ int main(int argc, char **argv) int w,h; //test_ycbcr(); - #if 1 + #if 0 // test hdr asserts for (h=0; h < 100; h += 2) for (w=0; w < 200; ++w) From 297ff6285909c510c27752785083d497ee1dbf7c Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 13:09:16 -0800 Subject: [PATCH 15/42] change bmp info to use common header parser --- stb_image.h | 34 +++++++++++----------------------- tests/image_test.c | 6 ++++-- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/stb_image.h b/stb_image.h index df78c2f..429f2ff 100644 --- a/stb_image.h +++ b/stb_image.h @@ -6088,29 +6088,17 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_BMP static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) { - int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') { - stbi__rewind( s ); - return 0; - } - stbi__skip(s,12); - hsz = stbi__get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) { - stbi__rewind( s ); - return 0; - } - if (hsz == 12) { - *x = stbi__get16le(s); - *y = stbi__get16le(s); - } else { - *x = stbi__get32le(s); - *y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) { - stbi__rewind( s ); - return 0; - } - *comp = stbi__get16le(s) / 8; + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = info.ma ? 4 : 3; return 1; } #endif diff --git a/tests/image_test.c b/tests/image_test.c index 86d3b46..b449744 100644 --- a/tests/image_test.c +++ b/tests/image_test.c @@ -81,15 +81,17 @@ int main(int argc, char **argv) for (i=1; i < argc; ++i) { int res; + int w2,h2,n2; unsigned char *data; printf("%s\n", argv[i]); - res = stbi_info(argv[1], &w, &h, &n); + res = stbi_info(argv[1], &w2, &h2, &n2); data = stbi_load(argv[i], &w, &h, &n, 4); if (data) free(data); else printf("Failed &n\n"); data = stbi_load(argv[i], &w, &h, 0, 1); if (data) free(data); else printf("Failed 1\n"); data = stbi_load(argv[i], &w, &h, 0, 2); if (data) free(data); else printf("Failed 2\n"); data = stbi_load(argv[i], &w, &h, 0, 3); if (data) free(data); else printf("Failed 3\n"); - data = stbi_load(argv[i], &w, &h, 0, 4); + data = stbi_load(argv[i], &w, &h, &n, 4); assert(data); + assert(w == w2 && h == h2 && n == n2); assert(res); if (data) { char fname[512]; From 2073403a5f54eda44090bc62d0907e07ba73bde5 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 13:09:30 -0800 Subject: [PATCH 16/42] fix two setup crashes found by fuzz testing --- stb_vorbis.c | 46 ++++++++++++++++++++++++++++------------------ tests/test_vorbis.c | 2 +- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 98e96fb..ac22315 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -556,9 +556,11 @@ enum STBVorbisError #if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)) #include #endif -#else +#else // STB_VORBIS_NO_CRT #define NULL 0 -#endif +#endif // STB_VORBIS_NO_CRT + +#include #if !defined(_MSC_VER) && !(defined(__MINGW32__) && defined(__forceinline)) #if __GNUC__ @@ -3645,14 +3647,15 @@ static int start_decoder(vorb *f) get32(f); // bitrate_nominal get32(f); // bitrate_minimum x = get8(f); - { int log0,log1; - log0 = x & 15; - log1 = x >> 4; - f->blocksize_0 = 1 << log0; - f->blocksize_1 = 1 << log1; - if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); - if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); - if (log0 > log1) return error(f, VORBIS_invalid_setup); + { + int log0,log1; + log0 = x & 15; + log1 = x >> 4; + f->blocksize_0 = 1 << log0; + f->blocksize_1 = 1 << log1; + if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); + if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); + if (log0 > log1) return error(f, VORBIS_invalid_setup); } // framing_flag @@ -3828,6 +3831,7 @@ static int start_decoder(vorb *f) } else { c->lookup_values = c->entries * c->dimensions; } + if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup); mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); if (mults == NULL) return error(f, VORBIS_outofmem); for (j=0; j < (int) c->lookup_values; ++j) { @@ -3848,21 +3852,27 @@ static int start_decoder(vorb *f) if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } len = sparse ? c->sorted_entries : c->entries; for (j=0; j < len; ++j) { - int z = sparse ? c->sorted_values[j] : j, div=1; + unsigned int z = sparse ? c->sorted_values[j] : j; + unsigned int div=1; for (k=0; k < c->dimensions; ++k) { int off = (z / div) % c->lookup_values; - c->multiplicands[j*c->dimensions + k] = - #ifndef STB_VORBIS_CODEBOOK_FLOATS - mults[off]; - #else - mults[off]*c->delta_value + c->minimum_value; + #ifndef STB_VORBIS_CODEBOOK_FLOATS + c->multiplicands[j*c->dimensions + k] = mults[off]; + #else + c->multiplicands[j*c->dimensions + k] = mults[off]*c->delta_value + c->minimum_value; // in this case (and this case only) we could pre-expand c->sequence_p, // and throw away the decode logic for it; have to ALSO do // it in the case below, but it can only be done if // STB_VORBIS_CODEBOOK_FLOATS // !STB_VORBIS_DIVIDES_IN_CODEBOOK - #endif - div *= c->lookup_values; + #endif + if (k+1 < c->dimensions) { + if (div > UINT_MAX / (unsigned int) c->lookup_values) { + setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); + return error(f, VORBIS_invalid_setup); + } + div *= c->lookup_values; + } } } setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index 5841381..f24376d 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -8,7 +8,7 @@ extern void stb_vorbis_dumpmem(void); int main(int argc, char **argv) { size_t memlen; - unsigned char *mem = stb_fileu("c:/x/theme_03.ogg", &memlen); + unsigned char *mem = stb_fileu("c:/x/vorbis/1.ogg", &memlen); int chan, samplerate; short *output; int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output); From 69a318bdb3bbaf7327a87bd18ec7d9b223091fe6 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 13:20:55 -0800 Subject: [PATCH 17/42] fix two invalid-file crashes found by fuzz testing --- stb_vorbis.c | 3 +++ tests/test_vorbis.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index ac22315..d902894 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -3715,6 +3715,8 @@ static int start_decoder(vorb *f) ordered = get_bits(f,1); c->sparse = ordered ? 0 : get_bits(f,1); + if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup); + if (c->sparse) lengths = (uint8 *) setup_temp_malloc(f, c->entries); else @@ -3998,6 +4000,7 @@ static int start_decoder(vorb *f) if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); r->begin = get_bits(f, 24); r->end = get_bits(f, 24); + if (r->end < r->begin) return error(f, VORBIS_invalid_setup); r->part_size = get_bits(f,24)+1; r->classifications = get_bits(f,6)+1; r->classbook = get_bits(f,8); diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index f24376d..0d0c0cf 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -8,7 +8,7 @@ extern void stb_vorbis_dumpmem(void); int main(int argc, char **argv) { size_t memlen; - unsigned char *mem = stb_fileu("c:/x/vorbis/1.ogg", &memlen); + unsigned char *mem = stb_fileu("c:/x/vorbis/4.ogg", &memlen); int chan, samplerate; short *output; int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output); From ea88e59b5dd48bc2179dd7db537923f9edbba707 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 13:45:33 -0800 Subject: [PATCH 18/42] fix invalid handling of truncated end-of-file indicator --- stb_vorbis.c | 7 +++++-- tests/test_vorbis.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index d902894..04f082e 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -906,7 +906,7 @@ static void *setup_malloc(vorb *f, int sz) static void setup_free(vorb *f, void *p) { - if (f->alloc.alloc_buffer) return; // do nothing; setup mem is not a stack + if (f->alloc.alloc_buffer) return; // do nothing; setup mem is a stack free(p); } @@ -3219,6 +3219,7 @@ static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, in *p_right_start = window_center; *p_right_end = n; } + return TRUE; } @@ -3457,7 +3458,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { uint32 current_end = f->known_loc_for_packet - (n-right_end); // then let's infer the size of the (probably) short final frame - if (current_end < f->current_loc + right_end) { + if (current_end < f->current_loc + (right_end-left_start)) { if (current_end < f->current_loc) { // negative truncation, that's impossible! *len = 0; @@ -3465,6 +3466,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, *len = current_end - f->current_loc; } *len += left_start; + if (*len > right_end) *len = right_end; // this should never happen f->current_loc += *len; return TRUE; } @@ -3482,6 +3484,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); *len = right_end; // ignore samples after the window goes to 0 + return TRUE; } diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index 0d0c0cf..74566da 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -8,7 +8,7 @@ extern void stb_vorbis_dumpmem(void); int main(int argc, char **argv) { size_t memlen; - unsigned char *mem = stb_fileu("c:/x/vorbis/4.ogg", &memlen); + unsigned char *mem = stb_fileu("c:/x/vorbis/5.ogg", &memlen); int chan, samplerate; short *output; int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output); From 70b33e99f0487d7d8665b483aff3cf2e70a4148f Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 14:04:56 -0800 Subject: [PATCH 19/42] fix crash from invalid file --- stb_vorbis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 04f082e..54481e7 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -1906,7 +1906,7 @@ static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **o } } else { i=0; - if (c_inter == 1) { + if (c_inter == 1 && i < effective) { float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; @@ -2176,7 +2176,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int goto done; #else // saves 1% - if (!codebook_decode_deinterleave_repeat_2(f, book, residue_buffers, &c_inter, &p_inter, n, r->part_size)) + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #endif stb_prof(7); From bdac1d2ab43823725fcd701e6310fbc0efd942de Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 16:01:40 -0800 Subject: [PATCH 20/42] fix two crashes in invalid files --- stb_vorbis.c | 83 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 54481e7..5bf8bae 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -579,6 +579,13 @@ enum STBVorbisError #endif +#if 0 +#include +#define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) +#else +#define CHECK(f) ((void) 0) +#endif + #define MAX_BLOCKSIZE_LOG 13 // from specification #define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) @@ -833,13 +840,6 @@ struct stb_vorbis int channel_buffer_end; }; -extern int my_prof(int slot); -//#define stb_prof my_prof - -#ifndef stb_prof -#define stb_prof(x) ((void) 0) -#endif - #if defined(STB_VORBIS_NO_PUSHDATA_API) #define IS_PUSH_MODE(f) FALSE #elif defined(STB_VORBIS_NO_PULLDATA_API) @@ -1894,7 +1894,6 @@ static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **o { z *= c->dimensions; - stb_prof(11); if (c->sequence_p) { // haven't optimized this case because I don't have any examples for (i=0; i < effective; ++i) { @@ -2078,15 +2077,17 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y #endif ady -= abs(base) * adx; if (x1 > n) x1 = n; - LINE_OP(output[x], inverse_db_table[y]); - for (++x; x < x1; ++x) { - err += ady; - if (err >= adx) { - err -= adx; - y += sy; - } else - y += base; + if (x < x1) { LINE_OP(output[x], inverse_db_table[y]); + for (++x; x < x1; ++x) { + err += ady; + if (err >= adx) { + err -= adx; + y += sy; + } else + y += base; + LINE_OP(output[x], inverse_db_table[y]); + } } } @@ -2125,7 +2126,8 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications)); #endif - stb_prof(2); + CHECK(f); + for (i=0; i < ch; ++i) if (!do_not_decode[i]) memset(residue_buffers[i], 0, sizeof(float) * n); @@ -2137,11 +2139,9 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int if (j == ch) goto done; - stb_prof(3); for (pass=0; pass < 8; ++pass) { int pcount = 0, class_set = 0; if (ch == 2) { - stb_prof(13); while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = (z & 1), p_inter = z>>1; @@ -2159,7 +2159,6 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int } #endif } - stb_prof(5); for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { int z = r->begin + pcount*r->part_size; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE @@ -2170,7 +2169,6 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; - stb_prof(20); // accounts for X time #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; @@ -2179,14 +2177,12 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #endif - stb_prof(7); } else { z += r->part_size; c_inter = z & 1; p_inter = z >> 1; } } - stb_prof(8); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE ++class_set; #endif @@ -2219,10 +2215,8 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; - stb_prof(22); if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; - stb_prof(3); } else { z += r->part_size; c_inter = 0; @@ -2261,10 +2255,8 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; - stb_prof(22); if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; - stb_prof(3); } else { z += r->part_size; c_inter = z % ch; @@ -2279,7 +2271,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int } goto done; } - stb_prof(9); + CHECK(f); for (pass=0; pass < 8; ++pass) { int pcount = 0, class_set=0; @@ -2328,7 +2320,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int } } done: - stb_prof(0); + CHECK(f); temp_alloc_restore(f,temp_alloc_point); } @@ -3142,13 +3134,16 @@ static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *f int hx = g->Xlist[j]; if (lx != hx) draw_line(target, lx,ly, hx,hy, n2); + CHECK(f); lx = hx, ly = hy; } } - if (lx < n2) + if (lx < n2) { // optimization of: draw_line(target, lx,ly, n,ly, n2); for (j=lx; j < n2; ++j) LINE_OP(target[j], inverse_db_table[ly]); + CHECK(f); + } } return TRUE; } @@ -3238,7 +3233,8 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, // FLOORS n2 = n >> 1; - stb_prof(1); + CHECK(f); + for (i=0; i < f->channels; ++i) { int s = map->chan[i].mux, floor; zero_channel[i] = FALSE; @@ -3330,7 +3326,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, // at this point we've decoded the floor into buffer } } - stb_prof(0); + CHECK(f); // at this point we've decoded all floors if (f->alloc.alloc_buffer) @@ -3343,6 +3339,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE; } + CHECK(f); // RESIDUE DECODE for (i=0; i < map->submaps; ++i) { float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; @@ -3367,9 +3364,9 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + CHECK(f); // INVERSE COUPLING - stb_prof(14); for (i = map->coupling_steps-1; i >= 0; --i) { int n2 = n >> 1; float *m = f->channel_buffers[map->chan[i].magnitude]; @@ -3390,10 +3387,10 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, a[j] = a2; } } + CHECK(f); // finish decoding the floors #ifndef STB_VORBIS_NO_DEFER_FLOOR - stb_prof(15); for (i=0; i < f->channels; ++i) { if (really_zero_channel[i]) { memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); @@ -3413,10 +3410,10 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, #endif // INVERSE MDCT - stb_prof(16); + CHECK(f); for (i=0; i < f->channels; ++i) inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); - stb_prof(0); + CHECK(f); // this shouldn't be necessary, unless we exited on an error // and want to flush to get to the next packet @@ -3484,6 +3481,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); *len = right_end; // ignore samples after the window goes to 0 + CHECK(f); return TRUE; } @@ -3707,6 +3705,7 @@ static int start_decoder(vorb *f) int total=0; uint8 *lengths; Codebook *c = f->codebooks+i; + CHECK(f); x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup); x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup); x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup); @@ -3778,6 +3777,7 @@ static int start_decoder(vorb *f) c->sorted_entries = sorted_count; values = NULL; + CHECK(f); if (!c->sparse) { c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries); if (!c->codewords) return error(f, VORBIS_outofmem); @@ -3823,6 +3823,7 @@ static int start_decoder(vorb *f) compute_accelerated_huffman(c); + CHECK(f); c->lookup_type = get_bits(f, 4); if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); if (c->lookup_type > 0) { @@ -3886,6 +3887,7 @@ static int start_decoder(vorb *f) else #endif { + CHECK(f); c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } #ifndef STB_VORBIS_CODEBOOK_FLOATS @@ -3900,14 +3902,17 @@ static int start_decoder(vorb *f) skip:; #endif + CHECK(f); #ifdef STB_VORBIS_CODEBOOK_FLOATS if (c->lookup_type == 2 && c->sequence_p) { - for (j=1; j < (int) c->lookup_values; ++j) - c->multiplicands[j] = c->multiplicands[j-1]; + for (j=1; j < (int) (c->sparse ? c->sorted_entries : c->lookup_values); ++j) + c->multiplicands[j] += c->multiplicands[j-1]; + CHECK(f); c->sequence_p = 0; } #endif } + CHECK(f); } // time domain transfers (notused) @@ -4187,6 +4192,7 @@ static void vorbis_deinit(stb_vorbis *p) } if (p->codebooks) { + CHECK(p); for (i=0; i < p->codebook_count; ++i) { Codebook *c = p->codebooks + i; setup_free(p, c->codeword_lengths); @@ -4205,6 +4211,7 @@ static void vorbis_deinit(stb_vorbis *p) setup_free(p, p->mapping[i].chan); setup_free(p, p->mapping); } + CHECK(p); for (i=0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) { setup_free(p, p->channel_buffers[i]); setup_free(p, p->previous_window[i]); From bc2219e1b3cfcaf511242f009186d13f78c8885d Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 16:22:07 -0800 Subject: [PATCH 21/42] fix multiple crashes on invalid files --- stb_vorbis.c | 20 ++++++++++++++++---- tests/test_vorbis.c | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 5bf8bae..731b6bd 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -1,8 +1,11 @@ -// Ogg Vorbis audio decoder - v1.06 - public domain +// Ogg Vorbis audio decoder - v1.07 - public domain // http://nothings.org/stb_vorbis/ // -// Written by Sean Barrett in 2007, last updated in 2014 -// Sponsored by RAD Game Tools. +// Original version written by Sean Barrett in 2007. +// +// Originally sponsored by RAD Game Tools. Seeking sponsored +// by Phillip Bennefall, Marc Andersen, Elias Software, vgstorm.com, +// Aras Pranckevicius, and Sean Barrett. // // LICENSE // @@ -30,11 +33,13 @@ // Laurent Gomila Marc LeBlanc Ronny Chevalier // Bernhard Wodo Evan Balster "alxprd"@github // Tom Beaumont Ingo Leitgeb Nicolas Guillemot +// Phillip Bennefall // (If you reported a bug but do not appear in this list, it is because // someone else reported the bug before you. There were too many of you to // list them all because I was lax about updating for a long time, sorry.) // // Partial history: +// 1.07 - 2015/11/08 - fixes for crashes on invalid files // 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) // some crash fixes when out of memory or with corrupt files // fix some inappropriately signed shifts @@ -1057,10 +1062,12 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) while (z > 0 && !available[z]) --z; if (z == 0) { return FALSE; } res = available[z]; + assert(z >= 0 && z < 32); available[z] = 0; add_entry(c, bit_reverse(res), i, m++, len[i], values); // propogate availability up the tree if (z != len[i]) { + assert(len[i] >= 0 && len[i] < 32); for (y=len[i]; y > z; --y) { assert(available[y] == 0); available[y] = res + (1 << (32-y)); @@ -1586,7 +1593,9 @@ static int codebook_decode_scalar_raw(vorb *f, Codebook *c) int i; prep_huffman(f); - assert(c->sorted_codewords || c->codewords); + if (c->codewords == NULL && c->sorted_codewords == NULL) + return -1; + // cases to use binary search: sorted_codewords && !c->codewords // sorted_codewords && c->entries > 8 if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) { @@ -3743,6 +3752,8 @@ static int start_decoder(vorb *f) if (present) { lengths[j] = get_bits(f, 5) + 1; ++total; + if (lengths[j] == 32) + return error(f, VORBIS_invalid_setup); } else { lengths[j] = NO_CODE; } @@ -4012,6 +4023,7 @@ static int start_decoder(vorb *f) r->part_size = get_bits(f,24)+1; r->classifications = get_bits(f,6)+1; r->classbook = get_bits(f,8); + if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup); for (j=0; j < r->classifications; ++j) { uint8 high_bits=0; uint8 low_bits=get_bits(f,3); diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index 74566da..a41c02c 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -8,7 +8,7 @@ extern void stb_vorbis_dumpmem(void); int main(int argc, char **argv) { size_t memlen; - unsigned char *mem = stb_fileu("c:/x/vorbis/5.ogg", &memlen); + unsigned char *mem = stb_fileu("c:/x/vorbis/stb_vorbis_crash.ogg", &memlen); int chan, samplerate; short *output; int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output); From fe74a8c2232c76ee4e34328ea585846460218483 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 19:13:32 -0800 Subject: [PATCH 22/42] broken attempt at removign STB_VORBIS_CODEBOOK_FLOAT option --- stb_vorbis.c | 63 +++++++++++++++++------------------------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 731b6bd..9030c31 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -493,14 +493,8 @@ enum STBVorbisError // trade off storage for speed. //#define STB_VORBIS_DIVIDES_IN_CODEBOOK -// STB_VORBIS_CODEBOOK_SHORTS -// The vorbis file format encodes VQ codebook floats as ax+b where a and -// b are floating point per-codebook constants, and x is a 16-bit int. -// Normally, stb_vorbis decodes them to floats rather than leaving them -// as 16-bit ints and computing ax+b while decoding. This is a speed/space -// tradeoff; you can save space by defining this flag. -#ifndef STB_VORBIS_CODEBOOK_SHORTS -#define STB_VORBIS_CODEBOOK_FLOATS +#ifdef STB_VORBIS_CODEBOOK_SHORTS +#error "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats" #endif // STB_VORBIS_DIVIDE_TABLE @@ -607,11 +601,7 @@ typedef signed int int32; #define FALSE 0 #endif -#ifdef STB_VORBIS_CODEBOOK_FLOATS typedef float codetype; -#else -typedef uint16 codetype; -#endif // @NOTE // @@ -1703,15 +1693,9 @@ static int codebook_decode_scalar(vorb *f, Codebook *c) // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case // where we avoid one addition -#ifndef STB_VORBIS_CODEBOOK_FLOATS - #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off] * c->delta_value + c->minimum_value) - #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off] * c->delta_value) - #define CODEBOOK_ELEMENT_BASE(c) (c->minimum_value) -#else - #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) - #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) - #define CODEBOOK_ELEMENT_BASE(c) (0) -#endif +#define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off] * c->delta_value + c->minimum_value) +#define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off] * c->delta_value) +#define CODEBOOK_ELEMENT_BASE(c) (c->minimum_value) static int codebook_decode_start(vorb *f, Codebook *c) { @@ -3860,6 +3844,7 @@ static int start_decoder(vorb *f) #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { int len, sparse = c->sparse; + float last=0; // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop if (sparse) { if (c->sorted_entries == 0) goto skip; @@ -3873,16 +3858,11 @@ static int start_decoder(vorb *f) unsigned int div=1; for (k=0; k < c->dimensions; ++k) { int off = (z / div) % c->lookup_values; - #ifndef STB_VORBIS_CODEBOOK_FLOATS - c->multiplicands[j*c->dimensions + k] = mults[off]; - #else - c->multiplicands[j*c->dimensions + k] = mults[off]*c->delta_value + c->minimum_value; - // in this case (and this case only) we could pre-expand c->sequence_p, - // and throw away the decode logic for it; have to ALSO do - // it in the case below, but it can only be done if - // STB_VORBIS_CODEBOOK_FLOATS - // !STB_VORBIS_DIVIDES_IN_CODEBOOK - #endif + float val = mults[off]; + val = mults[off]*c->delta_value + c->minimum_value + last; + c->multiplicands[j*c->dimensions + k] = val; + if (c->sequence_p) + last = val; if (k+1 < c->dimensions) { if (div > UINT_MAX / (unsigned int) c->lookup_values) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); @@ -3898,15 +3878,16 @@ static int start_decoder(vorb *f) else #endif { + float last=0; CHECK(f); c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } - #ifndef STB_VORBIS_CODEBOOK_FLOATS - memcpy(c->multiplicands, mults, sizeof(c->multiplicands[0]) * c->lookup_values); - #else - for (j=0; j < (int) c->lookup_values; ++j) - c->multiplicands[j] = mults[j] * c->delta_value + c->minimum_value; - #endif + for (j=0; j < (int) c->lookup_values; ++j) { + float val = mults[j] * c->delta_value + c->minimum_value + last; + c->multiplicands[j] = val; + if (c->sequence_p) + last = val; + } setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK @@ -3914,14 +3895,6 @@ static int start_decoder(vorb *f) #endif CHECK(f); - #ifdef STB_VORBIS_CODEBOOK_FLOATS - if (c->lookup_type == 2 && c->sequence_p) { - for (j=1; j < (int) (c->sparse ? c->sorted_entries : c->lookup_values); ++j) - c->multiplicands[j] += c->multiplicands[j-1]; - CHECK(f); - c->sequence_p = 0; - } - #endif } CHECK(f); } From 2b57ea95da349555469e5fd75c5c35e49d6060db Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 8 Nov 2015 19:16:25 -0800 Subject: [PATCH 23/42] fixed version of removed support for CODEBOOK_SHORTS --- stb_vorbis.c | 6 +++--- tests/test_vorbis.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 9030c31..ea753df 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -1693,9 +1693,9 @@ static int codebook_decode_scalar(vorb *f, Codebook *c) // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case // where we avoid one addition -#define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off] * c->delta_value + c->minimum_value) -#define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off] * c->delta_value) -#define CODEBOOK_ELEMENT_BASE(c) (c->minimum_value) +#define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_BASE(c) (0) static int codebook_decode_start(vorb *f, Codebook *c) { diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index a41c02c..d54ed23 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -8,10 +8,11 @@ extern void stb_vorbis_dumpmem(void); int main(int argc, char **argv) { size_t memlen; - unsigned char *mem = stb_fileu("c:/x/vorbis/stb_vorbis_crash.ogg", &memlen); + unsigned char *mem = stb_fileu("c:/x/sketch008.ogg", &memlen); int chan, samplerate; short *output; int samples = stb_vorbis_decode_memory(mem, memlen, &chan, &samplerate, &output); + stb_filewrite("c:/x/sketch008.raw", output, samples*4); return 0; } #endif From 4337345c5ddd636bcdee65439e5a9f4451114e88 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 14 Nov 2015 13:14:26 +0100 Subject: [PATCH 24/42] Prevent HDR info function from trashing stbi context by over-reading --- stb_image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_image.h b/stb_image.h index 0a9de39..a91952b 100644 --- a/stb_image.h +++ b/stb_image.h @@ -6017,7 +6017,7 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) char *token; int valid = 0; - if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { + if (stbi__hdr_test(s) == 0) { stbi__rewind( s ); return 0; } From 7453e1bfa417453db9b57091b71ad428ba0a6462 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sat, 5 Dec 2015 23:23:12 +0100 Subject: [PATCH 25/42] stb_image.h: Support 15/16bit per pixel RGB(A) TGAs stbi__tga_* assumed that 16bit TGAs were Grayscale + Alpha. However, if the TGA imagetype is not one of the gray ones, it's 16Bit RGB data, with 5 Bits per channel. If the TGA image descriptor field has alpha bits (the 3 least significant ones) set, the pixel's most significant bit is for alpha: 1 for opaque and 0 for translucent. Furthermore people claim that TGAs can also pretend to have 15bpp, which is the same as 16bpp but definitely without alpha. So 15/16bpp TGAs are now decoded to STBI_rgb(_alpha). --- stb_image.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/stb_image.h b/stb_image.h index 0a9de39..82a0ad8 100644 --- a/stb_image.h +++ b/stb_image.h @@ -4813,7 +4813,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int #ifndef STBI_NO_TGA static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) { - int tga_w, tga_h, tga_comp; + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel; int sz; stbi__get8(s); // discard Offset sz = stbi__get8(s); // color type @@ -4824,6 +4824,7 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) sz = stbi__get8(s); // image type // only RGB or grey allowed, +/- RLE if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + tga_image_type = sz; stbi__skip(s,9); tga_w = stbi__get16le(s); if( tga_w < 1 ) { @@ -4835,16 +4836,24 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) stbi__rewind(s); return 0; // test height } - sz = stbi__get8(s); // bits per pixel - // only RGB or RGBA or grey allowed - if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { - stbi__rewind(s); - return 0; + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + sz = stbi__get8(s) & 15; // alpha bits + // only RGB or RGBA (incl. 16bit) or grey allowed + // FIXME: don't we have to use the colormap's bpp if indexed? + switch(tga_bits_per_pixel) { + case 8: tga_comp = STBI_grey; break; + case 15: tga_comp = STBI_rgb; break; + case 16: + if((tga_image_type == 3) || (tga_image_type == 11)) tga_comp = STBI_grey_alpha; + else tga_comp = sz ? STBI_rgb_alpha : STBI_rgb; // most signif. bit might be for alpha + break; + case 24: // fall-through + case 32: tga_comp = tga_bits_per_pixel/8; break; + default: stbi__rewind(s); return 0; } - tga_comp = sz; if (x) *x = tga_w; if (y) *y = tga_h; - if (comp) *comp = tga_comp / 8; + if (comp) *comp = tga_comp; return 1; // seems to have passed everything } @@ -4865,7 +4874,7 @@ static int stbi__tga_test(stbi__context *s) if ( stbi__get16be(s) < 1 ) return 0; // test width if ( stbi__get16be(s) < 1 ) return 0; // test height sz = stbi__get8(s); // bits per pixel - if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) res = 0; else res = 1; @@ -4888,8 +4897,9 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int int tga_width = stbi__get16le(s); int tga_height = stbi__get16le(s); int tga_bits_per_pixel = stbi__get8(s); - int tga_comp = tga_bits_per_pixel / 8; + int tga_comp, tga_rgb16=0; int tga_inverted = stbi__get8(s); + int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits // image data unsigned char *tga_data; unsigned char *tga_palette = NULL; @@ -4905,14 +4915,13 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int tga_image_type -= 8; tga_is_RLE = 1; } - /* int tga_alpha_bits = tga_inverted & 15; */ tga_inverted = 1 - ((tga_inverted >> 5) & 1); // error check if ( //(tga_indexed) || (tga_width < 1) || (tga_height < 1) || (tga_image_type < 1) || (tga_image_type > 3) || - ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 15) && (tga_bits_per_pixel != 16) && (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) ) { @@ -4924,6 +4933,17 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int { tga_comp = tga_palette_bits / 8; } + else { + switch(tga_bits_per_pixel) { + case 8: tga_comp = STBI_grey; break; + case 15: tga_comp = STBI_rgb; tga_rgb16=1; break; + case 16: + if (tga_image_type == 3) tga_comp = STBI_grey_alpha; + else { tga_comp = tga_alpha_bits ? STBI_rgb_alpha : STBI_rgb; tga_rgb16=1; } + break; + default: tga_comp = tga_bits_per_pixel / 8; // incl. 24 and 32 + } + } // tga info *x = tga_width; @@ -4936,7 +4956,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int // skip to the data's starting position (offset usually = 0) stbi__skip(s, tga_offset ); - if ( !tga_indexed && !tga_is_RLE) { + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { for (i=0; i < tga_height; ++i) { int row = tga_inverted ? tga_height -i - 1 : i; stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; @@ -4999,8 +5019,24 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int { raw_data[j] = tga_palette[pal_idx+j]; } - } else - { + } else if(tga_rgb16) { + // convert from 16bit RGB(A) to 24/32bit RGB(A) + stbi__uint16 px = stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + raw_data[0] = (r * 255)/31; + raw_data[1] = (g * 255)/31; + raw_data[2] = (b * 255)/31; + + if(tga_comp == STBI_rgb_alpha) { + // most significant bit set to 1 for opaque, 0 for trans., according to + // http://www.imagemagick.org/discourse-server/viewtopic.php?t=27469 + raw_data[3] = !(px & 0x8000) * 255; + } + } else { // read in the data raw for (j = 0; j*8 < tga_bits_per_pixel; ++j) { @@ -5043,7 +5079,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int } // swap RGB - if (tga_comp >= 3) + if (tga_comp >= 3 && !tga_rgb16) { unsigned char* tga_pixel = tga_data; for (i=0; i < tga_width * tga_height; ++i) From 57409c3d159af0bb72dac2411fa3183d39202674 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 6 Dec 2015 00:30:16 +0100 Subject: [PATCH 26/42] stb_image.h: Improve stbi__tga_info() and stbi__tga_test() * for paletted images, .._info()'s comp should be based on the palette's bits per pixel, not the images bits per pixel (which describes the size of an index into the palette and is also checked now) * make sure the color (map) type and the image type fields of the header are consistent (=> if TGA color type is 1 for paletted, the TGA image type must be 1 or 9) * .._test() does some more checks and uses stbi__get16le() instead of stbi__get16be() - TGA is little endian. * .._test() now always rewinds (sometimes it used to do only return 0; without rewinding) * remove "error check" at the beginning of stbi__tga_load(), because all that is already tested in stbi__tga_test() --- stb_image.h | 94 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/stb_image.h b/stb_image.h index 82a0ad8..f627fc0 100644 --- a/stb_image.h +++ b/stb_image.h @@ -4813,19 +4813,36 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int #ifndef STBI_NO_TGA static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) { - int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel; - int sz; + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; stbi__get8(s); // discard Offset - sz = stbi__get8(s); // color type - if( sz > 1 ) { + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { stbi__rewind(s); return 0; // only RGB or indexed allowed } - sz = stbi__get8(s); // image type - // only RGB or grey allowed, +/- RLE - if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; - tga_image_type = sz; - stbi__skip(s,9); + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } tga_w = stbi__get16le(s); if( tga_w < 1 ) { stbi__rewind(s); @@ -4837,9 +4854,17 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) return 0; // test height } tga_bits_per_pixel = stbi__get8(s); // bits per pixel + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_bits_per_pixel = tga_colormap_bpp; // make sure colormap's bpp are tested for tga_comp + } sz = stbi__get8(s) & 15; // alpha bits // only RGB or RGBA (incl. 16bit) or grey allowed - // FIXME: don't we have to use the colormap's bpp if indexed? switch(tga_bits_per_pixel) { case 8: tga_comp = STBI_grey; break; case 15: tga_comp = STBI_rgb; break; @@ -4859,25 +4884,31 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__tga_test(stbi__context *s) { - int res; - int sz; + int res = 0; + int sz, tga_color_type; stbi__get8(s); // discard Offset - sz = stbi__get8(s); // color type - if ( sz > 1 ) return 0; // only RGB or indexed allowed + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed sz = stbi__get8(s); // image type - if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE - stbi__get16be(s); // discard palette start - stbi__get16be(s); // discard palette length - stbi__get8(s); // discard bits per palette color entry - stbi__get16be(s); // discard x origin - stbi__get16be(s); // discard y origin - if ( stbi__get16be(s) < 1 ) return 0; // test width - if ( stbi__get16be(s) < 1 ) return 0; // test height + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height sz = stbi__get8(s); // bits per pixel - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) - res = 0; - else - res = 1; + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: stbi__rewind(s); return res; } @@ -4917,17 +4948,6 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int } tga_inverted = 1 - ((tga_inverted >> 5) & 1); - // error check - if ( //(tga_indexed) || - (tga_width < 1) || (tga_height < 1) || - (tga_image_type < 1) || (tga_image_type > 3) || - ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 15) && (tga_bits_per_pixel != 16) && - (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) - ) - { - return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA - } - // If I'm paletted, then I'll use the number of bits from the palette if ( tga_indexed ) { From d23504932293f7a7b8bb13eae033eff5a03a68df Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 6 Dec 2015 04:33:37 +0100 Subject: [PATCH 27/42] stb_image.h: Fix TGA colormap support * Calculate correct stb format (incl. proper 16bit support) also when using a colormap (palette) * Create colormap with tga_comp, to correctly support 16bit RGB (instead of using tga_palette_bits/8 and just copying the data) * For TGAs with colormap, the TGA bits per pixel field specifies the size of an index to the colormap - the "real" color depth of the image is saved in the color map specification's bits per pixel field. I think only 8 and 16bit indices make sense (16 should be supported, otherwise the colormap length could be u8 instead of u16), so I added support for both. * Helper functions stbi__tga_get_comp() to calculate stb pixelformat and stbi__tga_read_rgb16() to read one 16bit pixel and convert it to 24/32bit RGB(A) - for less duplicate code --- stb_image.h | 134 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/stb_image.h b/stb_image.h index f627fc0..b0aca9d 100644 --- a/stb_image.h +++ b/stb_image.h @@ -4811,6 +4811,26 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int // Targa Truevision - TGA // by Jonathan Dummer #ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int alpha_bits, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if(is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 15: if(is_rgb16) *is_rgb16 = 1; return STBI_rgb; + case 16: + if(is_grey) return STBI_grey_alpha; + else { + if(is_rgb16) *is_rgb16 = 1; + return alpha_bits ? STBI_rgb_alpha : STBI_rgb; // most signif. bit might be for alpha + } + case 24: // fall-through + case 32: return bits_per_pixel/8; + default: return 0; + } +} + static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) { int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; @@ -4854,6 +4874,7 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) return 0; // test height } tga_bits_per_pixel = stbi__get8(s); // bits per pixel + sz = stbi__get8(s) & 15; // alpha bits if (tga_colormap_bpp != 0) { if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { // when using a colormap, tga_bits_per_pixel is the size of the indexes @@ -4861,20 +4882,13 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) stbi__rewind(s); return 0; } - tga_bits_per_pixel = tga_colormap_bpp; // make sure colormap's bpp are tested for tga_comp + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, sz, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, sz, (tga_image_type == 3) || (tga_image_type == 11), NULL); } - sz = stbi__get8(s) & 15; // alpha bits - // only RGB or RGBA (incl. 16bit) or grey allowed - switch(tga_bits_per_pixel) { - case 8: tga_comp = STBI_grey; break; - case 15: tga_comp = STBI_rgb; break; - case 16: - if((tga_image_type == 3) || (tga_image_type == 11)) tga_comp = STBI_grey_alpha; - else tga_comp = sz ? STBI_rgb_alpha : STBI_rgb; // most signif. bit might be for alpha - break; - case 24: // fall-through - case 32: tga_comp = tga_bits_per_pixel/8; break; - default: stbi__rewind(s); return 0; + if(!tga_comp) { + stbi__rewind(s); + return 0; } if (x) *x = tga_w; if (y) *y = tga_h; @@ -4913,6 +4927,27 @@ errorEnd: return res; } +// read 16bit value and convert to 24/32bit RGB(A) +void stbi__tga_read_rgb16(stbi__context *s, int has_alpha, stbi_uc* out) +{ + stbi__uint16 px = stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (r * 255)/31; + out[1] = (g * 255)/31; + out[2] = (b * 255)/31; + + if(has_alpha) { + // most significant bit set to 1 for opaque, 0 for trans., according to + // http://www.imagemagick.org/discourse-server/viewtopic.php?t=27469 + out[3] = !(px & 0x8000) * 255; + } +} + static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) { // read in the TGA header stuff @@ -4949,21 +4984,11 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int tga_inverted = 1 - ((tga_inverted >> 5) & 1); // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) - { - tga_comp = tga_palette_bits / 8; - } - else { - switch(tga_bits_per_pixel) { - case 8: tga_comp = STBI_grey; break; - case 15: tga_comp = STBI_rgb; tga_rgb16=1; break; - case 16: - if (tga_image_type == 3) tga_comp = STBI_grey_alpha; - else { tga_comp = tga_alpha_bits ? STBI_rgb_alpha : STBI_rgb; tga_rgb16=1; } - break; - default: tga_comp = tga_bits_per_pixel / 8; // incl. 24 and 32 - } - } + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, tga_alpha_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_alpha_bits, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); // tga info *x = tga_width; @@ -4989,15 +5014,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int // any data to skip? (offset usually = 0) stbi__skip(s, tga_palette_start ); // load the palette - tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 ); + tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); if (!tga_palette) { STBI_FREE(tga_data); return stbi__errpuc("outofmem", "Out of memory"); } - if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb || tga_comp == STBI_rgb_alpha); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, tga_comp == STBI_rgb_alpha, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); } } // load the data @@ -5027,39 +5059,21 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int // load however much data we did have if ( tga_indexed ) { - // read in 1 byte, then perform the lookup - int pal_idx = stbi__get8(s); - if ( pal_idx >= tga_palette_len ) - { - // invalid index + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index pal_idx = 0; } - pal_idx *= tga_bits_per_pixel / 8; - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { raw_data[j] = tga_palette[pal_idx+j]; } } else if(tga_rgb16) { - // convert from 16bit RGB(A) to 24/32bit RGB(A) - stbi__uint16 px = stbi__get16le(s); - stbi__uint16 fiveBitMask = 31; - // we have 3 channels with 5bits each - int r = (px >> 10) & fiveBitMask; - int g = (px >> 5) & fiveBitMask; - int b = px & fiveBitMask; - raw_data[0] = (r * 255)/31; - raw_data[1] = (g * 255)/31; - raw_data[2] = (b * 255)/31; - - if(tga_comp == STBI_rgb_alpha) { - // most significant bit set to 1 for opaque, 0 for trans., according to - // http://www.imagemagick.org/discourse-server/viewtopic.php?t=27469 - raw_data[3] = !(px & 0x8000) * 255; - } + stbi__tga_read_rgb16(s, tga_comp == STBI_rgb_alpha, raw_data); } else { // read in the data raw - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { + for (j = 0; j < tga_comp; ++j) { raw_data[j] = stbi__get8(s); } } @@ -5098,7 +5112,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int } } - // swap RGB + // swap RGB - if the source data was RGB16, it already is in the right order if (tga_comp >= 3 && !tga_rgb16) { unsigned char* tga_pixel = tga_data; From 87a0396922d2b49ea46d519bd69378761cf9d941 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 6 Dec 2015 05:47:47 +0100 Subject: [PATCH 28/42] stb_image.h: 16 bit TGAs don't really have an alpha channel I claimed that if the most significant bit of a 16bit pixel is set, it should be opaque (as is suggested by some sources on the internet), but implemented the opposite. If implemented "correctly", lots of 16bit TGAs become invisible.. so I guess 16bit TGAs aren't really supposed to have an alpha-channel, or at least most 16bit TGAs (despite having set an "alpha-bit" in the "image descriptor byte") in the wild don't seem to work like that. So just assume 16bit non-greyscale TGAs are always STBI_rgb without an alpha channel. --- stb_image.h | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/stb_image.h b/stb_image.h index b0aca9d..8af5565 100644 --- a/stb_image.h +++ b/stb_image.h @@ -4812,19 +4812,16 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int // by Jonathan Dummer #ifndef STBI_NO_TGA // returns STBI_rgb or whatever, 0 on error -static int stbi__tga_get_comp(int bits_per_pixel, int alpha_bits, int is_grey, int* is_rgb16) +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) { // only RGB or RGBA (incl. 16bit) or grey allowed if(is_rgb16) *is_rgb16 = 0; switch(bits_per_pixel) { case 8: return STBI_grey; - case 15: if(is_rgb16) *is_rgb16 = 1; return STBI_rgb; - case 16: - if(is_grey) return STBI_grey_alpha; - else { - if(is_rgb16) *is_rgb16 = 1; - return alpha_bits ? STBI_rgb_alpha : STBI_rgb; // most signif. bit might be for alpha - } + case 16: if(is_grey) return STBI_grey_alpha; + // else: fall-through + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; case 24: // fall-through case 32: return bits_per_pixel/8; default: return 0; @@ -4874,7 +4871,7 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) return 0; // test height } tga_bits_per_pixel = stbi__get8(s); // bits per pixel - sz = stbi__get8(s) & 15; // alpha bits + stbi__get8(s); // ignore alpha bits if (tga_colormap_bpp != 0) { if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { // when using a colormap, tga_bits_per_pixel is the size of the indexes @@ -4882,9 +4879,9 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) stbi__rewind(s); return 0; } - tga_comp = stbi__tga_get_comp(tga_colormap_bpp, sz, 0, NULL); + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); } else { - tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, sz, (tga_image_type == 3) || (tga_image_type == 11), NULL); + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); } if(!tga_comp) { stbi__rewind(s); @@ -4927,8 +4924,8 @@ errorEnd: return res; } -// read 16bit value and convert to 24/32bit RGB(A) -void stbi__tga_read_rgb16(stbi__context *s, int has_alpha, stbi_uc* out) +// read 16bit value and convert to 24bit RGB +void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) { stbi__uint16 px = stbi__get16le(s); stbi__uint16 fiveBitMask = 31; @@ -4941,11 +4938,10 @@ void stbi__tga_read_rgb16(stbi__context *s, int has_alpha, stbi_uc* out) out[1] = (g * 255)/31; out[2] = (b * 255)/31; - if(has_alpha) { - // most significant bit set to 1 for opaque, 0 for trans., according to - // http://www.imagemagick.org/discourse-server/viewtopic.php?t=27469 - out[3] = !(px & 0x8000) * 255; - } + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. } static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) @@ -4965,7 +4961,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int int tga_bits_per_pixel = stbi__get8(s); int tga_comp, tga_rgb16=0; int tga_inverted = stbi__get8(s); - int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) // image data unsigned char *tga_data; unsigned char *tga_palette = NULL; @@ -4984,8 +4980,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int tga_inverted = 1 - ((tga_inverted >> 5) & 1); // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, tga_alpha_bits, 0, &tga_rgb16); - else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_alpha_bits, (tga_image_type == 3), &tga_rgb16); + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); @@ -5021,9 +5017,9 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int } if (tga_rgb16) { stbi_uc *pal_entry = tga_palette; - STBI_ASSERT(tga_comp == STBI_rgb || tga_comp == STBI_rgb_alpha); + STBI_ASSERT(tga_comp == STBI_rgb); for (i=0; i < tga_palette_len; ++i) { - stbi__tga_read_rgb16(s, tga_comp == STBI_rgb_alpha, pal_entry); + stbi__tga_read_rgb16(s, pal_entry); pal_entry += tga_comp; } } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { @@ -5070,7 +5066,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int raw_data[j] = tga_palette[pal_idx+j]; } } else if(tga_rgb16) { - stbi__tga_read_rgb16(s, tga_comp == STBI_rgb_alpha, raw_data); + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); } else { // read in the data raw for (j = 0; j < tga_comp; ++j) { From 7e741ffc1e78c2ec9dfe8725f8fa52ca8bc393cc Mon Sep 17 00:00:00 2001 From: Romain Bailly Date: Thu, 14 Jan 2016 10:34:30 +0100 Subject: [PATCH 29/42] Added the old size as argument to the STBI_REALLOC() and STBIW_REALLOC() macros --- stb_image.h | 15 ++++++++------- stb_image_write.h | 8 ++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/stb_image.h b/stb_image.h index 0a9de39..fcb574f 100644 --- a/stb_image.h +++ b/stb_image.h @@ -639,9 +639,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #endif #ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,sz) realloc(p,sz) -#define STBI_FREE(p) free(p) +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,oldsz,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) #endif // x86/x64 detection @@ -3616,14 +3616,14 @@ 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 { char *q; - int cur, limit; + int cur, limit, old_limit; z->zout = zout; if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); cur = (int) (z->zout - z->zout_start); - limit = (int) (z->zout_end - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); while (cur + n > limit) limit *= 2; - q = (char *) STBI_REALLOC(z->zout_start, limit); + q = (char *) STBI_REALLOC(z->zout_start, old_limit, limit); if (q == NULL) return stbi__err("outofmem", "Out of memory"); z->zout_start = q; z->zout = q + cur; @@ -4408,11 +4408,12 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } if ((int)(ioff + c.length) < (int)ioff) return 0; if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; stbi_uc *p; if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; while (ioff + c.length > idata_limit) idata_limit *= 2; - p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); z->idata = p; } if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); diff --git a/stb_image_write.h b/stb_image_write.h index 38d3835..c737bb4 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -166,9 +166,9 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, #endif #ifndef STBIW_MALLOC -#define STBIW_MALLOC(sz) malloc(sz) -#define STBIW_REALLOC(p,sz) realloc(p,sz) -#define STBIW_FREE(p) free(p) +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,oldsz,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) #endif #ifndef STBIW_MEMMOVE #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) @@ -647,7 +647,7 @@ int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *da static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) { int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; - void *p = STBIW_REALLOC(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2); + void *p = STBIW_REALLOC(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); STBIW_ASSERT(p); if (p) { if (!*arr) ((int *) p)[1] = 0; From 0860860af60659d5803cbc5ecc6a932029b435c2 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 07:19:27 -0800 Subject: [PATCH 30/42] avoid __forceinline in mingw since their definition for C is broken; dummy definitions for malloc et al (note you have to modify source to make this work though anyway); tweak credits change; --- stb_vorbis.c | 17 +++++++++++++++-- tests/stb.dsp | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index ea753df..904209f 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -4,7 +4,7 @@ // Original version written by Sean Barrett in 2007. // // Originally sponsored by RAD Game Tools. Seeking sponsored -// by Phillip Bennefall, Marc Andersen, Elias Software, vgstorm.com, +// by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software, // Aras Pranckevicius, and Sean Barrett. // // LICENSE @@ -557,11 +557,24 @@ enum STBVorbisError #endif #else // STB_VORBIS_NO_CRT #define NULL 0 +#define malloc(s) 0 +#define free(s) ((void) 0) +#define realloc(s) 0 #endif // STB_VORBIS_NO_CRT #include -#if !defined(_MSC_VER) && !(defined(__MINGW32__) && defined(__forceinline)) +#ifdef __MINGW32__ + // eff you mingw: + // "fixed": + // http://sourceforge.net/p/mingw-w64/mailman/message/32882927/ + // "no that broke the build, reverted, who cares about C": + // http://sourceforge.net/p/mingw-w64/mailman/message/32890381/ + #ifdef __forceinline + #undef __forceinline + #endif + #define __forceinline +#elif !defined(_MSC_VER) #if __GNUC__ #define __forceinline inline #else diff --git a/tests/stb.dsp b/tests/stb.dsp index b4e1748..3dcb5c9 100644 --- a/tests/stb.dsp +++ b/tests/stb.dsp @@ -130,6 +130,10 @@ SOURCE=..\stb_leakcheck.h # End Source File # Begin Source File +SOURCE=..\stb_malloc.h +# End Source File +# Begin Source File + SOURCE=..\stb_perlin.h # End Source File # Begin Source File From 95e954c822042edb24d49e836d8ad294edb849fc Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 07:26:16 -0800 Subject: [PATCH 31/42] const correctness for pushdata API; minor tweak to get_samples_interleaved documentation --- stb_vorbis.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 904209f..73dadcf 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -160,10 +160,10 @@ extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); // specification does not bound the size of an individual frame. extern stb_vorbis *stb_vorbis_open_pushdata( - unsigned char *datablock, int datablock_length_in_bytes, + const unsigned char * datablock, int datablock_length_in_bytes, int *datablock_memory_consumed_in_bytes, int *error, - stb_vorbis_alloc *alloc_buffer); + const stb_vorbis_alloc *alloc_buffer); // create a vorbis decoder by passing in the initial data block containing // the ogg&vorbis headers (you don't need to do parse them, just provide // the first N bytes of the file--you're told if it's not enough, see below) @@ -174,7 +174,8 @@ extern stb_vorbis *stb_vorbis_open_pushdata( // incomplete and you need to pass in a larger block from the start of the file extern int stb_vorbis_decode_frame_pushdata( - stb_vorbis *f, unsigned char *datablock, int datablock_length_in_bytes, + stb_vorbis *f, + const unsigned char *datablock, int datablock_length_in_bytes, int *channels, // place to write number of float * buffers float ***output, // place to write float ** array of float * buffers int *samples // place to write number of output samples @@ -297,15 +298,17 @@ extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***out extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); #endif -// decode the next frame and return the number of samples per channel. the -// data is coerced to the number of channels you request according to the +// decode the next frame and return the number of *samples* per channel. +// Note that for interleaved data, you pass in the number of shorts (the +// size of your array), but the return value is the number of samples per +// channel, not the total number of samples. +// +// The data is coerced to the number of channels you request according to the // channel coercion rules (see below). You must pass in the size of your // buffer(s) so that stb_vorbis will not overwrite the end of the buffer. // The maximum buffer size needed can be gotten from get_info(); however, // the Vorbis I specification implies an absolute maximum of 4096 samples -// per channel. Note that for interleaved data, you pass in the number of -// shorts (the size of your array), but the return value is the number of -// samples per channel, not the total number of samples. +// per channel. // Channel coercion rules: // Let M be the number of channels requested, and N the number of channels present, From 3560e553e89f054a70d46ba447fbe9323600e4c9 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 07:42:24 -0800 Subject: [PATCH 32/42] stb_vorbis version history and contributor info --- stb_vorbis.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index 3d1b313..eff8c98 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -33,13 +33,10 @@ // Laurent Gomila Marc LeBlanc Ronny Chevalier // Bernhard Wodo Evan Balster "alxprd"@github // Tom Beaumont Ingo Leitgeb Nicolas Guillemot -// Phillip Bennefall -// (If you reported a bug but do not appear in this list, it is because -// someone else reported the bug before you. There were too many of you to -// list them all because I was lax about updating for a long time, sorry.) +// Phillip Bennefall Rohit // // Partial history: -// 1.07 - 2015/11/08 - fixes for crashes on invalid files +// 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const // 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) // some crash fixes when out of memory or with corrupt files // fix some inappropriately signed shifts @@ -50,8 +47,6 @@ // 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float (interleaved was correct) // 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in >2-channel; // (API change) report sample rate for decode-full-file funcs -// 0.99996 - - bracket #include for macintosh compilation -// 0.99995 - - avoid alias-optimization issue in float-to-int conversion // // See end of file for full version history. @@ -5416,6 +5411,8 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in #endif // STB_VORBIS_NO_PULLDATA_API /* Version history + 1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API + some more crash fixes when out of memory or with corrupt files 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) some crash fixes when out of memory or with corrupt files 1.05 - 2015/04/19 - don't define __forceinline if it's redundant From 1964d53d70507f26a82286208afb5a54a2208392 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 08:01:42 -0800 Subject: [PATCH 33/42] update version number and version history with everything committed to date --- stb_image.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stb_image.h b/stb_image.h index 429f2ff..3a8f3b1 100644 --- a/stb_image.h +++ b/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.08 - public domain image loader - http://nothings.org/stb_image.h +/* stb_image - v2.09 - public domain image loader - http://nothings.org/stb_image.h no warranty implied; use at your own risk Do this: @@ -6391,6 +6391,8 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: + 2.09 (2016-01-16) allow comments in PNM files + info() for BMP to shares code instead of sloppy parse 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA 2.07 (2015-09-13) fix compiler warnings partial animated GIF support From e30b75af8bfe864e77664b3b1e8c22b211f406b1 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 08:05:40 -0800 Subject: [PATCH 34/42] update contributor list --- stb_image.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stb_image.h b/stb_image.h index 21c1e29..7c1c91f 100644 --- a/stb_image.h +++ b/stb_image.h @@ -213,6 +213,7 @@ Nathan Reed Michaelangel007@github Nick Verigakis + svdijk@github LICENSE From 9cb29b6b39c1c2cd52843da6fef922852ee020aa Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 08:13:55 -0800 Subject: [PATCH 35/42] update and reorganize contributor list --- stb_image.h | 67 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/stb_image.h b/stb_image.h index 56779ad..ebe7f16 100644 --- a/stb_image.h +++ b/stb_image.h @@ -175,45 +175,34 @@ ============================ Contributors ========================= - Image formats Bug fixes & warning fixes - Sean Barrett (jpeg, png, bmp) Marc LeBlanc - Nicolas Schulz (hdr, psd) Christpher Lloyd - Jonathan Dummer (tga) Dave Moore - Jean-Marc Lienher (gif) Won Chun - Tom Seddon (pic) the Horde3D community - Thatcher Ulrich (psd) Janez Zemva - Ken Miller (pgm, ppm) Jonathan Blow - urraka@github (animated gif) Laurent Gomila - Aruelien Pocheville - Ryamond Barbiero - David Woo - Extensions, features Martin Golini - Jetro Lauha (stbi_info) Roy Eltham - Martin "SpartanJ" Golini (stbi_info) Luke Graham - James "moose2000" Brown (iPhone PNG) Thomas Ruf - Ben "Disch" Wenger (io callbacks) John Bartholomew - Omar Cornut (1/2/4-bit PNG) Ken Hamada - Nicolas Guillemot (vertical flip) Cort Stratton - Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski - Junggon Kim (PNM comments) Thibault Reuille - Paul Du Bois - Guillaume George - Jerry Jansson - Hayaki Saito - Johan Duparc - Ronny Chevalier - Optimizations & bugfixes Michal Cichon - Fabian "ryg" Giesen Tero Hanninen - Arseny Kapoulkine Sergio Gonzalez - Cass Everitt - Engin Manap - If your name should be here but Martins Mozeiko - isn't, let Sean know. Joseph Thomson - Phil Jordan - Nathan Reed - Michaelangel007@github - Nick Verigakis - svdijk@github + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + urraka@github (animated gif) Junggon Kim (PNM comments) + + Optimizations & bugfixes + Fabian "ryg" Giesen + Arseny Kapoulkine + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson + Dave Moore Roy Eltham Hayaki Saito Phil Jordan + Won Chun Luke Graham Johan Duparc Nathan Reed + the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis + Janez Zemva John Bartholomew Michal Cichon svdijk@github + Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson + Laurent Gomila Cort Stratton Sergio Gonzalez + Aruelien Pocheville Thibault Reuille Cass Everitt + Ryamond Barbiero Paul Du Bois Engin Manap + Blazej Dariusz Roszkowski + Michaelangel007@github + LICENSE From c8e50127c553ee578d76797adfca2f7825d25016 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 09:37:34 -0800 Subject: [PATCH 36/42] contributor list --- stb_image.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stb_image.h b/stb_image.h index cb7ff67..6faf88c 100644 --- a/stb_image.h +++ b/stb_image.h @@ -184,6 +184,7 @@ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) urraka@github (animated gif) Junggon Kim (PNM comments) + Daniel Gibson (16-bit TGA) Optimizations & bugfixes Fabian "ryg" Giesen From 82ca643ef3b1af0840f4069d691e2c2871fc127e Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 09:47:22 -0800 Subject: [PATCH 37/42] change previous explicitly-sized realloc support to be new API and unbreak old API --- stb_image.h | 20 ++++++++++++-------- stb_image_write.h | 20 +++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/stb_image.h b/stb_image.h index e2a89ef..7709f6c 100644 --- a/stb_image.h +++ b/stb_image.h @@ -621,18 +621,22 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) #endif -#if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC) +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) // ok -#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) // ok #else -#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC." +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." #endif #ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,oldsz,newsz) realloc(p,newsz) -#define STBI_FREE(p) free(p) +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) #endif // x86/x64 detection @@ -3615,7 +3619,7 @@ static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room limit = old_limit = (int) (z->zout_end - z->zout_start); while (cur + n > limit) limit *= 2; - q = (char *) STBI_REALLOC(z->zout_start, old_limit, limit); + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); if (q == NULL) return stbi__err("outofmem", "Out of memory"); z->zout_start = q; z->zout = q + cur; @@ -4405,7 +4409,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; while (ioff + c.length > idata_limit) idata_limit *= 2; - p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); z->idata = p; } if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); diff --git a/stb_image_write.h b/stb_image_write.h index c737bb4..aa4b828 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -157,19 +157,25 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, #include #include -#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && defined(STBIW_REALLOC) +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) // ok -#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) // ok #else -#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC." +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." #endif #ifndef STBIW_MALLOC -#define STBIW_MALLOC(sz) malloc(sz) -#define STBIW_REALLOC(p,oldsz,newsz) realloc(p,newsz) -#define STBIW_FREE(p) free(p) +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) #endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + #ifndef STBIW_MEMMOVE #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) #endif @@ -647,7 +653,7 @@ int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *da static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) { int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; - void *p = STBIW_REALLOC(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); STBIW_ASSERT(p); if (p) { if (!*arr) ((int *) p)[1] = 0; From 79f29bafffdbf33cb566102b1635c144beba0f28 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 09:48:01 -0800 Subject: [PATCH 38/42] fix previous stb_vorbis check-in that didn't actually compile; make stb_vorbis_alloc* parameter in APIs be const --- stb_vorbis.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/stb_vorbis.c b/stb_vorbis.c index eff8c98..d54087f 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -234,18 +234,18 @@ extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *chan // When you're done with it, just free() the pointer returned in *output. extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, - int *error, stb_vorbis_alloc *alloc_buffer); + int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an ogg vorbis stream in memory (note // this must be the entire stream!). on failure, returns NULL and sets *error #ifndef STB_VORBIS_NO_STDIO extern stb_vorbis * stb_vorbis_open_filename(const char *filename, - int *error, stb_vorbis_alloc *alloc_buffer); + int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from a filename via fopen(). on failure, // returns NULL and sets *error (possibly to VORBIS_file_open_failure). extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, - int *error, stb_vorbis_alloc *alloc_buffer); + int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell). on failure, returns NULL and sets *error. // note that stb_vorbis must "own" this stream; if you seek it in between @@ -255,7 +255,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, // function, stb_vorbis_open_file_section(), to limit it. extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, - int *error, stb_vorbis_alloc *alloc_buffer, unsigned int len); + int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell); the stream will be of length 'len' bytes. // on failure, returns NULL and sets *error. note that stb_vorbis must "own" @@ -4235,7 +4235,7 @@ void stb_vorbis_close(stb_vorbis *p) setup_free(p,p); } -static void vorbis_init(stb_vorbis *p, stb_vorbis_alloc *z) +static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) { memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start if (z) { @@ -4393,11 +4393,11 @@ static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len) // return value: number of bytes we used int stb_vorbis_decode_frame_pushdata( - stb_vorbis *f, // the file we're decoding - uint8 *data, int data_len, // the memory available for decoding - int *channels, // place to write number of float * buffers - float ***output, // place to write float ** array of float * buffers - int *samples // place to write number of output samples + stb_vorbis *f, // the file we're decoding + const uint8 *data, int data_len, // the memory available for decoding + int *channels, // place to write number of float * buffers + float ***output, // place to write float ** array of float * buffers + int *samples // place to write number of output samples ) { int i; @@ -4407,11 +4407,11 @@ int stb_vorbis_decode_frame_pushdata( if (f->page_crc_tests >= 0) { *samples = 0; - return vorbis_search_for_page_pushdata(f, data, data_len); + return vorbis_search_for_page_pushdata(f, (uint8 *) data, data_len); } - f->stream = data; - f->stream_end = data + data_len; + f->stream = (uint8 *) data; + f->stream_end = (uint8 *) data + data_len; f->error = VORBIS__no_error; // check that we have the entire packet in memory @@ -4463,14 +4463,14 @@ int stb_vorbis_decode_frame_pushdata( } stb_vorbis *stb_vorbis_open_pushdata( - unsigned char *data, int data_len, // the memory available for decoding + const unsigned char *data, int data_len, // the memory available for decoding int *data_used, // only defined if result is not NULL - int *error, stb_vorbis_alloc *alloc) + int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; vorbis_init(&p, alloc); - p.stream = data; - p.stream_end = data + data_len; + p.stream = (uint8 *) data; + p.stream_end = (uint8 *) data + data_len; p.push_mode = TRUE; if (!start_decoder(&p)) { if (p.eof) @@ -4990,7 +4990,7 @@ int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) #ifndef STB_VORBIS_NO_STDIO -stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, stb_vorbis_alloc *alloc, unsigned int length) +stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length) { stb_vorbis *f, p; vorbis_init(&p, alloc); @@ -5011,7 +5011,7 @@ stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *er return NULL; } -stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc) { unsigned int len, start; start = ftell(file); @@ -5021,7 +5021,7 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, stb return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); } -stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { FILE *f = fopen(filename, "rb"); if (f) @@ -5031,7 +5031,7 @@ stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, stb_vorb } #endif // STB_VORBIS_NO_STDIO -stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; if (data == NULL) return NULL; From ac748cba9bd9751bd5b219d0eca4c73ca94b583d Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 09:57:04 -0800 Subject: [PATCH 39/42] update contributor list, version history, version number --- stb_image.h | 7 +++++-- stb_image_write.h | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/stb_image.h b/stb_image.h index 7709f6c..5e07746 100644 --- a/stb_image.h +++ b/stb_image.h @@ -146,6 +146,7 @@ Latest revision history: + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA 2.07 (2015-09-13) partial animated GIF support limited 16-bit PSD support @@ -198,7 +199,7 @@ the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis Janez Zemva John Bartholomew Michal Cichon svdijk@github Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson - Laurent Gomila Cort Stratton Sergio Gonzalez + Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github Aruelien Pocheville Thibault Reuille Cass Everitt Ryamond Barbiero Paul Du Bois Engin Manap Blazej Dariusz Roszkowski @@ -6456,11 +6457,13 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA 2.07 (2015-09-13) fix compiler warnings partial animated GIF support - limited 16-bit PSD support + limited 16-bpc PSD support #ifdef unused functions bug with < 92 byte PIC,PNM,HDR,TGA 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value diff --git a/stb_image_write.h b/stb_image_write.h index aa4b828..2d1e670 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -1,4 +1,4 @@ -/* stb_image_write - v1.00 - public domain - http://nothings.org/stb/stb_image_write.h +/* stb_image_write - v1.01 - public domain - http://nothings.org/stb/stb_image_write.h writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk @@ -98,6 +98,7 @@ CREDITS: github:Chribba Guillaume Chereau github:jry2 + github:romigrou LICENSE @@ -974,6 +975,8 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, #endif // STB_IMAGE_WRITE_IMPLEMENTATION /* Revision history + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support 1.00 (2015-09-14) installable file IO function 0.99 (2015-09-13) From 472c4c82a44378b64245b1fbeaa9849f2cd0c51b Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 10:00:19 -0800 Subject: [PATCH 40/42] update version history --- stb_image.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stb_image.h b/stb_image.h index 5e07746..be25097 100644 --- a/stb_image.h +++ b/stb_image.h @@ -6458,8 +6458,10 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int revision history: 2.09 (2016-01-16) allow comments in PNM files 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling info() for BMP to shares code instead of sloppy parse can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA 2.07 (2015-09-13) fix compiler warnings partial animated GIF support From 8521c38956577468acc4c942348fb563ee0f2646 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 10:09:35 -0800 Subject: [PATCH 41/42] tweak previous crc commit --- stb_image_write.h | 104 ++++++++++++++++++++---------------------------------- 1 file changed, 38 insertions(+), 66 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index c6c604a..d76a616 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -100,6 +100,7 @@ CREDITS: github:jry2 github:romigrou Sergio Gonzalez + Jonas Karlsson LICENSE @@ -827,78 +828,47 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l return (unsigned char *) stbiw__sbraw(out); } -unsigned int stbiw__crc32(unsigned char *buffer, int len) +static unsigned int stbiw__crc32(unsigned char *buffer, int len) { static unsigned int crc_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; unsigned int crc = ~0u; - for (int i=0; i < len; ++i) + int i; + for (i=0; i < len; ++i) crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; return ~crc; } @@ -1044,6 +1014,8 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, /* Revision history 1.01 (2016-01-16) STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues 1.00 (2015-09-14) installable file IO function 0.99 (2015-09-13) From f1d2002a1db72294478943146052de7fac452327 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sat, 16 Jan 2016 10:16:23 -0800 Subject: [PATCH 42/42] update contributor list --- stb_image_write.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stb_image_write.h b/stb_image_write.h index 3407ca1..98fa410 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -101,6 +101,7 @@ CREDITS: github:romigrou Sergio Gonzalez Jonas Karlsson + Filip Wasil LICENSE