summaryrefslogtreecommitdiffhomepage
path: root/src/stb_image.h
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2015-05-11 18:22:16 +0200
committerraysan5 <[email protected]>2015-05-11 18:22:16 +0200
commite25f1227c0dfde7ba5c69237a4bbfe1277841135 (patch)
tree64a5beedab8191b5c867228042be4cbd3a589d7f /src/stb_image.h
parent4e4b6bef21a3913e924ac83259cf00e18b17f780 (diff)
downloadraylib-e25f1227c0dfde7ba5c69237a4bbfe1277841135.tar.gz
raylib-e25f1227c0dfde7ba5c69237a4bbfe1277841135.zip
Updated stb headers
Diffstat (limited to 'src/stb_image.h')
-rw-r--r--src/stb_image.h206
1 files changed, 161 insertions, 45 deletions
diff --git a/src/stb_image.h b/src/stb_image.h
index 39cbb7ad..1249c303 100644
--- a/src/stb_image.h
+++ b/src/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.00b - public domain image loader - http://nothings.org/stb_image.h
+/* stb_image - v2.05 - public domain image loader - http://nothings.org/stb_image.h
no warranty implied; use at your own risk
Do this:
@@ -143,6 +143,13 @@
Latest revision history:
+ 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
+ 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
+ 2.03 (2015-04-12) additional corruption checking
+ stbi_set_flip_vertically_on_load
+ fix NEON support; fix mingw support
+ 2.02 (2015-01-19) fix incorrect assert, fix warning
+ 2.01 (2015-01-17) fix various warnings
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD
progressive JPEG
@@ -154,8 +161,6 @@
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
optimize PNG
fix bug in interlaced PNG with user-specified channel count
- 1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG
- 1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc
See end of file for full revision history.
@@ -178,7 +183,7 @@
James "moose2000" Brown (iPhone PNG) Roy Eltham
Ben "Disch" Wenger (io callbacks) Luke Graham
Omar Cornut (1/2/4-bit PNG) Thomas Ruf
- John Bartholomew
+ Nicolas Guillemot (vertical flip) John Bartholomew
Ken Hamada
Optimizations & bugfixes Cort Stratton
Fabian "ryg" Giesen Blazej Dariusz Roszkowski
@@ -191,6 +196,12 @@
Ronny Chevalier
Michal Cichon
Tero Hanninen
+ Sergio Gonzalez
+ Cass Everitt
+ Engin Manap
+ Martins Mozeiko
+ Joseph Thomson
+ Phil Jordan
License:
This software is in the public domain. Where that dedication is not
@@ -371,6 +382,7 @@ License:
// and only if iPhone convert-to-rgb processing is on).
//
+
#define STBI_NO_HDR // RaySan: not required by raylib
#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2
@@ -489,6 +501,8 @@ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultipl
// or just pass them through "as-is"
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
+// flip the image vertically, so the first pixel in the output array is the bottom left
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
// ZLIB client - used by PNG, available for other purposes
@@ -626,7 +640,38 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI_FREE(p) free(p)
#endif
-#if !defined(STBI_NO_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
+// x86/x64 detection
+#if defined(__x86_64__) || defined(_M_X64)
+#define STBI__X64_TARGET
+#elif defined(__i386) || defined(_M_IX86)
+#define STBI__X86_TARGET
+#endif
+
+#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
+// NOTE: not clear do we actually need this for the 64-bit path?
+// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
+// (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
+// this is just broken and gcc are jerks for not fixing it properly
+// http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
+#define STBI_NO_SIMD
+#endif
+
+#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
+// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
+//
+// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
+// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
+// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
+// simultaneously enabling "-mstackrealign".
+//
+// See https://github.com/nothings/stb/issues/81 for more information.
+//
+// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
+// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
+#define STBI_NO_SIMD
+#endif
+
+#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
#define STBI_SSE2
#include <emmintrin.h>
@@ -879,7 +924,14 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
#endif
-static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+static int stbi__vertically_flip_on_load = 0;
+
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
+{
+ stbi__vertically_flip_on_load = flag_true_if_should_flip;
+}
+
+static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
#ifndef STBI_NO_JPEG
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
@@ -919,6 +971,53 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
}
+static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+ unsigned char *result = stbi__load_main(s, x, y, comp, req_comp);
+
+ if (stbi__vertically_flip_on_load && result != NULL) {
+ int w = *x, h = *y;
+ int depth = req_comp ? req_comp : *comp;
+ int row,col,z;
+ stbi_uc temp;
+
+ // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
+ for (row = 0; row < (h>>1); row++) {
+ for (col = 0; col < w; col++) {
+ for (z = 0; z < depth; z++) {
+ temp = result[(row * w + col) * depth + z];
+ result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
+ result[((h - row - 1) * w + col) * depth + z] = temp;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
+{
+ if (stbi__vertically_flip_on_load && result != NULL) {
+ int w = *x, h = *y;
+ int depth = req_comp ? req_comp : *comp;
+ int row,col,z;
+ float temp;
+
+ // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
+ for (row = 0; row < (h>>1); row++) {
+ for (col = 0; col < w; col++) {
+ for (z = 0; z < depth; z++) {
+ temp = result[(row * w + col) * depth + z];
+ result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
+ result[((h - row - 1) * w + col) * depth + z] = temp;
+ }
+ }
+ }
+ }
+}
+
+
#ifndef STBI_NO_STDIO
static FILE *stbi__fopen(char const *filename, char const *mode)
@@ -949,7 +1048,7 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
unsigned char *result;
stbi__context s;
stbi__start_file(&s,f);
- result = stbi_load_main(&s,x,y,comp,req_comp);
+ result = stbi__load_flip(&s,x,y,comp,req_comp);
if (result) {
// need to 'unget' all the characters in the IO buffer
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
@@ -962,25 +1061,29 @@ STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, i
{
stbi__context s;
stbi__start_mem(&s,buffer,len);
- return stbi_load_main(&s,x,y,comp,req_comp);
+ return stbi__load_flip(&s,x,y,comp,req_comp);
}
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
- return stbi_load_main(&s,x,y,comp,req_comp);
+ return stbi__load_flip(&s,x,y,comp,req_comp);
}
#ifndef STBI_NO_LINEAR
-static float *stbi_loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
unsigned char *data;
#ifndef STBI_NO_HDR
- if (stbi__hdr_test(s))
- return stbi__hdr_load(s,x,y,comp,req_comp);
+ if (stbi__hdr_test(s)) {
+ float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp);
+ if (hdr_data)
+ stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
+ return hdr_data;
+ }
#endif
- data = stbi_load_main(s, x, y, comp, req_comp);
+ data = stbi__load_flip(s, x, y, comp, req_comp);
if (data)
return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
@@ -990,14 +1093,14 @@ STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, in
{
stbi__context s;
stbi__start_mem(&s,buffer,len);
- return stbi_loadf_main(&s,x,y,comp,req_comp);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
}
STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
- return stbi_loadf_main(&s,x,y,comp,req_comp);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
}
#ifndef STBI_NO_STDIO
@@ -1015,7 +1118,7 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
{
stbi__context s;
stbi__start_file(&s,f);
- return stbi_loadf_main(&s,x,y,comp,req_comp);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
}
#endif // !STBI_NO_STDIO
@@ -1138,6 +1241,10 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
static void stbi__skip(stbi__context *s, int n)
{
+ if (n < 0) {
+ s->img_buffer = s->img_buffer_end;
+ return;
+ }
if (s->io.read) {
int blen = (int) (s->img_buffer_end - s->img_buffer);
if (blen < n) {
@@ -1546,6 +1653,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
k = stbi_lrot(j->code_buffer, n);
+ STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
j->code_bits -= n;
@@ -1730,15 +1838,12 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
short *p = &data[stbi__jpeg_dezigzag[k]];
if (*p != 0)
if (stbi__jpeg_get_bit(j))
- {
- if ((*p & bit)==0)
- {
+ if ((*p & bit)==0) {
if (*p > 0)
*p += bit;
else
*p -= bit;
}
- }
}
} else {
k = j->spec_start;
@@ -1754,8 +1859,11 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
if (r)
j->eob_run += stbi__jpeg_get_bits(j, r);
r = 64; // force end of block
- } else
- r = 16; // r=15 is the code for 16 0s
+ } else {
+ // r=15 s=0 should write 16 0s, so we just do
+ // a run of 15 0s and then write s (which is 0),
+ // so we don't have to do anything special here
+ }
} else {
if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
// sign bit
@@ -1767,27 +1875,21 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
// advance by r
while (k <= j->spec_end) {
- short *p = &data[stbi__jpeg_dezigzag[k]];
+ short *p = &data[stbi__jpeg_dezigzag[k++]];
if (*p != 0) {
if (stbi__jpeg_get_bit(j))
- {
- if ((*p & bit)==0)
- {
+ if ((*p & bit)==0) {
if (*p > 0)
*p += bit;
else
*p -= bit;
}
- }
- ++k;
} else {
if (r == 0) {
- if (s)
- data[stbi__jpeg_dezigzag[k++]] = s;
+ *p = (short) s;
break;
}
--r;
- ++k;
}
}
} while (k <= j->spec_end);
@@ -2207,7 +2309,7 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
// pass 1
dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
dct_trn16(row2, row3);
- dct_trn16(row4, row5);
+ dct_trn16(row4, row5);
dct_trn16(row6, row7);
// pass 2
@@ -2434,7 +2536,6 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
for (x=0; x < z->img_comp[n].h; ++x) {
int x2 = (i*z->img_comp[n].h + x);
int y2 = (j*z->img_comp[n].v + y);
- //int ha = z->img_comp[n].ha; // RaySan: Unused, commented to avoid warning
short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
return 0;
@@ -2701,6 +2802,10 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
static int stbi__decode_jpeg_image(stbi__jpeg *j)
{
int m;
+ for (m = 0; m < 4; m++) {
+ j->img_comp[m].raw_data = NULL;
+ j->img_comp[m].raw_coeff = NULL;
+ }
j->restart_interval = 0;
if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
m = stbi__get_marker(j);
@@ -3013,7 +3118,7 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
__m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
__m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
__m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f));
- __m128i y_bias = _mm_set1_epi8((char) 128);
+ __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
__m128i xw = _mm_set1_epi16(255); // alpha channel
for (; i+7 < count; i += 8) {
@@ -3380,7 +3485,8 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
++sizes[sizelist[i]];
sizes[0] = 0;
for (i=1; i < 16; ++i)
- STBI_ASSERT(sizes[i] <= (1 << i));
+ if (sizes[i] > (1 << i))
+ return stbi__err("bad sizes", "Corrupt PNG");
code = 0;
for (i=1; i < 16; ++i) {
next_code[i] = code;
@@ -3388,7 +3494,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
z->firstsymbol[i] = (stbi__uint16) k;
code = (code + sizes[i]);
if (sizes[i])
- if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt JPEG");
+ if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
z->maxcode[i] = code << (16-i); // preshift for inner loop
code <<= 1;
k += sizes[i];
@@ -3557,9 +3663,9 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
p = (stbi_uc *) (zout - dist);
if (dist == 1) { // run of one byte; common in images.
stbi_uc v = *p;
- do *zout++ = v; while (--len);
+ if (len) { do *zout++ = v; while (--len); }
} else {
- do *zout++ = *p++; while (--len);
+ if (len) { do *zout++ = *p++; while (--len); }
}
}
}
@@ -3587,7 +3693,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
n = 0;
while (n < hlit + hdist) {
int c = stbi__zhuffman_decode(a, &z_codelength);
- STBI_ASSERT(c >= 0 && c < 19);
+ if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
if (c < 16)
lencodes[n++] = (stbi_uc) c;
else if (c == 16) {
@@ -4019,7 +4125,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
cur[i*2+0] = cur[i];
}
} else {
- assert(img_n == 3);
+ STBI_ASSERT(img_n == 3);
for (i=x-1; i >= 0; --i) {
cur[i*4+3] = 255;
cur[i*4+2] = cur[i*3+2];
@@ -4284,6 +4390,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
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_uc *p;
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
@@ -4643,7 +4750,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
}
} else {
for (i=0; i < (int) s->img_x; ++i) {
- stbi__uint32 v = (stbi__uint32) (bpp == 16 ? stbi__get16le(s) : stbi__get32le(s));
+ stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
int a;
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
@@ -4800,7 +4907,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
*y = tga_height;
if (comp) *comp = tga_comp;
- tga_data = (unsigned char*)stbi__malloc( tga_width * tga_height * tga_comp );
+ tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp );
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
// skip to the data's starting position (offset usually = 0)
@@ -5461,6 +5568,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
stbi__gif_lzw *p;
lzw_cs = stbi__get8(s);
+ if (lzw_cs > 12) return NULL;
clear = 1 << lzw_cs;
first = 1;
codesize = lzw_cs + 1;
@@ -6130,7 +6238,7 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PSD
if (stbi__psd_info(s, x, y, comp)) return 1;
#endif
-
+
#ifndef STBI_NO_PIC
if (stbi__pic_info(s, x, y, comp)) return 1;
#endif
@@ -6192,6 +6300,13 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
revision history:
+ 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
+ 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
+ 2.03 (2015-04-12) extra corruption checking (mmozeiko)
+ stbi_set_flip_vertically_on_load (nguillemot)
+ fix NEON support; fix mingw support
+ 2.02 (2015-01-19) fix incorrect assert, fix warning
+ 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
progressive JPEG (stb)
@@ -6276,7 +6391,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
1.21 fix use of 'stbi_uc' in header (reported by jon blow)
1.20 added support for Softimage PIC, by Tom Seddon
1.19 bug in interlaced PNG corruption check (found by ryg)
- 1.18 2008-08-02
+ 1.18 (2008-08-02)
fix a threading bug (local mutable static)
1.17 support interlaced PNG
1.16 major bugfix - stbi__convert_format converted one too many pixels
@@ -6321,5 +6436,6 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
0.51 obey req_comp requests, 1-component jpegs return as 1-component,
on 'test' only check type, not whether we support this variant
- 0.50 first released version
+ 0.50 (2006-11-19)
+ first released version
*/