Re #3167: Update to new stb_image.h library v 2.10 (commit 30015ef464)
This commit is contained in:
Vendored
+304
-199
@@ -1,4 +1,4 @@
|
||||
/* stb_image - v2.08 - public domain image loader - http://nothings.org/stb_image.h
|
||||
/* stb_image - v2.10 - public domain image loader - http://nothings.org/stb_image.h
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
@@ -146,6 +146,8 @@
|
||||
|
||||
|
||||
Latest revision history:
|
||||
2.10 (2016-01-22) avoid warning introduced in 2.09
|
||||
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
|
||||
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
||||
2.07 (2015-09-13) partial animated GIF support
|
||||
limited 16-bit PSD support
|
||||
@@ -175,44 +177,35 @@
|
||||
|
||||
============================ Contributors =========================
|
||||
|
||||
Image formats Bug fixes & warning fixes
|
||||
Sean Barrett (jpeg, png, bmp) Marc LeBlanc
|
||||
Nicolas Schulz (hdr, psd) Christpher Lloyd
|
||||
Jonathan Dummer (tga) Dave Moore
|
||||
Jean-Marc Lienher (gif) Won Chun
|
||||
Tom Seddon (pic) the Horde3D community
|
||||
Thatcher Ulrich (psd) Janez Zemva
|
||||
Ken Miller (pgm, ppm) Jonathan Blow
|
||||
urraka@github (animated gif) Laurent Gomila
|
||||
Aruelien Pocheville
|
||||
Ryamond Barbiero
|
||||
David Woo
|
||||
Extensions, features Martin Golini
|
||||
Jetro Lauha (stbi_info) Roy Eltham
|
||||
Martin "SpartanJ" Golini (stbi_info) Luke Graham
|
||||
James "moose2000" Brown (iPhone PNG) Thomas Ruf
|
||||
Ben "Disch" Wenger (io callbacks) John Bartholomew
|
||||
Omar Cornut (1/2/4-bit PNG) Ken Hamada
|
||||
Nicolas Guillemot (vertical flip) Cort Stratton
|
||||
Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski
|
||||
Thibault Reuille
|
||||
Paul Du Bois
|
||||
Guillaume George
|
||||
Jerry Jansson
|
||||
Hayaki Saito
|
||||
Johan Duparc
|
||||
Ronny Chevalier
|
||||
Optimizations & bugfixes Michal Cichon
|
||||
Fabian "ryg" Giesen Tero Hanninen
|
||||
Arseny Kapoulkine Sergio Gonzalez
|
||||
Cass Everitt
|
||||
Engin Manap
|
||||
If your name should be here but Martins Mozeiko
|
||||
isn't, let Sean know. Joseph Thomson
|
||||
Phil Jordan
|
||||
Nathan Reed
|
||||
Michaelangel007@github
|
||||
Nick Verigakis
|
||||
Image formats Extensions, features
|
||||
Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
|
||||
Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
|
||||
Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
|
||||
Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
|
||||
Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
|
||||
Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
|
||||
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
|
||||
urraka@github (animated gif) Junggon Kim (PNM comments)
|
||||
Daniel Gibson (16-bit TGA)
|
||||
|
||||
Optimizations & bugfixes
|
||||
Fabian "ryg" Giesen
|
||||
Arseny Kapoulkine
|
||||
|
||||
Bug & warning fixes
|
||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||
Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson
|
||||
Dave Moore Roy Eltham Hayaki Saito Phil Jordan
|
||||
Won Chun Luke Graham Johan Duparc Nathan Reed
|
||||
the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis
|
||||
Janez Zemva John Bartholomew Michal Cichon svdijk@github
|
||||
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
|
||||
Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
|
||||
Aruelien Pocheville Thibault Reuille Cass Everitt
|
||||
Ryamond Barbiero Paul Du Bois Engin Manap
|
||||
Blazej Dariusz Roszkowski
|
||||
Michaelangel007@github
|
||||
|
||||
|
||||
LICENSE
|
||||
|
||||
@@ -461,12 +454,12 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y,
|
||||
#ifndef STBI_NO_HDR
|
||||
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
|
||||
STBIDEF void stbi_hdr_to_ldr_scale(float scale);
|
||||
#endif
|
||||
#endif // STBI_NO_HDR
|
||||
|
||||
#ifndef STBI_NO_LINEAR
|
||||
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
|
||||
STBIDEF void stbi_ldr_to_hdr_scale(float scale);
|
||||
#endif // STBI_NO_HDR
|
||||
#endif // STBI_NO_LINEAR
|
||||
|
||||
// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
|
||||
STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
|
||||
@@ -630,18 +623,22 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
||||
#define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
|
||||
#endif
|
||||
|
||||
#if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC)
|
||||
#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
|
||||
// ok
|
||||
#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC)
|
||||
#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
|
||||
// ok
|
||||
#else
|
||||
#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC."
|
||||
#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
|
||||
#endif
|
||||
|
||||
#ifndef STBI_MALLOC
|
||||
#define STBI_MALLOC(sz) malloc(sz)
|
||||
#define STBI_REALLOC(p,sz) realloc(p,sz)
|
||||
#define STBI_FREE(p) free(p)
|
||||
#define STBI_MALLOC(sz) malloc(sz)
|
||||
#define STBI_REALLOC(p,newsz) realloc(p,newsz)
|
||||
#define STBI_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
#ifndef STBI_REALLOC_SIZED
|
||||
#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
|
||||
#endif
|
||||
|
||||
// x86/x64 detection
|
||||
@@ -1186,14 +1183,15 @@ STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void
|
||||
#endif
|
||||
}
|
||||
|
||||
static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
|
||||
#ifndef STBI_NO_LINEAR
|
||||
static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
|
||||
|
||||
#ifndef STBI_NO_LINEAR
|
||||
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
|
||||
STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
|
||||
#endif
|
||||
|
||||
static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
|
||||
|
||||
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
|
||||
STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
|
||||
|
||||
@@ -3616,14 +3614,15 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
||||
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
||||
{
|
||||
char *q;
|
||||
int cur, limit;
|
||||
int cur, limit, old_limit;
|
||||
z->zout = zout;
|
||||
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
||||
cur = (int) (z->zout - z->zout_start);
|
||||
limit = (int) (z->zout_end - z->zout_start);
|
||||
limit = old_limit = (int) (z->zout_end - z->zout_start);
|
||||
while (cur + n > limit)
|
||||
limit *= 2;
|
||||
q = (char *) STBI_REALLOC(z->zout_start, limit);
|
||||
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
||||
STBI_NOTUSED(old_limit);
|
||||
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
||||
z->zout_start = q;
|
||||
z->zout = q + cur;
|
||||
@@ -4408,11 +4407,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
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) {
|
||||
stbi__uint32 idata_limit_old = idata_limit;
|
||||
stbi_uc *p;
|
||||
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
|
||||
while (ioff + c.length > idata_limit)
|
||||
idata_limit *= 2;
|
||||
p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
|
||||
STBI_NOTUSED(idata_limit_old);
|
||||
p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
|
||||
z->idata = p;
|
||||
}
|
||||
if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
|
||||
@@ -4598,19 +4599,22 @@ static int stbi__shiftsigned(int v, int shift, int bits)
|
||||
return result;
|
||||
}
|
||||
|
||||
static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
typedef struct
|
||||
{
|
||||
stbi_uc *out;
|
||||
unsigned int mr=0,mg=0,mb=0,ma=0, all_a=255;
|
||||
stbi_uc pal[256][4];
|
||||
int psize=0,i,j,compress=0,width;
|
||||
int bpp, flip_vertically, pad, target, offset, hsz;
|
||||
int bpp, offset, hsz;
|
||||
unsigned int mr,mg,mb,ma, all_a;
|
||||
} stbi__bmp_data;
|
||||
|
||||
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
||||
{
|
||||
int hsz;
|
||||
if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
|
||||
stbi__get32le(s); // discard filesize
|
||||
stbi__get16le(s); // discard reserved
|
||||
stbi__get16le(s); // discard reserved
|
||||
offset = stbi__get32le(s);
|
||||
hsz = stbi__get32le(s);
|
||||
info->offset = stbi__get32le(s);
|
||||
info->hsz = hsz = stbi__get32le(s);
|
||||
|
||||
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
||||
if (hsz == 12) {
|
||||
s->img_x = stbi__get16le(s);
|
||||
@@ -4620,15 +4624,10 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
s->img_y = stbi__get32le(s);
|
||||
}
|
||||
if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
|
||||
bpp = stbi__get16le(s);
|
||||
if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
|
||||
flip_vertically = ((int) s->img_y) > 0;
|
||||
s->img_y = abs((int) s->img_y);
|
||||
if (hsz == 12) {
|
||||
if (bpp < 24)
|
||||
psize = (offset - 14 - 24) / 3;
|
||||
} else {
|
||||
compress = stbi__get32le(s);
|
||||
info->bpp = stbi__get16le(s);
|
||||
if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
|
||||
if (hsz != 12) {
|
||||
int compress = stbi__get32le(s);
|
||||
if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
|
||||
stbi__get32le(s); // discard sizeof
|
||||
stbi__get32le(s); // discard hres
|
||||
@@ -4642,26 +4641,26 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
stbi__get32le(s);
|
||||
stbi__get32le(s);
|
||||
}
|
||||
if (bpp == 16 || bpp == 32) {
|
||||
mr = mg = mb = 0;
|
||||
if (info->bpp == 16 || info->bpp == 32) {
|
||||
info->mr = info->mg = info->mb = 0;
|
||||
if (compress == 0) {
|
||||
if (bpp == 32) {
|
||||
mr = 0xffu << 16;
|
||||
mg = 0xffu << 8;
|
||||
mb = 0xffu << 0;
|
||||
ma = 0xffu << 24;
|
||||
all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
|
||||
if (info->bpp == 32) {
|
||||
info->mr = 0xffu << 16;
|
||||
info->mg = 0xffu << 8;
|
||||
info->mb = 0xffu << 0;
|
||||
info->ma = 0xffu << 24;
|
||||
info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
|
||||
} else {
|
||||
mr = 31u << 10;
|
||||
mg = 31u << 5;
|
||||
mb = 31u << 0;
|
||||
info->mr = 31u << 10;
|
||||
info->mg = 31u << 5;
|
||||
info->mb = 31u << 0;
|
||||
}
|
||||
} else if (compress == 3) {
|
||||
mr = stbi__get32le(s);
|
||||
mg = stbi__get32le(s);
|
||||
mb = stbi__get32le(s);
|
||||
info->mr = stbi__get32le(s);
|
||||
info->mg = stbi__get32le(s);
|
||||
info->mb = stbi__get32le(s);
|
||||
// not documented, but generated by photoshop and handled by mspaint
|
||||
if (mr == mg && mg == mb) {
|
||||
if (info->mr == info->mg && info->mg == info->mb) {
|
||||
// ?!?!?
|
||||
return stbi__errpuc("bad BMP", "bad BMP");
|
||||
}
|
||||
@@ -4669,11 +4668,13 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
return stbi__errpuc("bad BMP", "bad BMP");
|
||||
}
|
||||
} else {
|
||||
STBI_ASSERT(hsz == 108 || hsz == 124);
|
||||
mr = stbi__get32le(s);
|
||||
mg = stbi__get32le(s);
|
||||
mb = stbi__get32le(s);
|
||||
ma = stbi__get32le(s);
|
||||
int i;
|
||||
if (hsz != 108 && hsz != 124)
|
||||
return stbi__errpuc("bad BMP", "bad BMP");
|
||||
info->mr = stbi__get32le(s);
|
||||
info->mg = stbi__get32le(s);
|
||||
info->mb = stbi__get32le(s);
|
||||
info->ma = stbi__get32le(s);
|
||||
stbi__get32le(s); // discard color space
|
||||
for (i=0; i < 12; ++i)
|
||||
stbi__get32le(s); // discard color space parameters
|
||||
@@ -4684,35 +4685,68 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
stbi__get32le(s); // discard reserved
|
||||
}
|
||||
}
|
||||
if (bpp < 16)
|
||||
psize = (offset - 14 - hsz) >> 2;
|
||||
}
|
||||
return (void *) 1;
|
||||
}
|
||||
|
||||
|
||||
static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi_uc *out;
|
||||
unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
|
||||
stbi_uc pal[256][4];
|
||||
int psize=0,i,j,width;
|
||||
int flip_vertically, pad, target;
|
||||
stbi__bmp_data info;
|
||||
|
||||
info.all_a = 255;
|
||||
if (stbi__bmp_parse_header(s, &info) == NULL)
|
||||
return NULL; // error code already set
|
||||
|
||||
flip_vertically = ((int) s->img_y) > 0;
|
||||
s->img_y = abs((int) s->img_y);
|
||||
|
||||
mr = info.mr;
|
||||
mg = info.mg;
|
||||
mb = info.mb;
|
||||
ma = info.ma;
|
||||
all_a = info.all_a;
|
||||
|
||||
if (info.hsz == 12) {
|
||||
if (info.bpp < 24)
|
||||
psize = (info.offset - 14 - 24) / 3;
|
||||
} else {
|
||||
if (info.bpp < 16)
|
||||
psize = (info.offset - 14 - info.hsz) >> 2;
|
||||
}
|
||||
|
||||
s->img_n = ma ? 4 : 3;
|
||||
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
||||
target = req_comp;
|
||||
else
|
||||
target = s->img_n; // if they want monochrome, we'll post-convert
|
||||
|
||||
out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y);
|
||||
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
||||
if (bpp < 16) {
|
||||
if (info.bpp < 16) {
|
||||
int z=0;
|
||||
if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
|
||||
for (i=0; i < psize; ++i) {
|
||||
pal[i][2] = stbi__get8(s);
|
||||
pal[i][1] = stbi__get8(s);
|
||||
pal[i][0] = stbi__get8(s);
|
||||
if (hsz != 12) stbi__get8(s);
|
||||
if (info.hsz != 12) stbi__get8(s);
|
||||
pal[i][3] = 255;
|
||||
}
|
||||
stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4));
|
||||
if (bpp == 4) width = (s->img_x + 1) >> 1;
|
||||
else if (bpp == 8) width = s->img_x;
|
||||
stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
|
||||
if (info.bpp == 4) width = (s->img_x + 1) >> 1;
|
||||
else if (info.bpp == 8) width = s->img_x;
|
||||
else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
|
||||
pad = (-width)&3;
|
||||
for (j=0; j < (int) s->img_y; ++j) {
|
||||
for (i=0; i < (int) s->img_x; i += 2) {
|
||||
int v=stbi__get8(s),v2=0;
|
||||
if (bpp == 4) {
|
||||
if (info.bpp == 4) {
|
||||
v2 = v & 15;
|
||||
v >>= 4;
|
||||
}
|
||||
@@ -4721,7 +4755,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
out[z++] = pal[v][2];
|
||||
if (target == 4) out[z++] = 255;
|
||||
if (i+1 == (int) s->img_x) break;
|
||||
v = (bpp == 8) ? stbi__get8(s) : v2;
|
||||
v = (info.bpp == 8) ? stbi__get8(s) : v2;
|
||||
out[z++] = pal[v][0];
|
||||
out[z++] = pal[v][1];
|
||||
out[z++] = pal[v][2];
|
||||
@@ -4733,14 +4767,14 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
|
||||
int z = 0;
|
||||
int easy=0;
|
||||
stbi__skip(s, offset - 14 - hsz);
|
||||
if (bpp == 24) width = 3 * s->img_x;
|
||||
else if (bpp == 16) width = 2*s->img_x;
|
||||
stbi__skip(s, info.offset - 14 - info.hsz);
|
||||
if (info.bpp == 24) width = 3 * s->img_x;
|
||||
else if (info.bpp == 16) width = 2*s->img_x;
|
||||
else /* bpp = 32 and pad = 0 */ width=0;
|
||||
pad = (-width) & 3;
|
||||
if (bpp == 24) {
|
||||
if (info.bpp == 24) {
|
||||
easy = 1;
|
||||
} else if (bpp == 32) {
|
||||
} else if (info.bpp == 32) {
|
||||
if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
|
||||
easy = 2;
|
||||
}
|
||||
@@ -4765,6 +4799,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
if (target == 4) out[z++] = a;
|
||||
}
|
||||
} else {
|
||||
int bpp = info.bpp;
|
||||
for (i=0; i < (int) s->img_x; ++i) {
|
||||
stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
|
||||
int a;
|
||||
@@ -4811,20 +4846,55 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
// Targa Truevision - TGA
|
||||
// by Jonathan Dummer
|
||||
#ifndef STBI_NO_TGA
|
||||
// returns STBI_rgb or whatever, 0 on error
|
||||
static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
|
||||
{
|
||||
// only RGB or RGBA (incl. 16bit) or grey allowed
|
||||
if(is_rgb16) *is_rgb16 = 0;
|
||||
switch(bits_per_pixel) {
|
||||
case 8: return STBI_grey;
|
||||
case 16: if(is_grey) return STBI_grey_alpha;
|
||||
// else: fall-through
|
||||
case 15: if(is_rgb16) *is_rgb16 = 1;
|
||||
return STBI_rgb;
|
||||
case 24: // fall-through
|
||||
case 32: return bits_per_pixel/8;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
||||
{
|
||||
int tga_w, tga_h, tga_comp;
|
||||
int sz;
|
||||
int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
|
||||
int sz, tga_colormap_type;
|
||||
stbi__get8(s); // discard Offset
|
||||
sz = stbi__get8(s); // color type
|
||||
if( sz > 1 ) {
|
||||
tga_colormap_type = stbi__get8(s); // colormap type
|
||||
if( tga_colormap_type > 1 ) {
|
||||
stbi__rewind(s);
|
||||
return 0; // only RGB or indexed allowed
|
||||
}
|
||||
sz = stbi__get8(s); // image type
|
||||
// only RGB or grey allowed, +/- RLE
|
||||
if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
|
||||
stbi__skip(s,9);
|
||||
tga_image_type = stbi__get8(s); // image type
|
||||
if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
|
||||
if (tga_image_type != 1 && tga_image_type != 9) {
|
||||
stbi__rewind(s);
|
||||
return 0;
|
||||
}
|
||||
stbi__skip(s,4); // skip index of first colormap entry and number of entries
|
||||
sz = stbi__get8(s); // check bits per palette color entry
|
||||
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
|
||||
stbi__rewind(s);
|
||||
return 0;
|
||||
}
|
||||
stbi__skip(s,4); // skip image x and y origin
|
||||
tga_colormap_bpp = sz;
|
||||
} else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
|
||||
if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
|
||||
stbi__rewind(s);
|
||||
return 0; // only RGB or grey allowed, +/- RLE
|
||||
}
|
||||
stbi__skip(s,9); // skip colormap specification and image x/y origin
|
||||
tga_colormap_bpp = 0;
|
||||
}
|
||||
tga_w = stbi__get16le(s);
|
||||
if( tga_w < 1 ) {
|
||||
stbi__rewind(s);
|
||||
@@ -4835,44 +4905,80 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
||||
stbi__rewind(s);
|
||||
return 0; // test height
|
||||
}
|
||||
sz = stbi__get8(s); // bits per pixel
|
||||
// only RGB or RGBA or grey allowed
|
||||
if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) {
|
||||
stbi__rewind(s);
|
||||
return 0;
|
||||
tga_bits_per_pixel = stbi__get8(s); // bits per pixel
|
||||
stbi__get8(s); // ignore alpha bits
|
||||
if (tga_colormap_bpp != 0) {
|
||||
if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
|
||||
// when using a colormap, tga_bits_per_pixel is the size of the indexes
|
||||
// I don't think anything but 8 or 16bit indexes makes sense
|
||||
stbi__rewind(s);
|
||||
return 0;
|
||||
}
|
||||
tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
|
||||
} else {
|
||||
tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
|
||||
}
|
||||
if(!tga_comp) {
|
||||
stbi__rewind(s);
|
||||
return 0;
|
||||
}
|
||||
tga_comp = sz;
|
||||
if (x) *x = tga_w;
|
||||
if (y) *y = tga_h;
|
||||
if (comp) *comp = tga_comp / 8;
|
||||
if (comp) *comp = tga_comp;
|
||||
return 1; // seems to have passed everything
|
||||
}
|
||||
|
||||
static int stbi__tga_test(stbi__context *s)
|
||||
{
|
||||
int res;
|
||||
int sz;
|
||||
int res = 0;
|
||||
int sz, tga_color_type;
|
||||
stbi__get8(s); // discard Offset
|
||||
sz = stbi__get8(s); // color type
|
||||
if ( sz > 1 ) return 0; // only RGB or indexed allowed
|
||||
tga_color_type = stbi__get8(s); // color type
|
||||
if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
|
||||
sz = stbi__get8(s); // image type
|
||||
if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE
|
||||
stbi__get16be(s); // discard palette start
|
||||
stbi__get16be(s); // discard palette length
|
||||
stbi__get8(s); // discard bits per palette color entry
|
||||
stbi__get16be(s); // discard x origin
|
||||
stbi__get16be(s); // discard y origin
|
||||
if ( stbi__get16be(s) < 1 ) return 0; // test width
|
||||
if ( stbi__get16be(s) < 1 ) return 0; // test height
|
||||
if ( tga_color_type == 1 ) { // colormapped (paletted) image
|
||||
if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
|
||||
stbi__skip(s,4); // skip index of first colormap entry and number of entries
|
||||
sz = stbi__get8(s); // check bits per palette color entry
|
||||
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
||||
stbi__skip(s,4); // skip image x and y origin
|
||||
} else { // "normal" image w/o colormap
|
||||
if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
|
||||
stbi__skip(s,9); // skip colormap specification and image x/y origin
|
||||
}
|
||||
if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width
|
||||
if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height
|
||||
sz = stbi__get8(s); // bits per pixel
|
||||
if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) )
|
||||
res = 0;
|
||||
else
|
||||
res = 1;
|
||||
if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
|
||||
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
||||
|
||||
res = 1; // if we got this far, everything's good and we can return 1 instead of 0
|
||||
|
||||
errorEnd:
|
||||
stbi__rewind(s);
|
||||
return res;
|
||||
}
|
||||
|
||||
// read 16bit value and convert to 24bit RGB
|
||||
void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
|
||||
{
|
||||
stbi__uint16 px = stbi__get16le(s);
|
||||
stbi__uint16 fiveBitMask = 31;
|
||||
// we have 3 channels with 5bits each
|
||||
int r = (px >> 10) & fiveBitMask;
|
||||
int g = (px >> 5) & fiveBitMask;
|
||||
int b = px & fiveBitMask;
|
||||
// Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
|
||||
out[0] = (r * 255)/31;
|
||||
out[1] = (g * 255)/31;
|
||||
out[2] = (b * 255)/31;
|
||||
|
||||
// some people claim that the most significant bit might be used for alpha
|
||||
// (possibly if an alpha-bit is set in the "image descriptor byte")
|
||||
// but that only made 16bit test images completely translucent..
|
||||
// so let's treat all 15 and 16bit TGAs as RGB with no alpha.
|
||||
}
|
||||
|
||||
static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
// read in the TGA header stuff
|
||||
@@ -4888,8 +4994,9 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
int tga_width = stbi__get16le(s);
|
||||
int tga_height = stbi__get16le(s);
|
||||
int tga_bits_per_pixel = stbi__get8(s);
|
||||
int tga_comp = tga_bits_per_pixel / 8;
|
||||
int tga_comp, tga_rgb16=0;
|
||||
int tga_inverted = stbi__get8(s);
|
||||
// int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
|
||||
// image data
|
||||
unsigned char *tga_data;
|
||||
unsigned char *tga_palette = NULL;
|
||||
@@ -4905,25 +5012,14 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
tga_image_type -= 8;
|
||||
tga_is_RLE = 1;
|
||||
}
|
||||
/* int tga_alpha_bits = tga_inverted & 15; */
|
||||
tga_inverted = 1 - ((tga_inverted >> 5) & 1);
|
||||
|
||||
// error check
|
||||
if ( //(tga_indexed) ||
|
||||
(tga_width < 1) || (tga_height < 1) ||
|
||||
(tga_image_type < 1) || (tga_image_type > 3) ||
|
||||
((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) &&
|
||||
(tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))
|
||||
)
|
||||
{
|
||||
return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA
|
||||
}
|
||||
|
||||
// If I'm paletted, then I'll use the number of bits from the palette
|
||||
if ( tga_indexed )
|
||||
{
|
||||
tga_comp = tga_palette_bits / 8;
|
||||
}
|
||||
if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
|
||||
else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
|
||||
|
||||
if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
|
||||
return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
|
||||
|
||||
// tga info
|
||||
*x = tga_width;
|
||||
@@ -4936,7 +5032,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
// skip to the data's starting position (offset usually = 0)
|
||||
stbi__skip(s, tga_offset );
|
||||
|
||||
if ( !tga_indexed && !tga_is_RLE) {
|
||||
if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
|
||||
for (i=0; i < tga_height; ++i) {
|
||||
int row = tga_inverted ? tga_height -i - 1 : i;
|
||||
stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
|
||||
@@ -4949,15 +5045,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
// any data to skip? (offset usually = 0)
|
||||
stbi__skip(s, tga_palette_start );
|
||||
// load the palette
|
||||
tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 );
|
||||
tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp );
|
||||
if (!tga_palette) {
|
||||
STBI_FREE(tga_data);
|
||||
return stbi__errpuc("outofmem", "Out of memory");
|
||||
}
|
||||
if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) {
|
||||
STBI_FREE(tga_data);
|
||||
STBI_FREE(tga_palette);
|
||||
return stbi__errpuc("bad palette", "Corrupt TGA");
|
||||
if (tga_rgb16) {
|
||||
stbi_uc *pal_entry = tga_palette;
|
||||
STBI_ASSERT(tga_comp == STBI_rgb);
|
||||
for (i=0; i < tga_palette_len; ++i) {
|
||||
stbi__tga_read_rgb16(s, pal_entry);
|
||||
pal_entry += tga_comp;
|
||||
}
|
||||
} else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
|
||||
STBI_FREE(tga_data);
|
||||
STBI_FREE(tga_palette);
|
||||
return stbi__errpuc("bad palette", "Corrupt TGA");
|
||||
}
|
||||
}
|
||||
// load the data
|
||||
@@ -4987,23 +5090,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
// load however much data we did have
|
||||
if ( tga_indexed )
|
||||
{
|
||||
// read in 1 byte, then perform the lookup
|
||||
int pal_idx = stbi__get8(s);
|
||||
if ( pal_idx >= tga_palette_len )
|
||||
{
|
||||
// invalid index
|
||||
// read in index, then perform the lookup
|
||||
int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
|
||||
if ( pal_idx >= tga_palette_len ) {
|
||||
// invalid index
|
||||
pal_idx = 0;
|
||||
}
|
||||
pal_idx *= tga_bits_per_pixel / 8;
|
||||
for (j = 0; j*8 < tga_bits_per_pixel; ++j)
|
||||
{
|
||||
pal_idx *= tga_comp;
|
||||
for (j = 0; j < tga_comp; ++j) {
|
||||
raw_data[j] = tga_palette[pal_idx+j];
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else if(tga_rgb16) {
|
||||
STBI_ASSERT(tga_comp == STBI_rgb);
|
||||
stbi__tga_read_rgb16(s, raw_data);
|
||||
} else {
|
||||
// read in the data raw
|
||||
for (j = 0; j*8 < tga_bits_per_pixel; ++j)
|
||||
{
|
||||
for (j = 0; j < tga_comp; ++j) {
|
||||
raw_data[j] = stbi__get8(s);
|
||||
}
|
||||
}
|
||||
@@ -5042,8 +5144,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
}
|
||||
}
|
||||
|
||||
// swap RGB
|
||||
if (tga_comp >= 3)
|
||||
// swap RGB - if the source data was RGB16, it already is in the right order
|
||||
if (tga_comp >= 3 && !tga_rgb16)
|
||||
{
|
||||
unsigned char* tga_pixel = tga_data;
|
||||
for (i=0; i < tga_width * tga_height; ++i)
|
||||
@@ -6017,7 +6119,7 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
|
||||
char *token;
|
||||
int valid = 0;
|
||||
|
||||
if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) {
|
||||
if (stbi__hdr_test(s) == 0) {
|
||||
stbi__rewind( s );
|
||||
return 0;
|
||||
}
|
||||
@@ -6054,29 +6156,17 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
|
||||
#ifndef STBI_NO_BMP
|
||||
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
||||
{
|
||||
int hsz;
|
||||
if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') {
|
||||
stbi__rewind( s );
|
||||
return 0;
|
||||
}
|
||||
stbi__skip(s,12);
|
||||
hsz = stbi__get32le(s);
|
||||
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) {
|
||||
stbi__rewind( s );
|
||||
return 0;
|
||||
}
|
||||
if (hsz == 12) {
|
||||
*x = stbi__get16le(s);
|
||||
*y = stbi__get16le(s);
|
||||
} else {
|
||||
*x = stbi__get32le(s);
|
||||
*y = stbi__get32le(s);
|
||||
}
|
||||
if (stbi__get16le(s) != 1) {
|
||||
stbi__rewind( s );
|
||||
return 0;
|
||||
}
|
||||
*comp = stbi__get16le(s) / 8;
|
||||
void *p;
|
||||
stbi__bmp_data info;
|
||||
|
||||
info.all_a = 255;
|
||||
p = stbi__bmp_parse_header(s, &info);
|
||||
stbi__rewind( s );
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
*x = s->img_x;
|
||||
*y = s->img_y;
|
||||
*comp = info.ma ? 4 : 3;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -6222,8 +6312,16 @@ static int stbi__pnm_isspace(char c)
|
||||
|
||||
static void stbi__pnm_skip_whitespace(stbi__context *s, char *c)
|
||||
{
|
||||
while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
|
||||
*c = (char) stbi__get8(s);
|
||||
for (;;) {
|
||||
while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
|
||||
*c = (char) stbi__get8(s);
|
||||
|
||||
if (stbi__at_eof(s) || *c != '#')
|
||||
break;
|
||||
|
||||
while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
|
||||
*c = (char) stbi__get8(s);
|
||||
}
|
||||
}
|
||||
|
||||
static int stbi__pnm_isdigit(char c)
|
||||
@@ -6361,10 +6459,17 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
|
||||
/*
|
||||
revision history:
|
||||
2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
|
||||
2.09 (2016-01-16) allow comments in PNM files
|
||||
16-bit-per-pixel TGA (not bit-per-component)
|
||||
info() for TGA could break due to .hdr handling
|
||||
info() for BMP to shares code instead of sloppy parse
|
||||
can use STBI_REALLOC_SIZED if allocator doesn't support realloc
|
||||
code cleanup
|
||||
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
||||
2.07 (2015-09-13) fix compiler warnings
|
||||
partial animated GIF support
|
||||
limited 16-bit PSD support
|
||||
limited 16-bpc 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
|
||||
|
||||
Reference in New Issue
Block a user