Browse Source

Merge branch 'working'

Sean Barrett 11 years ago
parent
commit
b2cbed2634
1 changed files with 50 additions and 32 deletions
  1. 50 32
      stb_image.h

+ 50 - 32
stb_image.h

@@ -6,6 +6,8 @@
       #define STB_IMAGE_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:
       Primarily of interest to game developers and other people who can
           avoid problematic images and only need the trivial interface
@@ -26,6 +28,7 @@
       - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
 
    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.40 (2014-06-22) gcc warning
       1.39 (2014-06-15) TGA optimization fix, multiple BMP fixes
@@ -33,8 +36,6 @@
       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.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.
 
@@ -189,12 +190,6 @@
 
 
 #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>
 #endif // STBI_NO_STDIO
 
@@ -354,8 +349,11 @@ STBIDEF void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
 #include <stdio.h>
 #endif
 #include <stdlib.h>
-#include <memory.h>
+#include <string.h>
+#ifndef STBI_ASSERT
 #include <assert.h>
+#define STBI_ASSERT(x) assert(x)
+#endif
 #include <stdarg.h>
 #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
+
+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)
 {
-   FILE *f = fopen(filename, "rb");
+   FILE *f = stbi__fopen(filename, "rb");
    unsigned char *result;
    if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
    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
 float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
 {
-   FILE *f = fopen(filename, "rb");
    float *result;
+   FILE *f = stbi__fopen(filename, "rb");
    if (!f) return stbi__errpf("can't fopen", "Unable to open file");
    result = stbi_loadf_from_file(f,x,y,comp,req_comp);
    fclose(f);
@@ -682,7 +694,7 @@ int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
 #ifndef STBI_NO_STDIO
 STBIDEF int      stbi_is_hdr          (char const *filename)
 {
-   FILE *f = fopen(filename, "rb");
+   FILE *f = stbi__fopen(filename, "rb");
    int result=0;
    if (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;
 
    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);
    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,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;
-         default: assert(0);
+         default: STBI_ASSERT(0);
       }
       #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
    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
    j->code_bits -= k;
@@ -1807,8 +1819,9 @@ static void stbi__cleanup_jpeg(stbi__jpeg *j)
 {
    int 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);
+         j->img_comp[i].raw_data = NULL;
          j->img_comp[i].data = NULL;
       }
       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)
 {
    int n, decode_n;
+   z->s->img_n = 0; // make stbi__cleanup_jpeg safe
+
    // validate req_comp
    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
    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)
 {
-   assert(bits <= 16);
+   STBI_ASSERT(bits <= 16);
    // to bit reverse n bits, reverse 16 and shift
    // stbi__err.g. 11 bits, bit reverse and shift away 5
    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[0] = 0;
    for (i=1; i < 16; ++i)
-      assert(sizes[i] <= (1 << i));
+      STBI_ASSERT(sizes[i] <= (1 << i));
    code = 0;
    for (i=1; i < 16; ++i) {
       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)
 {
    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->num_bits += 8;
    } 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!
    // code size is s, so:
    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->num_bits -= s;
    return z->value[b];
@@ -2202,7 +2216,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
    n = 0;
    while (n < hlit + hdist) {
       int c = stbi__zhuffman_decode(a, &z_codelength);
-      assert(c >= 0 && c < 19);
+      STBI_ASSERT(c >= 0 && c < 19);
       if (c < 16)
          lencodes[n++] = (stbi_uc) c;
       else if (c == 16) {
@@ -2214,7 +2228,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
          memset(lencodes+n, 0, c);
          n += c;
       } else {
-         assert(c == 18);
+         STBI_ASSERT(c == 18);
          c = stbi__zreceive(a,7)+11;
          memset(lencodes+n, 0, c);
          n += c;
@@ -2239,7 +2253,7 @@ static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
       a->code_buffer >>= 8;
       a->num_bits -= 8;
    }
-   assert(a->num_bits == 0);
+   STBI_ASSERT(a->num_bits == 0);
    // now fill header the normal way
    while (k < 4)
       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;
    int k;
    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);
    if (!a->out) return stbi__err("outofmem", "Out of memory");
    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
       } else {
-         assert(img_n+1 == out_n);
+         STBI_ASSERT(img_n+1 == out_n);
          #define CASE(f) \
              case f:     \
                 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
    // 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) {
       for (i=0; i < pixel_count; ++i) {
@@ -2662,7 +2676,7 @@ static void stbi__de_iphone(stbi__png *z)
          p += 3;
       }
    } else {
-      assert(s->img_out_n == 4);
+      STBI_ASSERT(s->img_out_n == 4);
       if (stbi__unpremultiply_on_load) {
          // convert bgr to rgb and unpremultiply
          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");
          }
       } else {
-         assert(hsz == 108 || hsz == 124);
+         STBI_ASSERT(hsz == 108 || hsz == 124);
          mr = stbi__get32le(s);
          mg = 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
-            return (stbi_uc *) 1;
+            return (stbi_uc *) s; // using '1' causes warning on some compilers
 
          default:
             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));
 
    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) {
       *x = g.w;
       *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
 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;
     if (!f) return stbi__err("can't fopen", "Unable to open file");
     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:
+      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)
              fix search&replace from 1.36 that messed up comments/error messages
       1.40 (2014-06-22)