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()
pull/208/head
Daniel Gibson 2015-12-06 00:30:16 +01:00
parent 7453e1bfa4
commit 57409c3d15
1 changed files with 57 additions and 37 deletions

View File

@ -4813,19 +4813,36 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
#ifndef STBI_NO_TGA
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 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;
tga_image_type = sz;
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);
@ -4837,9 +4854,17 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
return 0; // test height
}
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
// 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) {
case 8: tga_comp = STBI_grey; 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)
{
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 != 15) && (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;
}
@ -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);
// 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 ( tga_indexed )
{