Updated stb_image to 2.07.

This commit is contained in:
Alex Szpakowski
2015-09-13 11:26:11 -03:00
parent d30e60f8d7
commit 05ed70ed18
2 changed files with 171 additions and 101 deletions
+169 -99
View File
@@ -1,4 +1,4 @@
/* stb_image - v2.05 - public domain image loader - http://nothings.org/stb_image.h /* stb_image - v2.07 - 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:
@@ -25,13 +25,16 @@
TGA (not sure what subset, if a subset) TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE BMP non-1bpp, non-RLE
PSD (composited view only, no extra channels) PSD (composited view only, no extra channels, 8/16 bit-per-channel)
GIF (*comp always reports as 4-channel) GIF (*comp always reports as 4-channel)
HDR (radiance rgbE format) HDR (radiance rgbE format)
PIC (Softimage PIC) PIC (Softimage PIC)
PNM (PPM and PGM binary only) PNM (PPM and PGM binary only)
Animated GIF still needs a proper API, but here's one way to do it:
http://gist.github.com/urraka/685d9a6340b26b830d49
- decode from memory or through FILE (define STBI_NO_STDIO to remove code) - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
- decode from arbitrary I/O callbacks - decode from arbitrary I/O callbacks
- SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
@@ -143,6 +146,10 @@
Latest revision history: Latest revision history:
2.07 (2015-09-13) partial animated GIF support
limited 16-bit PSD support
minor bugs, code cleanup, and compiler warnings
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
2.03 (2015-04-12) additional corruption checking 2.03 (2015-04-12) additional corruption checking
@@ -175,38 +182,41 @@
Tom Seddon (pic) the Horde3D community Tom Seddon (pic) the Horde3D community
Thatcher Ulrich (psd) Janez Zemva Thatcher Ulrich (psd) Janez Zemva
Ken Miller (pgm, ppm) Jonathan Blow Ken Miller (pgm, ppm) Jonathan Blow
Laurent Gomila urraka@github (animated gif) Laurent Gomila
Aruelien Pocheville Aruelien Pocheville
Extensions, features Ryamond Barbiero Ryamond Barbiero
Jetro Lauha (stbi_info) David Woo David Woo
Martin "SpartanJ" Golini (stbi_info) Martin Golini Extensions, features Martin Golini
James "moose2000" Brown (iPhone PNG) Roy Eltham Jetro Lauha (stbi_info) Roy Eltham
Ben "Disch" Wenger (io callbacks) Luke Graham Martin "SpartanJ" Golini (stbi_info) Luke Graham
Omar Cornut (1/2/4-bit PNG) Thomas Ruf James "moose2000" Brown (iPhone PNG) Thomas Ruf
Nicolas Guillemot (vertical flip) John Bartholomew Ben "Disch" Wenger (io callbacks) John Bartholomew
Ken Hamada Omar Cornut (1/2/4-bit PNG) Ken Hamada
Optimizations & bugfixes Cort Stratton Nicolas Guillemot (vertical flip) Cort Stratton
Fabian "ryg" Giesen Blazej Dariusz Roszkowski Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski
Arseny Kapoulkine Thibault Reuille Thibault Reuille
Paul Du Bois Paul Du Bois
Guillaume George Guillaume George
If your name should be here but Jerry Jansson Jerry Jansson
isn't, let Sean know. Hayaki Saito Hayaki Saito
Johan Duparc Johan Duparc
Ronny Chevalier Ronny Chevalier
Michal Cichon Optimizations & bugfixes Michal Cichon
Tero Hanninen Fabian "ryg" Giesen Tero Hanninen
Sergio Gonzalez Arseny Kapoulkine Sergio Gonzalez
Cass Everitt Cass Everitt
Engin Manap Engin Manap
Martins Mozeiko If your name should be here but Martins Mozeiko
Joseph Thomson isn't, let Sean know. Joseph Thomson
Phil Jordan Phil Jordan
Nathan Reed
Michaelangel007@github
License: LICENSE
This software is in the public domain. Where that dedication is not
recognized, you are granted a perpetual, irrevocable license to copy This software is in the public domain. Where that dedication is not
and modify this file however you want. recognized, you are granted a perpetual, irrevocable license to copy,
distribute, and modify this file as you see fit.
*/ */
@@ -748,7 +758,7 @@ typedef struct
stbi_uc buffer_start[128]; stbi_uc buffer_start[128];
stbi_uc *img_buffer, *img_buffer_end; stbi_uc *img_buffer, *img_buffer_end;
stbi_uc *img_buffer_original; stbi_uc *img_buffer_original, *img_buffer_original_end;
} stbi__context; } stbi__context;
@@ -760,7 +770,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
s->io.read = NULL; s->io.read = NULL;
s->read_from_callbacks = 0; s->read_from_callbacks = 0;
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
s->img_buffer_end = (stbi_uc *) buffer+len; s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
} }
// initialize a callback-based context // initialize a callback-based context
@@ -772,6 +782,7 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
s->read_from_callbacks = 1; s->read_from_callbacks = 1;
s->img_buffer_original = s->buffer_start; s->img_buffer_original = s->buffer_start;
stbi__refill_buffer(s); stbi__refill_buffer(s);
s->img_buffer_original_end = s->img_buffer_end;
} }
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
@@ -813,6 +824,7 @@ static void stbi__rewind(stbi__context *s)
// but we just rewind to the beginning of the initial buffer, because // but we just rewind to the beginning of the initial buffer, because
// we only use it after doing 'test', which only ever looks at at most 92 bytes // we only use it after doing 'test', which only ever looks at at most 92 bytes
s->img_buffer = s->img_buffer_original; s->img_buffer = s->img_buffer_original;
s->img_buffer_end = s->img_buffer_original_end;
} }
#ifndef STBI_NO_JPEG #ifndef STBI_NO_JPEG
@@ -900,8 +912,8 @@ static void *stbi__malloc(size_t size)
#define stbi__err(x,y) stbi__err(x) #define stbi__err(x,y) stbi__err(x)
#endif #endif
#define stbi__errpf(x,y) ((float *) (stbi__err(x,y)?NULL:NULL)) #define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
#define stbi__errpuc(x,y) ((unsigned char *) (stbi__err(x,y)?NULL:NULL)) #define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
STBIDEF void stbi_image_free(void *retval_from_stbi_load) STBIDEF void stbi_image_free(void *retval_from_stbi_load)
{ {
@@ -988,6 +1000,7 @@ static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *com
return result; return result;
} }
#ifndef STBI_NO_HDR
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
{ {
if (stbi__vertically_flip_on_load && result != NULL) { if (stbi__vertically_flip_on_load && result != NULL) {
@@ -1008,7 +1021,7 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
} }
} }
} }
#endif
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
@@ -1152,6 +1165,7 @@ 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
} }
@@ -1164,6 +1178,8 @@ 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
} }
@@ -1278,23 +1294,29 @@ static int stbi__get16be(stbi__context *s)
return (z << 8) + stbi__get8(s); return (z << 8) + stbi__get8(s);
} }
#if !defined(STBI_NO_PNG) || !defined(STBI_NO_PSD)
static stbi__uint32 stbi__get32be(stbi__context *s) static stbi__uint32 stbi__get32be(stbi__context *s)
{ {
stbi__uint32 z = stbi__get16be(s); stbi__uint32 z = stbi__get16be(s);
return (z << 16) + stbi__get16be(s); return (z << 16) + stbi__get16be(s);
} }
#endif
#if !defined(STBI_NO_BMP) || !defined(STBI_NO_TGA) || !defined(STBI_NO_GIF)
static int stbi__get16le(stbi__context *s) static int stbi__get16le(stbi__context *s)
{ {
int z = stbi__get8(s); int z = stbi__get8(s);
return z + (stbi__get8(s) << 8); return z + (stbi__get8(s) << 8);
} }
#endif
#ifndef STBI_NO_BMP
static stbi__uint32 stbi__get32le(stbi__context *s) static stbi__uint32 stbi__get32le(stbi__context *s)
{ {
stbi__uint32 z = stbi__get16le(s); stbi__uint32 z = stbi__get16le(s);
return z + (stbi__get16le(s) << 16); return z + (stbi__get16le(s) << 16);
} }
#endif
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
@@ -2738,7 +2760,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (z->img_comp[i].raw_data == NULL) { if (z->img_comp[i].raw_data == NULL) {
for(--i; i >= 0; --i) { for(--i; i >= 0; --i) {
STBI_FREE(z->img_comp[i].raw_data); STBI_FREE(z->img_comp[i].raw_data);
z->img_comp[i].data = NULL; z->img_comp[i].raw_data = NULL;
} }
return stbi__err("outofmem", "Out of memory"); return stbi__err("outofmem", "Out of memory");
} }
@@ -3500,10 +3522,10 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
z->size [c] = (stbi_uc ) s; z->size [c] = (stbi_uc ) s;
z->value[c] = (stbi__uint16) i; z->value[c] = (stbi__uint16) i;
if (s <= STBI__ZFAST_BITS) { if (s <= STBI__ZFAST_BITS) {
int k = stbi__bit_reverse(next_code[s],s); int j = stbi__bit_reverse(next_code[s],s);
while (k < (1 << STBI__ZFAST_BITS)) { while (j < (1 << STBI__ZFAST_BITS)) {
z->fast[k] = fastv; z->fast[j] = fastv;
k += (1 << s); j += (1 << s);
} }
} }
++next_code[s]; ++next_code[s];
@@ -3542,7 +3564,7 @@ static void stbi__fill_bits(stbi__zbuf *z)
{ {
do { do {
STBI_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 |= (unsigned int) stbi__zget8(z) << z->num_bits;
z->num_bits += 8; z->num_bits += 8;
} while (z->num_bits <= 24); } while (z->num_bits <= 24);
} }
@@ -4108,21 +4130,21 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
} }
if (img_n != out_n) { if (img_n != out_n) {
int q;
// insert alpha = 255 // insert alpha = 255
stbi_uc *cur = a->out + stride*j; cur = a->out + stride*j;
int i;
if (img_n == 1) { if (img_n == 1) {
for (i=x-1; i >= 0; --i) { for (q=x-1; q >= 0; --q) {
cur[i*2+1] = 255; cur[q*2+1] = 255;
cur[i*2+0] = cur[i]; cur[q*2+0] = cur[q];
} }
} else { } else {
STBI_ASSERT(img_n == 3); STBI_ASSERT(img_n == 3);
for (i=x-1; i >= 0; --i) { for (q=x-1; q >= 0; --q) {
cur[i*4+3] = 255; cur[q*4+3] = 255;
cur[i*4+2] = cur[i*3+2]; cur[q*4+2] = cur[q*3+2];
cur[i*4+1] = cur[i*3+1]; cur[q*4+1] = cur[q*3+1];
cur[i*4+0] = cur[i*3+0]; cur[q*4+0] = cur[q*3+0];
} }
} }
} }
@@ -4577,7 +4599,7 @@ static int stbi__shiftsigned(int v, int shift, int bits)
static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{ {
stbi_uc *out; stbi_uc *out;
unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; unsigned int mr=0,mg=0,mb=0,ma=0, all_a=255;
stbi_uc pal[256][4]; stbi_uc pal[256][4];
int psize=0,i,j,compress=0,width; int psize=0,i,j,compress=0,width;
int bpp, flip_vertically, pad, target, offset, hsz; int bpp, flip_vertically, pad, target, offset, hsz;
@@ -4626,8 +4648,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
mg = 0xffu << 8; mg = 0xffu << 8;
mb = 0xffu << 0; mb = 0xffu << 0;
ma = 0xffu << 24; ma = 0xffu << 24;
fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
STBI_NOTUSED(fake_a);
} else { } else {
mr = 31u << 10; mr = 31u << 10;
mg = 31u << 5; mg = 31u << 5;
@@ -4738,6 +4759,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
out[z+0] = stbi__get8(s); out[z+0] = stbi__get8(s);
z += 3; z += 3;
a = (easy == 2 ? stbi__get8(s) : 255); a = (easy == 2 ? stbi__get8(s) : 255);
all_a |= a;
if (target == 4) out[z++] = a; if (target == 4) out[z++] = a;
} }
} else { } else {
@@ -4748,12 +4770,19 @@ 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);
all_a |= a;
if (target == 4) out[z++] = STBI__BYTECAST(a); if (target == 4) out[z++] = STBI__BYTECAST(a);
} }
} }
stbi__skip(s, pad); stbi__skip(s, pad);
} }
} }
// if alpha channel is all 0s, replace with all 255s
if (target == 4 && all_a == 0)
for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
out[i] = 255;
if (flip_vertically) { if (flip_vertically) {
stbi_uc t; stbi_uc t;
for (j=0; j < (int) s->img_y>>1; ++j) { for (j=0; j < (int) s->img_y>>1; ++j) {
@@ -4907,8 +4936,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
if ( !tga_indexed && !tga_is_RLE) { if ( !tga_indexed && !tga_is_RLE) {
for (i=0; i < tga_height; ++i) { for (i=0; i < tga_height; ++i) {
int y = tga_inverted ? tga_height -i - 1 : i; int row = tga_inverted ? tga_height -i - 1 : i;
stbi_uc *tga_row = tga_data + y*tga_width*tga_comp; stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
stbi__getn(s, tga_row, tga_width * tga_comp); stbi__getn(s, tga_row, tga_width * tga_comp);
} }
} else { } else {
@@ -5053,6 +5082,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
int pixelCount; int pixelCount;
int channelCount, compression; int channelCount, compression;
int channel, i, count, len; int channel, i, count, len;
int bitdepth;
int w,h; int w,h;
stbi_uc *out; stbi_uc *out;
@@ -5077,8 +5107,9 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
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) bitdepth = stbi__get16be(s);
return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit"); if (bitdepth != 8 && bitdepth != 16)
return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
// Make sure the color mode is RGB. // Make sure the color mode is RGB.
// Valid options are: // Valid options are:
@@ -5139,7 +5170,8 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
p = out+channel; p = out+channel;
if (channel >= channelCount) { if (channel >= channelCount) {
// Fill this channel with default data. // Fill this channel with default data.
for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; for (i = 0; i < pixelCount; i++, p += 4)
*p = (channel == 3 ? 255 : 0);
} else { } else {
// Read the RLE data. // Read the RLE data.
count = 0; count = 0;
@@ -5185,11 +5217,17 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
p = out + channel; p = out + channel;
if (channel > channelCount) { if (channel > channelCount) {
// Fill this channel with default data. // Fill this channel with default data.
for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; for (i = 0; i < pixelCount; i++, p += 4)
*p = channel == 3 ? 255 : 0;
} else { } else {
// Read the data. // Read the data.
for (i = 0; i < pixelCount; i++) if (bitdepth == 16) {
*p = stbi__get8(s), p += 4; for (i = 0; i < pixelCount; i++, p += 4)
*p = stbi__get16be(s) >> 8;
} else {
for (i = 0; i < pixelCount; i++, p += 4)
*p = stbi__get8(s);
}
} }
} }
} }
@@ -5199,7 +5237,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
if (out == NULL) return out; // stbi__convert_format frees input on failure if (out == NULL) return out; // stbi__convert_format frees input on failure
} }
if (comp) *comp = channelCount; if (comp) *comp = 4;
*y = h; *y = h;
*x = w; *x = w;
@@ -5347,7 +5385,6 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
if (count >= 128) { // Repeated if (count >= 128) { // Repeated
stbi_uc value[4]; stbi_uc value[4];
int i;
if (count==128) if (count==128)
count = stbi__get16be(s); count = stbi__get16be(s);
@@ -5435,8 +5472,8 @@ typedef struct
typedef struct typedef struct
{ {
int w,h; int w,h;
stbi_uc *out; // output buffer (always 4 components) stbi_uc *out, *old_out; // output buffer (always 4 components)
int flags, bgindex, ratio, transparent, eflags; int flags, bgindex, ratio, transparent, eflags, delay;
stbi_uc pal[256][4]; stbi_uc pal[256][4];
stbi_uc lpal[256][4]; stbi_uc lpal[256][4];
stbi__gif_lzw codes[4096]; stbi__gif_lzw codes[4096];
@@ -5554,7 +5591,7 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
{ {
stbi_uc lzw_cs; stbi_uc lzw_cs;
stbi__int32 len, code; stbi__int32 len, init_code;
stbi__uint32 first; stbi__uint32 first;
stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
stbi__gif_lzw *p; stbi__gif_lzw *p;
@@ -5567,10 +5604,10 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
codemask = (1 << codesize) - 1; codemask = (1 << codesize) - 1;
bits = 0; bits = 0;
valid_bits = 0; valid_bits = 0;
for (code = 0; code < clear; code++) { for (init_code = 0; init_code < clear; init_code++) {
g->codes[code].prefix = -1; g->codes[init_code].prefix = -1;
g->codes[code].first = (stbi_uc) code; g->codes[init_code].first = (stbi_uc) init_code;
g->codes[code].suffix = (stbi_uc) code; g->codes[init_code].suffix = (stbi_uc) init_code;
} }
// support no starting clear code // support no starting clear code
@@ -5631,17 +5668,18 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
} }
} }
static void stbi__fill_gif_background(stbi__gif *g) static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1)
{ {
int i; int x, y;
stbi_uc *c = g->pal[g->bgindex]; stbi_uc *c = g->pal[g->bgindex];
// @OPTIMIZE: write a dword at a time for (y = y0; y < y1; y += 4 * g->w) {
for (i = 0; i < g->w * g->h * 4; i += 4) { for (x = x0; x < x1; x += 4) {
stbi_uc *p = &g->out[i]; stbi_uc *p = &g->out[y + x];
p[0] = c[2]; p[0] = c[2];
p[1] = c[1]; p[1] = c[1];
p[2] = c[0]; p[2] = c[0];
p[3] = c[3]; p[3] = 0;
}
} }
} }
@@ -5649,27 +5687,40 @@ static void stbi__fill_gif_background(stbi__gif *g)
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp)
{ {
int i; int i;
stbi_uc *old_out = 0; stbi_uc *prev_out = 0;
if (g->out == 0) { if (g->out == 0 && !stbi__gif_header(s, g, comp,0))
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header return 0; // stbi__g_failure_reason set by stbi__gif_header
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); prev_out = g->out;
stbi__fill_gif_background(g); g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
} else { if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
// animated-gif-only path
if (((g->eflags & 0x1C) >> 2) == 3) { switch ((g->eflags & 0x1C) >> 2) {
old_out = g->out; case 0: // unspecified (also always used on 1st frame)
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h);
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); break;
memcpy(g->out, old_out, g->w*g->h*4); case 1: // do not dispose
} if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
g->old_out = prev_out;
break;
case 2: // dispose to background
if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y);
break;
case 3: // dispose to previous
if (g->old_out) {
for (i = g->start_y; i < g->max_y; i += 4 * g->w)
memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x);
}
break;
} }
for (;;) { for (;;) {
switch (stbi__get8(s)) { switch (stbi__get8(s)) {
case 0x2C: /* Image Descriptor */ case 0x2C: /* Image Descriptor */
{ {
int prev_trans = -1;
stbi__int32 x, y, w, h; stbi__int32 x, y, w, h;
stbi_uc *o; stbi_uc *o;
@@ -5702,10 +5753,10 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
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 if (g->transparent >= 0 && (g->eflags & 0x01)) {
g->pal[i][3] = 255; prev_trans = g->pal[g->transparent][3];
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");
@@ -5713,8 +5764,9 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
o = stbi__process_gif_raster(s, g); o = stbi__process_gif_raster(s, g);
if (o == NULL) return NULL; if (o == NULL) return NULL;
if (req_comp && req_comp != 4) if (prev_trans != -1)
o = stbi__convert_format(o, 4, req_comp, g->w, g->h); g->pal[g->transparent][3] = prev_trans;
return o; return o;
} }
@@ -5725,7 +5777,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
len = stbi__get8(s); len = stbi__get8(s);
if (len == 4) { if (len == 4) {
g->eflags = stbi__get8(s); g->eflags = stbi__get8(s);
stbi__get16le(s); // delay g->delay = stbi__get16le(s);
g->transparent = stbi__get8(s); g->transparent = stbi__get8(s);
} else { } else {
stbi__skip(s, len); stbi__skip(s, len);
@@ -5757,7 +5809,11 @@ static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int
if (u) { if (u) {
*x = g.w; *x = g.w;
*y = g.h; *y = g.h;
if (req_comp && req_comp != 4)
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
} }
else if (g.out)
STBI_FREE(g.out);
return u; return u;
} }
@@ -6059,14 +6115,22 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
int act_comp=0,num_packets=0,chained; int act_comp=0,num_packets=0,chained;
stbi__pic_packet packets[10]; stbi__pic_packet packets[10];
stbi__skip(s, 92); if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
stbi__rewind(s);
return 0;
}
stbi__skip(s, 88);
*x = stbi__get16be(s); *x = stbi__get16be(s);
*y = stbi__get16be(s); *y = stbi__get16be(s);
if (stbi__at_eof(s)) return 0; if (stbi__at_eof(s)) {
stbi__rewind( s);
return 0;
}
if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
stbi__rewind( s ); stbi__rewind( s );
return 0; return 0;
} }
stbi__skip(s, 8); stbi__skip(s, 8);
@@ -6292,6 +6356,12 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/* /*
revision history: revision history:
2.07 (2015-09-13) fix compiler warnings
partial animated GIF support
limited 16-bit PSD support
#ifdef unused functions
bug with < 92 byte PIC,PNM,HDR,TGA
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
2.03 (2015-04-12) extra corruption checking (mmozeiko) 2.03 (2015-04-12) extra corruption checking (mmozeiko)
+2 -2
View File
@@ -143,7 +143,7 @@ public:
{ {
public: public:
#if defined(DEBUG) && DEBUG == 1 #if defined(LOVE_IOS)
TempDebugGroup(const char *name) TempDebugGroup(const char *name)
{ {
if (GLAD_EXT_debug_marker) if (GLAD_EXT_debug_marker)
@@ -153,7 +153,7 @@ public:
TempDebugGroup(const char *) {} TempDebugGroup(const char *) {}
#endif #endif
#if defined(DEBUG) && DEBUG == 1 #if defined(LOVE_IOS)
~TempDebugGroup() ~TempDebugGroup()
{ {
if (GLAD_EXT_debug_marker) if (GLAD_EXT_debug_marker)