浏览代码

Merge branch 'working'

Sean Barrett 11 年之前
父节点
当前提交
b2cbed2634
共有 1 个文件被更改,包括 50 次插入32 次删除
  1. 50 32
      stb_image.h

+ 50 - 32
stb_image.h

@@ -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)