Updated stb_image (the latest version includes my patches)

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1544 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-08-01 19:26:35 +00:00
parent 8bde578f90
commit 41b29f45f8
2 changed files with 5445 additions and 5424 deletions

View File

@ -1,4 +1,4 @@
/* stbi-1.26 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
/* stbi-1.27 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
when you control the images you're loading
no warranty implied; use at your own risk
@ -21,24 +21,22 @@
- supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
Latest revisions:
1.26 (2010-07-24)
fix bug in file buffering for PNG reported by SpartanJ
1.25 (2010-07-17)
refix trans_data warning (Won Chun)
1.24 (2010-07-12)
perf improvements reading from files on platforms with lock-heavy fgetc()
minor perf improvements for jpeg
deprecated type-specific functions so we'll get feedback if they're needed
attempt to fix trans_data warning (Won Chun)
1.23 fixed bug in iPhone support
1.22 (2010-07-10)
removed image *writing* support, moved to stb_image_write.h
stbi_info support from Jetro Lauha
GIF support from Jean-Marc Lienher
iPhone PNG-extensions from James Brown
warning-fixes from Nicolas Schulz and Janez Zemva (aka Janez U+017D;emva)
1.21 fix use of 'uint8' in header (reported by jon blow)
1.20 added support for Softimage PIC, by Tom Seddon
1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila)
allow trailing 0s at end of image data (Laurent Gomila)
1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ
1.25 (2010-07-17) refix trans_data warning (Won Chun)
1.24 (2010-07-12) perf improvements reading from files
minor perf improvements for jpeg
deprecated type-specific functions in hope of feedback
attempt to fix trans_data warning (Won Chun)
1.23 fixed bug in iPhone support
1.22 (2010-07-10) removed image *writing* support to stb_image_write.h
stbi_info support from Jetro Lauha
GIF support from Jean-Marc Lienher
iPhone PNG-extensions from James Brown
warning-fixes from Nicolas Schulz and Janez Zemva
1.21 fix use of 'uint8' in header (reported by jon blow)
1.20 added support for Softimage PIC, by Tom Seddon
See end of file for full revision history.
@ -851,7 +849,7 @@ __forceinline static int at_eof(stbi *s)
if (s->img_file) {
if (!feof(s->img_file)) return 0;
// if feof() is true, check if buffer = end
// special case: we've got the one extra character at the end
// special case: we've only got the special 0 character at the end
if (s->from_file == 0) return 1;
}
#endif
@ -1015,13 +1013,13 @@ static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp)
float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f;
if (z < 0) z = 0;
if (z > 255) z = 255;
output[i*comp + k] = (stbi_uc)float2int(z);
output[i*comp + k] = (uint8) float2int(z);
}
if (k < comp) {
float z = data[i*comp+k] * 255 + 0.5f;
if (z < 0) z = 0;
if (z > 255) z = 255;
output[i*comp + k] = (stbi_uc)float2int(z);
output[i*comp + k] = (uint8) float2int(z);
}
}
free(data);
@ -1737,6 +1735,17 @@ static int decode_jpeg_image(jpeg *j)
if (SOS(m)) {
if (!process_scan_header(j)) return 0;
if (!parse_entropy_coded_data(j)) return 0;
if (j->marker == MARKER_none ) {
while (!at_eof(&j->s)) {
int x = get8(&j->s);
if (x == 255) {
j->marker = get8u(&j->s);
break;
} else if (x != 0) {
return 0;
}
}
}
} else {
if (!process_marker(j, m)) return 0;
}
@ -1825,10 +1834,11 @@ static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w
return out;
}
static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 * /*in_far*/, int w, int hs)
static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{
// resample with nearest-neighbor
int i,j;
in_far = in_far;
for (i=0; i < w; ++i)
for (j=0; j < hs; ++j)
out[i*hs+j] = in_near[i];
@ -3207,15 +3217,15 @@ static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp)
mr = mg = mb = 0;
if (compress == 0) {
if (bpp == 32) {
mr = (unsigned int)0xff << 16;
mg = (unsigned int)0xff << 8;
mb = (unsigned int)0xff << 0;
ma = (unsigned int)0xff << 24;
mr = 0xffu << 16;
mg = 0xffu << 8;
mb = 0xffu << 0;
ma = 0xffu << 24;
fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255
} else {
mr = (unsigned int)31 << 10;
mg = (unsigned int)31 << 5;
mb = (unsigned int)31 << 0;
mr = 31u << 10;
mg = 31u << 5;
mb = 31u << 0;
}
} else if (compress == 3) {
mr = get32le(s);
@ -3253,9 +3263,9 @@ static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp)
int z=0;
if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); }
for (i=0; i < psize; ++i) {
pal[i][2] = (stbi_uc)get8(s);
pal[i][1] = (stbi_uc)get8(s);
pal[i][0] = (stbi_uc)get8(s);
pal[i][2] = get8u(s);
pal[i][1] = get8u(s);
pal[i][0] = get8u(s);
if (hsz != 12) get8(s);
pal[i][3] = 255;
}
@ -3311,22 +3321,22 @@ static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp)
if (easy) {
for (i=0; i < (int) s->img_x; ++i) {
int a;
out[z+2] = (uint8)get8(s);
out[z+1] = (uint8)get8(s);
out[z+0] = (uint8)get8(s);
out[z+2] = get8u(s);
out[z+1] = get8u(s);
out[z+0] = get8u(s);
z += 3;
a = (easy == 2 ? get8(s) : 255);
if (target == 4) out[z++] = (uint8)a;
if (target == 4) out[z++] = (uint8) a;
}
} else {
for (i=0; i < (int) s->img_x; ++i) {
uint32 v = (bpp == 16 ? get16le(s) : get32le(s));
int a;
out[z++] = (uint8)shiftsigned(v & mr, rshift, rcount);
out[z++] = (uint8)shiftsigned(v & mg, gshift, gcount);
out[z++] = (uint8)shiftsigned(v & mb, bshift, bcount);
out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount);
out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount);
out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount);
a = (ma ? shiftsigned(v & ma, ashift, acount) : 255);
if (target == 4) out[z++] = (uint8)a;
if (target == 4) out[z++] = (uint8) a;
}
}
skip(s, pad);
@ -3849,20 +3859,20 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp)
len++;
count += len;
while (len) {
*p = (uint8)get8(s);
*p = get8u(s);
p += 4;
len--;
}
} else if (len > 128) {
uint32 val;
uint8 val;
// Next -len+1 bytes in the dest are replicated from next source byte.
// (Interpret len as a negative 8-bit int.)
len ^= 0x0FF;
len += 2;
val = get8(s);
val = get8u(s);
count += len;
while (len) {
*p = (uint8)val;
*p = val;
p += 4;
len--;
}
@ -3886,7 +3896,7 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp)
} else {
// Read the data.
for (i = 0; i < pixelCount; i++)
*p = (uint8)get8(s), p += 4;
*p = get8u(s), p += 4;
}
}
}
@ -3974,7 +3984,7 @@ static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest)
for (i=0; i<4; ++i, mask>>=1) {
if (channel & mask) {
if (at_eof(s)) return epuc("bad file","PIC file too short");
dest[i]=(stbi_uc)get8(s);
dest[i]=get8u(s);
}
}
@ -4006,9 +4016,9 @@ static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *resul
packet = &packets[num_packets++];
chained = get8(s);
packet->size = (stbi_uc)get8(s);
packet->type = (stbi_uc)get8(s);
packet->channel = (stbi_uc)get8(s);
packet->size = get8u(s);
packet->type = get8u(s);
packet->channel = get8u(s);
act_comp |= packet->channel;
@ -4045,11 +4055,11 @@ static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *resul
while (left>0) {
stbi_uc count,value[4];
count=(stbi_uc)get8(s);
count=get8u(s);
if (at_eof(s)) return epuc("bad file","file too short (pure read count)");
if (count > left)
count = (stbi_uc)left;
count = (uint8) left;
if (!pic_readval(s,packet->channel,value)) return 0;
@ -4232,14 +4242,14 @@ int stbi_gif_test_memory (stbi_uc const *buffer, int len)
return gif_test(&s);
}
static void stbi_gif_parse_colortable(stbi *s, stbi_gif *g, uint8 /*pal*/[256][4], int num_entries, int transp)
static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp)
{
int i;
for (i=0; i < num_entries; ++i) {
g->pal[i][2] = (uint8)get8(s);
g->pal[i][1] = (uint8)get8(s);
g->pal[i][0] = (uint8)get8(s);
g->pal[i][3] = transp ? 0 : 255;
pal[i][2] = get8u(s);
pal[i][1] = get8u(s);
pal[i][0] = get8u(s);
pal[i][3] = transp ? 0 : 255;
}
}
@ -4249,7 +4259,7 @@ static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info)
if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8')
return e("not GIF", "Corrupt GIF");
version = (uint8)get8(s);
version = get8u(s);
if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF");
if (get8(s) != 'a') return e("not GIF", "Corrupt GIF");
@ -4266,7 +4276,7 @@ static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info)
if (is_info) return 1;
if (g->flags & 0x80)
stbi_gif_parse_colortable(s,g,g->pal, 2 << (g->flags & 7), -1);
stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1);
return 1;
}
@ -4322,7 +4332,7 @@ static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g)
int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
stbi_gif_lzw *p;
lzw_cs = (uint8)get8(s);
lzw_cs = get8u(s);
clear = 1 << lzw_cs;
first = 1;
codesize = lzw_cs + 1;
@ -4331,8 +4341,8 @@ static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g)
valid_bits = 0;
for (code = 0; code < clear; code++) {
g->codes[code].prefix = -1;
g->codes[code].first = (uint8)code;
g->codes[code].suffix = (uint8)code;
g->codes[code].first = (uint8) code;
g->codes[code].suffix = (uint8) code;
}
// support no starting clear code
@ -4372,13 +4382,13 @@ static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g)
if (oldcode >= 0) {
p = &g->codes[avail++];
if (avail > 4096) return epuc("too many codes", "Corrupt GIF");
p->prefix = (int16)oldcode;
p->prefix = (int16) oldcode;
p->first = g->codes[oldcode].first;
p->suffix = (code == avail) ? p->first : g->codes[code].first;
} else if (code == avail)
return epuc("illegal code in raster", "Corrupt GIF");
stbi_out_gif_code(g, (uint16)code);
stbi_out_gif_code(g, (uint16) code);
if ((avail & codemask) == 0 && avail <= 0x0FFF) {
codesize++;
@ -4461,7 +4471,7 @@ static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp)
}
if (g->lflags & 0x80) {
stbi_gif_parse_colortable(s,g,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 = (uint8 *) g->lpal;
} else if (g->flags & 0x80) {
for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent
@ -4624,7 +4634,7 @@ static char *hdr_gettoken(stbi *z, char *buffer)
int len=0;
char c = '\0';
c = (char)get8(z);
c = (char) get8(z);
while (!at_eof(z) && c != '\n') {
buffer[len++] = c;
@ -4634,7 +4644,7 @@ static char *hdr_gettoken(stbi *z, char *buffer)
;
break;
}
c = (char)get8(z);
c = (char) get8(z);
}
buffer[len] = 0;
@ -4687,13 +4697,11 @@ static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp)
return epf("not HDR", "Corrupt HDR image");
// Parse header
do {
for(;;) {
token = hdr_gettoken(s,buffer);
if (token[0] != 0) {
if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0)
valid = 1;
}
} while (token[0] != 0);
if (token[0] == 0) break;
if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
}
if (!valid) return epf("unsupported format", "Unsupported HDR format");
@ -4740,7 +4748,11 @@ static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp)
if (c1 != 2 || c2 != 2 || (len & 0x80)) {
// not run-length encoded, so we have to actually use THIS data as a decoded
// pixel (note this can't be a valid pixel--one of RGB must be >= 128)
stbi_uc rgbe[4] = { (stbi_uc)c1,(stbi_uc)c2,(stbi_uc)len, (stbi_uc)get8(s) };
uint8 rgbe[4];
rgbe[0] = (uint8) c1;
rgbe[1] = (uint8) c2;
rgbe[2] = (uint8) len;
rgbe[3] = (uint8) get8u(s);
hdr_convert(hdr_data, rgbe, req_comp);
i = 1;
j = 0;
@ -4755,17 +4767,17 @@ static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp)
for (k = 0; k < 4; ++k) {
i = 0;
while (i < width) {
count = (unsigned char)get8(s);
count = get8u(s);
if (count > 128) {
// Run
value = (unsigned char)get8(s);
value = get8u(s);
count -= 128;
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = value;
} else {
// Dump
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = (stbi_uc)get8(s);
scanline[i++ * 4 + k] = get8u(s);
}
}
}
@ -4851,6 +4863,8 @@ int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *c
/*
revision history:
1.27 (2010-08-01)
cast-to-uint8 to fix warnings
1.26 (2010-07-24)
fix bug in file buffering for PNG reported by SpartanJ
1.25 (2010-07-17)

View File

@ -1,4 +1,4 @@
/* stbiw-0.91 - public domain - http://nothings.org/stb/stb_image_write.h
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
@ -84,9 +84,14 @@ static void writefv(FILE *f, const char *fmt, va_list v)
while (*fmt) {
switch (*fmt++) {
case ' ': break;
case '1': { unsigned char x = (unsigned char)va_arg(v, int); fputc(x,f); break; }
case '2': { int x = va_arg(v,int); unsigned char b[2]; b[0] = (unsigned char)x; b[1] = (unsigned char)(x>>8); fwrite(b,2,1,f); break; }
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8); b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24); fwrite(b,4,1,f); break; }
case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
case '2': { int x = va_arg(v,int); unsigned char b[2];
b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
fwrite(b,2,1,f); break; }
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
fwrite(b,4,1,f); break; }
default:
assert(0);
return;
@ -205,7 +210,7 @@ static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
{
while (*bitcount >= 8) {
stbi__sbpush(data, (unsigned char)*bitbuffer);
stbi__sbpush(data, (unsigned char) *bitbuffer);
*bitbuffer >>= 8;
*bitcount -= 8;
}
@ -348,10 +353,10 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
j += blocklen;
blocklen = 5552;
}
stbi__sbpush(out, (unsigned char)(s2 >> 8));
stbi__sbpush(out, (unsigned char)s2);
stbi__sbpush(out, (unsigned char)(s1 >> 8));
stbi__sbpush(out, (unsigned char)s1);
stbi__sbpush(out, (unsigned char) (s2 >> 8));
stbi__sbpush(out, (unsigned char) s2);
stbi__sbpush(out, (unsigned char) (s1 >> 8));
stbi__sbpush(out, (unsigned char) s1);
}
*out_len = stbi__sbn(out);
// make returned pointer freeable
@ -362,7 +367,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
unsigned int stbi__crc32(unsigned char *buffer, int len)
{
static unsigned int crc_table[256];
unsigned int crc = ~(unsigned int)0;
unsigned int crc = ~0u;
int i,j;
if (crc_table[1] == 0)
for(i=0; i < 256; i++)
@ -374,7 +379,7 @@ unsigned int stbi__crc32(unsigned char *buffer, int len)
}
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbi__wp32(data,v) stbi__wpng4(data, v>>24,v>>16,v>>8,v);
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
static void stbi__wpcrc(unsigned char **data, int len)
@ -383,12 +388,12 @@ static void stbi__wpcrc(unsigned char **data, int len)
stbi__wp32(*data, crc);
}
static int stbi__paeth(int a, int b, int c)
static unsigned char stbi__paeth(int a, int b, int c)
{
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
if (pa <= pb && pa <= pc) return a;
if (pb <= pc) return b;
return c;
if (pa <= pb && pa <= pc) return (unsigned char) a;
if (pb <= pc) return (unsigned char) b;
return (unsigned char) c;
}
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
@ -419,7 +424,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
case 4: line_buffer[i] = (signed char)(z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break;
}
@ -429,9 +434,9 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
case 1: line_buffer[i] = z[i] - z[i-n]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
case 4: line_buffer[i] = (signed char)(z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n])); break;
case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 6: line_buffer[i] = (signed char)(z[i] - stbi__paeth(z[i-n], 0,0)); break;
case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
}
}
if (p) break;
@ -441,7 +446,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
}
}
// when we get here, best contains the filter type, and line_buffer contains the data
filt[j*(x*n+1)] = (unsigned char)best;
filt[j*(x*n+1)] = (unsigned char) best;
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
}
free(line_buffer);
@ -461,7 +466,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
stbi__wp32(o, x);
stbi__wp32(o, y);
*o++ = 8;
*o++ = (unsigned char)ctype[n];
*o++ = (unsigned char) ctype[n];
*o++ = 0;
*o++ = 0;
*o++ = 0;
@ -498,6 +503,8 @@ int stbi_write_png(char const *filename, int x, int y, int comp, const void *dat
/* Revision history
0.92 (2010-08-01)
casts to unsigned char to fix warnings
0.91 (2010-07-17)
first public release
0.90 first internal release