stb_image.h: Improve stbi__tga_info() and stbi__tga_test()
* for paletted images, .._info()'s comp should be based on the palette's bits per pixel, not the images bits per pixel (which describes the size of an index into the palette and is also checked now) * make sure the color (map) type and the image type fields of the header are consistent (=> if TGA color type is 1 for paletted, the TGA image type must be 1 or 9) * .._test() does some more checks and uses stbi__get16le() instead of stbi__get16be() - TGA is little endian. * .._test() now always rewinds (sometimes it used to do only return 0; without rewinding) * remove "error check" at the beginning of stbi__tga_load(), because all that is already tested in stbi__tga_test()
This commit is contained in:
parent
7453e1bfa4
commit
57409c3d15
94
stb_image.h
94
stb_image.h
@ -4813,19 +4813,36 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|||||||
#ifndef STBI_NO_TGA
|
#ifndef STBI_NO_TGA
|
||||||
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
||||||
{
|
{
|
||||||
int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel;
|
int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
|
||||||
int sz;
|
int sz, tga_colormap_type;
|
||||||
stbi__get8(s); // discard Offset
|
stbi__get8(s); // discard Offset
|
||||||
sz = stbi__get8(s); // color type
|
tga_colormap_type = stbi__get8(s); // colormap type
|
||||||
if( sz > 1 ) {
|
if( tga_colormap_type > 1 ) {
|
||||||
stbi__rewind(s);
|
stbi__rewind(s);
|
||||||
return 0; // only RGB or indexed allowed
|
return 0; // only RGB or indexed allowed
|
||||||
}
|
}
|
||||||
sz = stbi__get8(s); // image type
|
tga_image_type = stbi__get8(s); // image type
|
||||||
// only RGB or grey allowed, +/- RLE
|
if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
|
||||||
if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
|
if (tga_image_type != 1 && tga_image_type != 9) {
|
||||||
tga_image_type = sz;
|
stbi__rewind(s);
|
||||||
stbi__skip(s,9);
|
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);
|
tga_w = stbi__get16le(s);
|
||||||
if( tga_w < 1 ) {
|
if( tga_w < 1 ) {
|
||||||
stbi__rewind(s);
|
stbi__rewind(s);
|
||||||
@ -4837,9 +4854,17 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
return 0; // test height
|
return 0; // test height
|
||||||
}
|
}
|
||||||
tga_bits_per_pixel = stbi__get8(s); // bits per pixel
|
tga_bits_per_pixel = stbi__get8(s); // bits per pixel
|
||||||
|
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_bits_per_pixel = tga_colormap_bpp; // make sure colormap's bpp are tested for tga_comp
|
||||||
|
}
|
||||||
sz = stbi__get8(s) & 15; // alpha bits
|
sz = stbi__get8(s) & 15; // alpha bits
|
||||||
// only RGB or RGBA (incl. 16bit) or grey allowed
|
// only RGB or RGBA (incl. 16bit) or grey allowed
|
||||||
// FIXME: don't we have to use the colormap's bpp if indexed?
|
|
||||||
switch(tga_bits_per_pixel) {
|
switch(tga_bits_per_pixel) {
|
||||||
case 8: tga_comp = STBI_grey; break;
|
case 8: tga_comp = STBI_grey; break;
|
||||||
case 15: tga_comp = STBI_rgb; break;
|
case 15: tga_comp = STBI_rgb; break;
|
||||||
@ -4859,25 +4884,31 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
|
|
||||||
static int stbi__tga_test(stbi__context *s)
|
static int stbi__tga_test(stbi__context *s)
|
||||||
{
|
{
|
||||||
int res;
|
int res = 0;
|
||||||
int sz;
|
int sz, tga_color_type;
|
||||||
stbi__get8(s); // discard Offset
|
stbi__get8(s); // discard Offset
|
||||||
sz = stbi__get8(s); // color type
|
tga_color_type = stbi__get8(s); // color type
|
||||||
if ( sz > 1 ) return 0; // only RGB or indexed allowed
|
if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
|
||||||
sz = stbi__get8(s); // image type
|
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
|
if ( tga_color_type == 1 ) { // colormapped (paletted) image
|
||||||
stbi__get16be(s); // discard palette start
|
if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
|
||||||
stbi__get16be(s); // discard palette length
|
stbi__skip(s,4); // skip index of first colormap entry and number of entries
|
||||||
stbi__get8(s); // discard bits per palette color entry
|
sz = stbi__get8(s); // check bits per palette color entry
|
||||||
stbi__get16be(s); // discard x origin
|
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
||||||
stbi__get16be(s); // discard y origin
|
stbi__skip(s,4); // skip image x and y origin
|
||||||
if ( stbi__get16be(s) < 1 ) return 0; // test width
|
} else { // "normal" image w/o colormap
|
||||||
if ( stbi__get16be(s) < 1 ) return 0; // test height
|
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
|
sz = stbi__get8(s); // bits per pixel
|
||||||
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) )
|
if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
|
||||||
res = 0;
|
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
||||||
else
|
|
||||||
res = 1;
|
res = 1; // if we got this far, everything's good and we can return 1 instead of 0
|
||||||
|
|
||||||
|
errorEnd:
|
||||||
stbi__rewind(s);
|
stbi__rewind(s);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -4917,17 +4948,6 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|||||||
}
|
}
|
||||||
tga_inverted = 1 - ((tga_inverted >> 5) & 1);
|
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 != 15) && (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 I'm paletted, then I'll use the number of bits from the palette
|
||||||
if ( tga_indexed )
|
if ( tga_indexed )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user