tweak release docs

tweak credits
tweak revision history
remove trailing whitespace
This commit is contained in:
Sean Barrett 2014-12-20 06:22:17 -08:00
parent b4e526d7cf
commit 9ad85cc8d2

View File

@ -51,7 +51,7 @@
intrinsics or that doesn't support the method used to detect intrinsics or that doesn't support the method used to detect
SSE2 support at run-time), and even those can be reported as SSE2 support at run-time), and even those can be reported as
bugs so I can refine the built-in compile-time checking to be bugs so I can refine the built-in compile-time checking to be
smarter. smarter.
- RGB values computed for JPEG images are slightly different from - RGB values computed for JPEG images are slightly different from
previous versions of stb_image. (This is due to using less previous versions of stb_image. (This is due to using less
@ -73,12 +73,18 @@
removed in future versions of the library. It is only intended for removed in future versions of the library. It is only intended for
back-compatibility use. back-compatibility use.
- Added support for PNM images.
- Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing
the memory allocator. Unlike other STBI libraries, these macros don't
support a context parameter, so if you need to pass a context in to
the allocator, you'll have to store it in a global or a thread-local
variable.
Latest revision history: Latest revision history:
1.49 (2014-12-25) optimize JPG, incl. x86 SIMD 1.49 (2014-12-25) optimize JPG, incl. x86 SIMD
PGM/PPM support PGM/PPM support
allocation macros
stbi_load_into() -- load into pre-defined memory
STBI_MALLOC,STBI_REALLOC,STBI_FREE STBI_MALLOC,STBI_REALLOC,STBI_FREE
1.48 (2014-12-14) fix incorrectly-named assert() 1.48 (2014-12-14) fix incorrectly-named assert()
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted) 1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
@ -86,16 +92,12 @@
fix bug in interlaced PNG with user-specified channel count fix bug in interlaced PNG with user-specified channel count
1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG 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 1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc
1.44 (2014-08-07) warnings
1.43 (2014-07-15) fix MSVC-only bug in 1.42
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
See end of file for full revision history. See end of file for full revision history.
============================ Contributors ========================= ============================ Contributors =========================
Image formats Bug fixes & warning fixes Image formats Bug fixes & warning fixes
Sean Barrett (jpeg, png, bmp) Marc LeBlanc Sean Barrett (jpeg, png, bmp) Marc LeBlanc
Nicolas Schulz (hdr, psd) Christpher Lloyd Nicolas Schulz (hdr, psd) Christpher Lloyd
@ -105,24 +107,32 @@
Thatcher Ulrich (psd) Janez Zemva Thatcher Ulrich (psd) Janez Zemva
Ken Miller (pgm, ppm) Jonathan Blow Ken Miller (pgm, ppm) Jonathan Blow
Laurent Gomila Laurent Gomila
Extensions, features Aruelien Pocheville Aruelien Pocheville
Jetro Lauha (stbi_info) Ryamond Barbiero Extensions, features Ryamond Barbiero
James "moose2000" Brown (iPhone PNG) David Woo Jetro Lauha (stbi_info) David Woo
Ben "Disch" Wenger (io callbacks) Roy Eltham Martin "SpartanJ" Golini (stbi_info) Martin Golini
Martin "SpartanJ" Golini Luke Graham James "moose2000" Brown (iPhone PNG) Roy Eltham
Omar Cornut (1/2/4-bit png) Thomas Ruf Ben "Disch" Wenger (io callbacks) Luke Graham
Omar Cornut (1/2/4-bit PNG) Thomas Ruf
John Bartholomew John Bartholomew
Optimizations & bugfixes Ken Hamada Ken Hamada
Fabian "ryg" Giesen Cort Stratton Optimizations & bugfixes Cort Stratton
Arseny Kapoulkine Blazej Dariusz Roszkowski Fabian "ryg" Giesen Blazej Dariusz Roszkowski
Thibault Reuille Arseny Kapoulkine Thibault Reuille
Paul Du Bois Paul Du Bois
Guillaume George Guillaume George
Jerry Jansson If your name should be here but Jerry Jansson
If your name should be here but Hayaki Saito isn't, let Sean know. Hayaki Saito
isn't, let Sean know. Johan Duparc Johan Duparc
Ronny Chevalier Ronny Chevalier
Michal Cichon Michal Cichon
Tero Hanninen
License:
This software is in the public domain. Where that dedication is not
recognized, you are granted a perpetual, irrevocable license to copy
and modify this file as you see fit.
*/ */
#ifndef STBI_INCLUDE_STB_IMAGE_H #ifndef STBI_INCLUDE_STB_IMAGE_H
@ -140,7 +150,7 @@
// Basic usage (see HDR discussion below for HDR usage): // Basic usage (see HDR discussion below for HDR usage):
// int x,y,n; // int x,y,n;
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); // unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
// // ... process data if not NULL ... // // ... process data if not NULL ...
// // ... x = width, y = height, n = # 8-bit components per pixel ... // // ... x = width, y = height, n = # 8-bit components per pixel ...
// // ... replace '0' with '1'..'4' to force that many components per pixel // // ... replace '0' with '1'..'4' to force that many components per pixel
// // ... but 'n' will always be the number that it would have been if you said 0 // // ... but 'n' will always be the number that it would have been if you said 0
@ -189,7 +199,7 @@
// I/O callbacks allow you to read from arbitrary sources, like packaged // I/O callbacks allow you to read from arbitrary sources, like packaged
// files or some other source. Data read from callbacks are processed // files or some other source. Data read from callbacks are processed
// through a small internal buffer (currently 128 bytes) to try to reduce // through a small internal buffer (currently 128 bytes) to try to reduce
// overhead. // overhead.
// //
// The three functions you must define are "read" (reads some bytes of data), // The three functions you must define are "read" (reads some bytes of data),
// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
@ -239,7 +249,7 @@
// (linear) floats to preserve the full dynamic range: // (linear) floats to preserve the full dynamic range:
// //
// float *data = stbi_loadf(filename, &x, &y, &n, 0); // float *data = stbi_loadf(filename, &x, &y, &n, 0);
// //
// If you load LDR images through this interface, those images will // If you load LDR images through this interface, those images will
// be promoted to floating point values, run through the inverse of // be promoted to floating point values, run through the inverse of
// constants corresponding to the above: // constants corresponding to the above:
@ -310,7 +320,7 @@ extern "C" {
typedef struct typedef struct
{ {
int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
int (*eof) (void *user); // returns nonzero if we are at end of file/data int (*eof) (void *user); // returns nonzero if we are at end of file/data
} stbi_io_callbacks; } stbi_io_callbacks;
@ -353,7 +363,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f);
// get a VERY brief reason for failure // get a VERY brief reason for failure
// NOT THREADSAFE // NOT THREADSAFE
STBIDEF const char *stbi_failure_reason (void); STBIDEF const char *stbi_failure_reason (void);
// free the loaded image -- this is just free() // free the loaded image -- this is just free()
STBIDEF void stbi_image_free (void *retval_from_stbi_load); STBIDEF void stbi_image_free (void *retval_from_stbi_load);
@ -543,7 +553,7 @@ typedef struct
{ {
stbi__uint32 img_x, img_y; stbi__uint32 img_x, img_y;
int img_n, img_out_n; int img_n, img_out_n;
stbi_io_callbacks io; stbi_io_callbacks io;
void *io_user_data; void *io_user_data;
@ -928,7 +938,7 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
if (s->read_from_callbacks == 0) return 1; if (s->read_from_callbacks == 0) return 1;
} }
return s->img_buffer >= s->img_buffer_end; return s->img_buffer >= s->img_buffer_end;
} }
static void stbi__skip(stbi__context *s, int n) static void stbi__skip(stbi__context *s, int n)
@ -952,7 +962,7 @@ static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
int res, count; int res, count;
memcpy(buffer, s->img_buffer, blen); memcpy(buffer, s->img_buffer, blen);
count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen);
res = (count == (n-blen)); res = (count == (n-blen));
s->img_buffer = s->img_buffer_end; s->img_buffer = s->img_buffer_end;
@ -2379,7 +2389,7 @@ typedef struct
resample_row_func resample; resample_row_func resample;
stbi_uc *line0,*line1; stbi_uc *line0,*line1;
int hs,vs; // expansion factor in each axis int hs,vs; // expansion factor in each axis
int w_lores; // horizontal pixels pre-expansion int w_lores; // horizontal pixels pre-expansion
int ystep; // how far through vertical expansion we are int ystep; // how far through vertical expansion we are
int ypos; // which pre-expansion row we're on int ypos; // which pre-expansion row we're on
} stbi__resample; } stbi__resample;
@ -2539,7 +2549,7 @@ typedef struct
int maxcode[17]; int maxcode[17];
stbi__uint16 firstsymbol[16]; stbi__uint16 firstsymbol[16];
stbi_uc size[288]; stbi_uc size[288];
stbi__uint16 value[288]; stbi__uint16 value[288];
} stbi__zhuffman; } stbi__zhuffman;
stbi_inline static int stbi__bitreverse16(int n) stbi_inline static int stbi__bitreverse16(int n)
@ -2567,7 +2577,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
// DEFLATE spec for generating codes // DEFLATE spec for generating codes
memset(sizes, 0, sizeof(sizes)); memset(sizes, 0, sizeof(sizes));
memset(z->fast, 0, sizeof(z->fast)); memset(z->fast, 0, sizeof(z->fast));
for (i=0; i < num; ++i) for (i=0; i < num; ++i)
++sizes[sizelist[i]]; ++sizes[sizelist[i]];
sizes[0] = 0; sizes[0] = 0;
for (i=1; i < 16; ++i) for (i=1; i < 16; ++i)
@ -2647,7 +2657,7 @@ stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n)
k = z->code_buffer & ((1 << n) - 1); k = z->code_buffer & ((1 << n) - 1);
z->code_buffer >>= n; z->code_buffer >>= n;
z->num_bits -= n; z->num_bits -= n;
return k; return k;
} }
static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
@ -2705,7 +2715,7 @@ static int stbi__zlength_base[31] = {
15,17,19,23,27,31,35,43,51,59, 15,17,19,23,27,31,35,43,51,59,
67,83,99,115,131,163,195,227,258,0,0 }; 67,83,99,115,131,163,195,227,258,0,0 };
static int stbi__zlength_extra[31]= static int stbi__zlength_extra[31]=
{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
@ -3370,7 +3380,7 @@ static void stbi__de_iphone(stbi__png *z)
} else { } else {
p[0] = p[2]; p[0] = p[2];
p[2] = t; p[2] = t;
} }
p += 4; p += 4;
} }
} else { } else {
@ -3837,7 +3847,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
if (target == 4) out[z++] = STBI__BYTECAST(a); if (target == 4) out[z++] = STBI__BYTECAST(a);
} }
} }
stbi__skip(s, pad); stbi__skip(s, pad);
@ -4161,7 +4171,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
// Read the rows and columns of the image. // Read the rows and columns of the image.
h = stbi__get32be(s); h = stbi__get32be(s);
w = stbi__get32be(s); w = stbi__get32be(s);
// Make sure the depth is 8 bits. // Make sure the depth is 8 bits.
if (stbi__get16be(s) != 8) if (stbi__get16be(s) != 8)
return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit"); return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit");
@ -4203,7 +4213,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
// Initialize the data to zero. // Initialize the data to zero.
//memset( out, 0, pixelCount * 4 ); //memset( out, 0, pixelCount * 4 );
// Finally, the image data. // Finally, the image data.
if (compression) { if (compression) {
// RLE as used by .PSD and .TIFF // RLE as used by .PSD and .TIFF
@ -4221,7 +4231,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
// Read the RLE data by channel. // Read the RLE data by channel.
for (channel = 0; channel < 4; channel++) { for (channel = 0; channel < 4; channel++) {
stbi_uc *p; stbi_uc *p;
p = out+channel; p = out+channel;
if (channel >= channelCount) { if (channel >= channelCount) {
// Fill this channel with default data. // Fill this channel with default data.
@ -4259,15 +4269,15 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
} }
} }
} }
} else { } else {
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
// where each channel consists of an 8-bit value for each pixel in the image. // where each channel consists of an 8-bit value for each pixel in the image.
// Read the data by channel. // Read the data by channel.
for (channel = 0; channel < 4; channel++) { for (channel = 0; channel < 4; channel++) {
stbi_uc *p; stbi_uc *p;
p = out + channel; p = out + channel;
if (channel > channelCount) { if (channel > channelCount) {
// Fill this channel with default data. // Fill this channel with default data.
@ -4288,7 +4298,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
if (comp) *comp = channelCount; if (comp) *comp = channelCount;
*y = h; *y = h;
*x = w; *x = w;
return out; return out;
} }
@ -4506,7 +4516,7 @@ static int stbi__pic_test(stbi__context *s)
// ************************************************************************************************* // *************************************************************************************************
// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
typedef struct typedef struct
{ {
stbi__int16 prefix; stbi__int16 prefix;
stbi_uc first; stbi_uc first;
@ -4555,7 +4565,7 @@ static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], in
pal[i][1] = stbi__get8(s); pal[i][1] = stbi__get8(s);
pal[i][0] = stbi__get8(s); pal[i][0] = stbi__get8(s);
pal[i][3] = transp ? 0 : 255; pal[i][3] = transp ? 0 : 255;
} }
} }
static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info)
@ -4567,7 +4577,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
version = stbi__get8(s); version = stbi__get8(s);
if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF");
if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF");
stbi__g_failure_reason = ""; stbi__g_failure_reason = "";
g->w = stbi__get16le(s); g->w = stbi__get16le(s);
g->h = stbi__get16le(s); g->h = stbi__get16le(s);
@ -4588,7 +4598,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
{ {
stbi__gif g; stbi__gif g;
if (!stbi__gif_header(s, &g, comp, 1)) { if (!stbi__gif_header(s, &g, comp, 1)) {
stbi__rewind( s ); stbi__rewind( s );
return 0; return 0;
@ -4608,7 +4618,7 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
stbi__out_gif_code(g, g->codes[code].prefix); stbi__out_gif_code(g, g->codes[code].prefix);
if (g->cur_y >= g->max_y) return; if (g->cur_y >= g->max_y) return;
p = &g->out[g->cur_x + g->cur_y]; p = &g->out[g->cur_x + g->cur_y];
c = &g->color_table[g->codes[code].suffix * 4]; c = &g->color_table[g->codes[code].suffix * 4];
@ -4662,7 +4672,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
if (valid_bits < codesize) { if (valid_bits < codesize) {
if (len == 0) { if (len == 0) {
len = stbi__get8(s); // start new block len = stbi__get8(s); // start new block
if (len == 0) if (len == 0)
return g->out; return g->out;
} }
--len; --len;
@ -4707,7 +4717,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
} else { } else {
return stbi__errpuc("illegal code in raster", "Corrupt GIF"); return stbi__errpuc("illegal code in raster", "Corrupt GIF");
} }
} }
} }
} }
@ -4745,7 +4755,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
memcpy(g->out, old_out, g->w*g->h*4); memcpy(g->out, old_out, g->w*g->h*4);
} }
} }
for (;;) { for (;;) {
switch (stbi__get8(s)) { switch (stbi__get8(s)) {
case 0x2C: /* Image Descriptor */ case 0x2C: /* Image Descriptor */
@ -4780,16 +4790,16 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
if (g->lflags & 0x80) { if (g->lflags & 0x80) {
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
g->color_table = (stbi_uc *) g->lpal; g->color_table = (stbi_uc *) g->lpal;
} else if (g->flags & 0x80) { } else if (g->flags & 0x80) {
for (i=0; i < 256; ++i) // @OPTIMIZE: stbi__jpeg_reset only the previous transparent for (i=0; i < 256; ++i) // @OPTIMIZE: stbi__jpeg_reset only the previous transparent
g->pal[i][3] = 255; g->pal[i][3] = 255;
if (g->transparent >= 0 && (g->eflags & 0x01)) if (g->transparent >= 0 && (g->eflags & 0x01))
g->pal[g->transparent][3] = 0; g->pal[g->transparent][3] = 0;
g->color_table = (stbi_uc *) g->pal; g->color_table = (stbi_uc *) g->pal;
} else } else
return stbi__errpuc("missing color table", "Corrupt GIF"); return stbi__errpuc("missing color table", "Corrupt GIF");
o = stbi__process_gif_raster(s, g); o = stbi__process_gif_raster(s, g);
if (o == NULL) return NULL; if (o == NULL) return NULL;
@ -4935,7 +4945,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
// Check identifier // Check identifier
if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0)
return stbi__errpf("not HDR", "Corrupt HDR image"); return stbi__errpf("not HDR", "Corrupt HDR image");
// Parse header // Parse header
for(;;) { for(;;) {
token = stbi__hdr_gettoken(s,buffer); token = stbi__hdr_gettoken(s,buffer);
@ -5003,7 +5013,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
len |= stbi__get8(s); len |= stbi__get8(s);
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4);
for (k = 0; k < 4; ++k) { for (k = 0; k < 4; ++k) {
i = 0; i = 0;
while (i < width) { while (i < width) {
@ -5263,7 +5273,7 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
*comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm
c = (char) stbi__get8(s); c = (char) stbi__get8(s);
stbi__pnm_skip_whitespace(s, &c); stbi__pnm_skip_whitespace(s, &c);
*x = stbi__pnm_getinteger(s, &c); // read width *x = stbi__pnm_getinteger(s, &c); // read width
@ -5347,6 +5357,10 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/* /*
revision history: revision history:
1.49 (2014-12-25) optimize JPG, incl. x86 SIMD (ryg)
PGM/PPM support (Ken Miller)
STBI_MALLOC,STBI_REALLOC,STBI_FREE
stbi_load_into() -- load into pre-defined memory
1.48 (2014-12-14) fix incorrectly-named assert() 1.48 (2014-12-14) fix incorrectly-named assert()
1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
optimize PNG (ryg) optimize PNG (ryg)
@ -5400,7 +5414,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha)
fix inefficiency in decoding 32-bit BMP (David Woo) fix inefficiency in decoding 32-bit BMP (David Woo)
1.29 (2010-08-16) 1.29 (2010-08-16)
various warning fixes from Aurelien Pocheville various warning fixes from Aurelien Pocheville
1.28 (2010-08-01) 1.28 (2010-08-01)
fix bug in GIF palette transparency (SpartanJ) fix bug in GIF palette transparency (SpartanJ)
1.27 (2010-08-01) 1.27 (2010-08-01)