Browse Source

Updated stb_image to version 2.0.3.

Alex Szpakowski 10 years ago
parent
commit
2a482f8e98
1 changed files with 124 additions and 27 deletions
  1. 124 27
      src/libraries/stb/stb_image.h

+ 124 - 27
src/libraries/stb/stb_image.h

@@ -1,4 +1,4 @@
-/* stb_image - v2.02 - public domain image loader - http://nothings.org/stb_image.h
+/* stb_image - v2.03 - public domain image loader - http://nothings.org/stb_image.h
                                      no warranty implied; use at your own risk
                                      no warranty implied; use at your own risk
 
 
    Do this:
    Do this:
@@ -143,6 +143,9 @@
 
 
 
 
    Latest revision history:
    Latest revision history:
+      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.02  (2015-01-19) fix incorrect assert, fix warning
       2.01  (2015-01-17) fix various warnings
       2.01  (2015-01-17) fix various warnings
       2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
       2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
@@ -180,7 +183,7 @@
     James "moose2000" Brown (iPhone PNG)         Roy Eltham
     James "moose2000" Brown (iPhone PNG)         Roy Eltham
     Ben "Disch" Wenger (io callbacks)            Luke Graham
     Ben "Disch" Wenger (io callbacks)            Luke Graham
     Omar Cornut (1/2/4-bit PNG)                  Thomas Ruf
     Omar Cornut (1/2/4-bit PNG)                  Thomas Ruf
-                                                 John Bartholomew
+    Nicolas Guillemot (vertical flip)            John Bartholomew
                                                  Ken Hamada
                                                  Ken Hamada
  Optimizations & bugfixes                        Cort Stratton
  Optimizations & bugfixes                        Cort Stratton
     Fabian "ryg" Giesen                          Blazej Dariusz Roszkowski
     Fabian "ryg" Giesen                          Blazej Dariusz Roszkowski
@@ -196,6 +199,9 @@
                                                  Sergio Gonzalez
                                                  Sergio Gonzalez
                                                  Cass Everitt
                                                  Cass Everitt
                                                  Engin Manap
                                                  Engin Manap
+                                                 Martins Mozeiko
+                                                 Joseph Thomson
+                                                 Phil Jordan
 
 
 License:
 License:
    This software is in the public domain. Where that dedication is not
    This software is in the public domain. Where that dedication is not
@@ -487,6 +493,8 @@ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultipl
 // or just pass them through "as-is"
 // or just pass them through "as-is"
 STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
 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
 // ZLIB client - used by PNG, available for other purposes
 
 
@@ -624,7 +632,12 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #define STBI_FREE(p)       free(p)
 #define STBI_FREE(p)       free(p)
 #endif
 #endif
 
 
-#if defined(__GNUC__) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
+// x86/x64 detection
+#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
+#define STBI__X86_TARGET
+#endif
+
+#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
 // gcc doesn't support sse2 intrinsics unless you compile with -msse2,
 // gcc doesn't support sse2 intrinsics unless you compile with -msse2,
 // (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
 // (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
 // this is just broken and gcc are jerks for not fixing it properly
 // this is just broken and gcc are jerks for not fixing it properly
@@ -632,7 +645,20 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #define STBI_NO_SIMD
 #define STBI_NO_SIMD
 #endif
 #endif
 
 
-#if !defined(STBI_NO_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
+#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
+// 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
 #define STBI_SSE2
 #include <emmintrin.h>
 #include <emmintrin.h>
 
 
@@ -885,7 +911,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);
 static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp);
 #endif
 #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
    #ifndef STBI_NO_JPEG
    if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
    if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
@@ -925,6 +958,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");
    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
 #ifndef STBI_NO_STDIO
 
 
 static FILE *stbi__fopen(char const *filename, char const *mode)
 static FILE *stbi__fopen(char const *filename, char const *mode)
@@ -955,7 +1035,7 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
    unsigned char *result;
    unsigned char *result;
    stbi__context s;
    stbi__context s;
    stbi__start_file(&s,f);
    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) {
    if (result) {
       // need to 'unget' all the characters in the IO buffer
       // need to 'unget' all the characters in the IO buffer
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
@@ -968,25 +1048,29 @@ STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, i
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_mem(&s,buffer,len);
    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)
 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__context s;
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    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
 #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;
    unsigned char *data;
    #ifndef STBI_NO_HDR
    #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
    #endif
-   data = stbi_load_main(s, x, y, comp, req_comp);
+   data = stbi__load_flip(s, x, y, comp, req_comp);
    if (data)
    if (data)
       return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
       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");
    return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
@@ -996,14 +1080,14 @@ STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, in
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_mem(&s,buffer,len);
    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)
 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__context s;
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    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
 #ifndef STBI_NO_STDIO
@@ -1021,7 +1105,7 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
 {
 {
    stbi__context s;
    stbi__context s;
    stbi__start_file(&s,f);
    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
 #endif // !STBI_NO_STDIO
 
 
@@ -1063,7 +1147,6 @@ STBIDEF int      stbi_is_hdr_from_file(FILE *f)
    stbi__start_file(&s,f);
    stbi__start_file(&s,f);
    return stbi__hdr_test(&s);
    return stbi__hdr_test(&s);
    #else
    #else
-   STBI_NOTUSED(f);
    return 0;
    return 0;
    #endif
    #endif
 }
 }
@@ -1076,8 +1159,6 @@ STBIDEF int      stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    return stbi__hdr_test(&s);
    return stbi__hdr_test(&s);
    #else
    #else
-   STBI_NOTUSED(clbk);
-   STBI_NOTUSED(user);
    return 0;
    return 0;
    #endif
    #endif
 }
 }
@@ -1147,6 +1228,10 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
 
 
 static void stbi__skip(stbi__context *s, int n)
 static void stbi__skip(stbi__context *s, int n)
 {
 {
+   if (n < 0) {
+      s->img_buffer = s->img_buffer_end;
+      return;
+   }
    if (s->io.read) {
    if (s->io.read) {
       int blen = (int) (s->img_buffer_end - s->img_buffer);
       int blen = (int) (s->img_buffer_end - s->img_buffer);
       if (blen < n) {
       if (blen < n) {
@@ -1555,6 +1640,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
    sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
    k = stbi_lrot(j->code_buffer, n);
    k = stbi_lrot(j->code_buffer, n);
+   STBI_ASSERT(n >= 0 && n < sizeof(stbi__bmask)/sizeof(*stbi__bmask));
    j->code_buffer = k & ~stbi__bmask[n];
    j->code_buffer = k & ~stbi__bmask[n];
    k &= stbi__bmask[n];
    k &= stbi__bmask[n];
    j->code_bits -= n;
    j->code_bits -= n;
@@ -2703,6 +2789,10 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
 static int stbi__decode_jpeg_image(stbi__jpeg *j)
 static int stbi__decode_jpeg_image(stbi__jpeg *j)
 {
 {
    int m;
    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;
    j->restart_interval = 0;
    if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
    if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
    m = stbi__get_marker(j);
    m = stbi__get_marker(j);
@@ -3382,7 +3472,8 @@ 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)
-      STBI_ASSERT(sizes[i] <= (1 << i));
+      if (sizes[i] > (1 << i))
+         return stbi__err("bad sizes", "Corrupt PNG");
    code = 0;
    code = 0;
    for (i=1; i < 16; ++i) {
    for (i=1; i < 16; ++i) {
       next_code[i] = code;
       next_code[i] = code;
@@ -3390,7 +3481,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
       z->firstsymbol[i] = (stbi__uint16) k;
       z->firstsymbol[i] = (stbi__uint16) k;
       code = (code + sizes[i]);
       code = (code + sizes[i]);
       if (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
       z->maxcode[i] = code << (16-i); // preshift for inner loop
       code <<= 1;
       code <<= 1;
       k += sizes[i];
       k += sizes[i];
@@ -3559,9 +3650,9 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
          p = (stbi_uc *) (zout - dist);
          p = (stbi_uc *) (zout - dist);
          if (dist == 1) { // run of one byte; common in images.
          if (dist == 1) { // run of one byte; common in images.
             stbi_uc v = *p;
             stbi_uc v = *p;
-            do *zout++ = v; while (--len);
+            if (len) { do *zout++ = v; while (--len); }
          } else {
          } else {
-            do *zout++ = *p++; while (--len);
+            if (len) { do *zout++ = *p++; while (--len); }
          }
          }
       }
       }
    }
    }
@@ -3589,7 +3680,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);
-      STBI_ASSERT(c >= 0 && c < 19);
+      if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
       if (c < 16)
       if (c < 16)
          lencodes[n++] = (stbi_uc) c;
          lencodes[n++] = (stbi_uc) c;
       else if (c == 16) {
       else if (c == 16) {
@@ -4286,6 +4377,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 (first) return stbi__err("first not IHDR", "Corrupt PNG");
             if (pal_img_n && !pal_len) return stbi__err("no PLTE","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 (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) {
             if (ioff + c.length > idata_limit) {
                stbi_uc *p;
                stbi_uc *p;
                if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
                if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
@@ -4645,7 +4737,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
             }
             }
          } else {
          } else {
             for (i=0; i < (int) s->img_x; ++i) {
             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;
                int a;
                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
@@ -4802,7 +4894,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
    *y = tga_height;
    *y = tga_height;
    if (comp) *comp = tga_comp;
    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");
    if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
 
 
    // skip to the data's starting position (offset usually = 0)
    // skip to the data's starting position (offset usually = 0)
@@ -5463,6 +5555,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
    stbi__gif_lzw *p;
    stbi__gif_lzw *p;
 
 
    lzw_cs = stbi__get8(s);
    lzw_cs = stbi__get8(s);
+   if (lzw_cs > 12) return NULL;
    clear = 1 << lzw_cs;
    clear = 1 << lzw_cs;
    first = 1;
    first = 1;
    codesize = lzw_cs + 1;
    codesize = lzw_cs + 1;
@@ -6194,6 +6287,9 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
 
 
 /*
 /*
    revision history:
    revision history:
+      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.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.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.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
@@ -6280,7 +6376,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.21    fix use of 'stbi_uc' in header (reported by jon blow)
       1.20    added support for Softimage PIC, by Tom Seddon
       1.20    added support for Softimage PIC, by Tom Seddon
       1.19    bug in interlaced PNG corruption check (found by ryg)
       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)
               fix a threading bug (local mutable static)
       1.17    support interlaced PNG
       1.17    support interlaced PNG
       1.16    major bugfix - stbi__convert_format converted one too many pixels
       1.16    major bugfix - stbi__convert_format converted one too many pixels
@@ -6325,5 +6421,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.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,
       0.51    obey req_comp requests, 1-component jpegs return as 1-component,
               on 'test' only check type, not whether we support this variant
               on 'test' only check type, not whether we support this variant
-      0.50    first released version
+      0.50  (2006-11-19)
+              first released version
 */
 */