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
|
||||
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 )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user