Merge branch 'working'

pull/26/head
Sean Barrett 2014-07-09 23:44:48 -07:00
commit b2cbed2634
1 changed files with 50 additions and 32 deletions

View File

@ -6,6 +6,8 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
before you include this file in *one* C or C++ file to create the implementation. before you include this file in *one* C or C++ file to create the implementation.
#define STBI_ASSERT(x) to avoid using assert.h.
QUICK NOTES: QUICK NOTES:
Primarily of interest to game developers and other people who can Primarily of interest to game developers and other people who can
avoid problematic images and only need the trivial interface avoid problematic images and only need the trivial interface
@ -26,6 +28,7 @@
- overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
Latest revisions: Latest revisions:
1.42 (2014-07-09) no _CRT_SECURE_NO_WARNINGS; error-path fixes; STBI_ASSERT
1.41 (2014-06-25) fix search&replace that messed up comments/error messages 1.41 (2014-06-25) fix search&replace that messed up comments/error messages
1.40 (2014-06-22) gcc warning 1.40 (2014-06-22) gcc warning
1.39 (2014-06-15) TGA optimization fix, multiple BMP fixes 1.39 (2014-06-15) TGA optimization fix, multiple BMP fixes
@ -33,8 +36,6 @@
1.37 (2014-06-04) remove duplicate typedef 1.37 (2014-06-04) remove duplicate typedef
1.36 (2014-06-03) converted to header file, allow reading incorrect iphoned-images without iphone flag 1.36 (2014-06-03) converted to header file, allow reading incorrect iphoned-images without iphone flag
1.35 (2014-05-27) warnings, bugfixes, TGA optimization, etc 1.35 (2014-05-27) warnings, bugfixes, TGA optimization, etc
1.34 (unknown ) warning fix
1.33 (2011-07-14) minor fixes suggested by Dave Moore
See end of file for full revision history. See end of file for full revision history.
@ -189,12 +190,6 @@
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
#if defined(_MSC_VER) && _MSC_VER >= 1400
#define _CRT_SECURE_NO_WARNINGS // suppress warnings about fopen()
#pragma warning(push)
#pragma warning(disable:4996) // suppress even more warnings about fopen()
#endif
#include <stdio.h> #include <stdio.h>
#endif // STBI_NO_STDIO #endif // STBI_NO_STDIO
@ -354,8 +349,11 @@ STBIDEF void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
#include <stdio.h> #include <stdio.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <string.h>
#ifndef STBI_ASSERT
#include <assert.h> #include <assert.h>
#define STBI_ASSERT(x) assert(x)
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> // ptrdiff_t on osx #include <stddef.h> // ptrdiff_t on osx
@ -574,9 +572,23 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
} }
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
FILE *stbi__fopen(char const *filename, char const *mode)
{
FILE *f;
#if _MSC_VER >= 1400
if (0 != fopen_s(&f, filename, "rb"))
f=0;
#else
f = fopen(filename, "rb");
#endif
return f;
}
STBIDEF unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) STBIDEF unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
{ {
FILE *f = fopen(filename, "rb"); FILE *f = stbi__fopen(filename, "rb");
unsigned char *result; unsigned char *result;
if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
result = stbi_load_from_file(f,x,y,comp,req_comp); result = stbi_load_from_file(f,x,y,comp,req_comp);
@ -644,8 +656,8 @@ float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
{ {
FILE *f = fopen(filename, "rb");
float *result; float *result;
FILE *f = stbi__fopen(filename, "rb");
if (!f) return stbi__errpf("can't fopen", "Unable to open file"); if (!f) return stbi__errpf("can't fopen", "Unable to open file");
result = stbi_loadf_from_file(f,x,y,comp,req_comp); result = stbi_loadf_from_file(f,x,y,comp,req_comp);
fclose(f); fclose(f);
@ -682,7 +694,7 @@ int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
STBIDEF int stbi_is_hdr (char const *filename) STBIDEF int stbi_is_hdr (char const *filename)
{ {
FILE *f = fopen(filename, "rb"); FILE *f = stbi__fopen(filename, "rb");
int result=0; int result=0;
if (f) { if (f) {
result = stbi_is_hdr_from_file(f); result = stbi_is_hdr_from_file(f);
@ -860,7 +872,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
unsigned char *good; unsigned char *good;
if (req_comp == img_n) return data; if (req_comp == img_n) return data;
assert(req_comp >= 1 && req_comp <= 4); STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
good = (unsigned char *) malloc(req_comp * x * y); good = (unsigned char *) malloc(req_comp * x * y);
if (good == NULL) { if (good == NULL) {
@ -889,7 +901,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break;
CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break;
CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break;
default: assert(0); default: STBI_ASSERT(0);
} }
#undef CASE #undef CASE
} }
@ -1126,7 +1138,7 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
// convert the huffman code to the symbol id // convert the huffman code to the symbol id
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
assert((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
// convert the id to a symbol // convert the id to a symbol
j->code_bits -= k; j->code_bits -= k;
@ -1807,8 +1819,9 @@ static void stbi__cleanup_jpeg(stbi__jpeg *j)
{ {
int i; int i;
for (i=0; i < j->s->img_n; ++i) { for (i=0; i < j->s->img_n; ++i) {
if (j->img_comp[i].data) { if (j->img_comp[i].raw_data) {
free(j->img_comp[i].raw_data); free(j->img_comp[i].raw_data);
j->img_comp[i].raw_data = NULL;
j->img_comp[i].data = NULL; j->img_comp[i].data = NULL;
} }
if (j->img_comp[i].linebuf) { if (j->img_comp[i].linebuf) {
@ -1831,9 +1844,10 @@ typedef struct
static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
{ {
int n, decode_n; int n, decode_n;
z->s->img_n = 0; // make stbi__cleanup_jpeg safe
// validate req_comp // validate req_comp
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
z->s->img_n = 0;
// load a jpeg image from whichever source // load a jpeg image from whichever source
if (!decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } if (!decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
@ -1998,7 +2012,7 @@ stbi_inline static int stbi__bitreverse16(int n)
stbi_inline static int stbi__bit_reverse(int v, int bits) stbi_inline static int stbi__bit_reverse(int v, int bits)
{ {
assert(bits <= 16); STBI_ASSERT(bits <= 16);
// to bit reverse n bits, reverse 16 and shift // to bit reverse n bits, reverse 16 and shift
// stbi__err.g. 11 bits, bit reverse and shift away 5 // stbi__err.g. 11 bits, bit reverse and shift away 5
return stbi__bitreverse16(v) >> (16-bits); return stbi__bitreverse16(v) >> (16-bits);
@ -2016,7 +2030,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
++sizes[sizelist[i]]; ++sizes[sizelist[i]];
sizes[0] = 0; sizes[0] = 0;
for (i=1; i < 16; ++i) for (i=1; i < 16; ++i)
assert(sizes[i] <= (1 << i)); STBI_ASSERT(sizes[i] <= (1 << i));
code = 0; code = 0;
for (i=1; i < 16; ++i) { for (i=1; i < 16; ++i) {
next_code[i] = code; next_code[i] = code;
@ -2078,7 +2092,7 @@ stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
static void stbi__fill_bits(stbi__zbuf *z) static void stbi__fill_bits(stbi__zbuf *z)
{ {
do { do {
assert(z->code_buffer < (1U << z->num_bits)); STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
z->code_buffer |= stbi__zget8(z) << z->num_bits; z->code_buffer |= stbi__zget8(z) << z->num_bits;
z->num_bits += 8; z->num_bits += 8;
} while (z->num_bits <= 24); } while (z->num_bits <= 24);
@ -2115,7 +2129,7 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
if (s == 16) return -1; // invalid code! if (s == 16) return -1; // invalid code!
// code size is s, so: // code size is s, so:
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
assert(z->size[b] == s); STBI_ASSERT(z->size[b] == s);
a->code_buffer >>= s; a->code_buffer >>= s;
a->num_bits -= s; a->num_bits -= s;
return z->value[b]; return z->value[b];
@ -2202,7 +2216,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
n = 0; n = 0;
while (n < hlit + hdist) { while (n < hlit + hdist) {
int c = stbi__zhuffman_decode(a, &z_codelength); int c = stbi__zhuffman_decode(a, &z_codelength);
assert(c >= 0 && c < 19); STBI_ASSERT(c >= 0 && c < 19);
if (c < 16) if (c < 16)
lencodes[n++] = (stbi_uc) c; lencodes[n++] = (stbi_uc) c;
else if (c == 16) { else if (c == 16) {
@ -2214,7 +2228,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
memset(lencodes+n, 0, c); memset(lencodes+n, 0, c);
n += c; n += c;
} else { } else {
assert(c == 18); STBI_ASSERT(c == 18);
c = stbi__zreceive(a,7)+11; c = stbi__zreceive(a,7)+11;
memset(lencodes+n, 0, c); memset(lencodes+n, 0, c);
n += c; n += c;
@ -2239,7 +2253,7 @@ static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
a->code_buffer >>= 8; a->code_buffer >>= 8;
a->num_bits -= 8; a->num_bits -= 8;
} }
assert(a->num_bits == 0); STBI_ASSERT(a->num_bits == 0);
// now fill header the normal way // now fill header the normal way
while (k < 4) while (k < 4)
header[k++] = stbi__zget8(a); header[k++] = stbi__zget8(a);
@ -2468,7 +2482,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
stbi__uint32 i,j,stride = x*out_n; stbi__uint32 i,j,stride = x*out_n;
int k; int k;
int img_n = s->img_n; // copy it into a local for later int img_n = s->img_n; // copy it into a local for later
assert(out_n == s->img_n || out_n == s->img_n+1); STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
a->out = (stbi_uc *) malloc(x * y * out_n); a->out = (stbi_uc *) malloc(x * y * out_n);
if (!a->out) return stbi__err("outofmem", "Out of memory"); if (!a->out) return stbi__err("outofmem", "Out of memory");
if (s->img_x == x && s->img_y == y) { if (s->img_x == x && s->img_y == y) {
@ -2516,7 +2530,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
} }
#undef CASE #undef CASE
} else { } else {
assert(img_n+1 == out_n); STBI_ASSERT(img_n+1 == out_n);
#define CASE(f) \ #define CASE(f) \
case f: \ case f: \
for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
@ -2581,7 +2595,7 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
// compute color-based transparency, assuming we've // compute color-based transparency, assuming we've
// already got 255 as the alpha value in the output // already got 255 as the alpha value in the output
assert(out_n == 2 || out_n == 4); STBI_ASSERT(out_n == 2 || out_n == 4);
if (out_n == 2) { if (out_n == 2) {
for (i=0; i < pixel_count; ++i) { for (i=0; i < pixel_count; ++i) {
@ -2662,7 +2676,7 @@ static void stbi__de_iphone(stbi__png *z)
p += 3; p += 3;
} }
} else { } else {
assert(s->img_out_n == 4); STBI_ASSERT(s->img_out_n == 4);
if (stbi__unpremultiply_on_load) { if (stbi__unpremultiply_on_load) {
// convert bgr to rgb and unpremultiply // convert bgr to rgb and unpremultiply
for (i=0; i < pixel_count; ++i) { for (i=0; i < pixel_count; ++i) {
@ -3036,7 +3050,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
return stbi__errpuc("bad BMP", "bad BMP"); return stbi__errpuc("bad BMP", "bad BMP");
} }
} else { } else {
assert(hsz == 108 || hsz == 124); STBI_ASSERT(hsz == 108 || hsz == 124);
mr = stbi__get32le(s); mr = stbi__get32le(s);
mg = stbi__get32le(s); mg = stbi__get32le(s);
mb = stbi__get32le(s); mb = stbi__get32le(s);
@ -4119,7 +4133,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
} }
case 0x3B: // gif stream termination code case 0x3B: // gif stream termination code
return (stbi_uc *) 1; return (stbi_uc *) s; // using '1' causes warning on some compilers
default: default:
return stbi__errpuc("unknown code", "Corrupt GIF"); return stbi__errpuc("unknown code", "Corrupt GIF");
@ -4134,7 +4148,7 @@ static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
u = stbi__gif_load_next(s, &g, comp, req_comp); u = stbi__gif_load_next(s, &g, comp, req_comp);
if (u == (void *) 1) u = 0; // end of animated gif marker if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
if (u) { if (u) {
*x = g.w; *x = g.w;
*y = g.h; *y = g.h;
@ -4502,7 +4516,7 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
{ {
FILE *f = fopen(filename, "rb"); FILE *f = stbi__fopen(filename, "rb");
int result; int result;
if (!f) return stbi__err("can't fopen", "Unable to open file"); if (!f) return stbi__err("can't fopen", "Unable to open file");
result = stbi_info_from_file(f, x, y, comp); result = stbi_info_from_file(f, x, y, comp);
@ -4545,6 +4559,10 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/* /*
revision history: revision history:
1.42 (2014-07-09)
don't define _CRT_SECURE_NO_WARNINGS (affects user code)
fixes to stbi__cleanup_jpeg path
added STBI_ASSERT to avoid requiring assert.h
1.41 (2014-06-25) 1.41 (2014-06-25)
fix search&replace from 1.36 that messed up comments/error messages fix search&replace from 1.36 that messed up comments/error messages
1.40 (2014-06-22) 1.40 (2014-06-22)