tga optimizations

This commit is contained in:
Sean Barrett 2014-05-27 21:56:00 -07:00
parent fc0bfd1b71
commit f0976fd312

View File

@ -22,7 +22,7 @@
- overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
Latest revisions: Latest revisions:
1.35 (2014-05-27) warnings, bugfixes, etc 1.35 (2014-05-27) warnings, bugfixes, TGA optimization, etc
1.34 (unknown ) warning fix 1.34 (unknown ) warning fix
1.33 (2011-07-14) minor fixes suggested by Dave Moore 1.33 (2011-07-14) minor fixes suggested by Dave Moore
1.32 (2011-07-13) info support for all filetypes (SpartanJ) 1.32 (2011-07-13) info support for all filetypes (SpartanJ)
@ -57,7 +57,7 @@
John Bartholomew John Bartholomew
Optimizations & bugfixes Ken Hamada Optimizations & bugfixes Ken Hamada
Fabian "ryg" Giesen Cort Stratton Fabian "ryg" Giesen Cort Stratton
Blazej Dariusz Roszkowski Arseny Kapoulkine Blazej Dariusz Roszkowski
Thibault Reuille Thibault Reuille
If your name should be here but Paul Du Bois If your name should be here but Paul Du Bois
isn't let Sean know. Guillaume George isn't let Sean know. Guillaume George
@ -3260,13 +3260,13 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
int tga_width = get16le(s); int tga_width = get16le(s);
int tga_height = get16le(s); int tga_height = get16le(s);
int tga_bits_per_pixel = get8u(s); int tga_bits_per_pixel = get8u(s);
int tga_comp = tga_bits_per_pixel / 8;
int tga_inverted = get8u(s); int tga_inverted = get8u(s);
// image data // image data
unsigned char *tga_data; unsigned char *tga_data;
unsigned char *tga_palette = NULL; unsigned char *tga_palette = NULL;
int i, j; int i, j;
unsigned char raw_data[4]; unsigned char raw_data[4];
unsigned char trans_data[4];
int RLE_count = 0; int RLE_count = 0;
int RLE_repeating = 0; int RLE_repeating = 0;
int read_next_pixel = 1; int read_next_pixel = 1;
@ -3294,29 +3294,29 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
// 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 )
{ {
tga_bits_per_pixel = tga_palette_bits; tga_comp = tga_palette_bits / 8;
} }
// tga info // tga info
*x = tga_width; *x = tga_width;
*y = tga_height; *y = tga_height;
if ( (req_comp < 1) || (req_comp > 4) ) if (comp) *comp = tga_comp;
{
// just use whatever the file was
req_comp = tga_bits_per_pixel / 8;
*comp = req_comp;
} else
{
// force a new number of components
*comp = tga_bits_per_pixel/8;
}
tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp );
if (!tga_data) return epuc("outofmem", "Out of memory"); if (!tga_data) return epuc("outofmem", "Out of memory");
// skip to the data's starting position (offset usually = 0) // skip to the data's starting position (offset usually = 0)
skip(s, tga_offset ); skip(s, tga_offset );
if ( !tga_indexed && !tga_is_RLE) {
for (i=0; i < tga_height; ++i) {
int y = tga_inverted ? tga_height -i - 1 : i;
stbi__uint8 *tga_row = tga_data + y*tga_width*tga_comp;
getn(s, tga_row, tga_width * tga_comp);
}
} else {
// do I need to load a palette? // do I need to load a palette?
if ( tga_indexed ) if ( tga_indexed)
{ {
// any data to skip? (offset usually = 0) // any data to skip? (offset usually = 0)
skip(s, tga_palette_start ); skip(s, tga_palette_start );
@ -3333,7 +3333,6 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
} }
} }
// load the data // load the data
trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0;
for (i=0; i < tga_width * tga_height; ++i) for (i=0; i < tga_width * tga_height; ++i)
{ {
// if I'm in RLE mode, do I need to get a RLE chunk? // if I'm in RLE mode, do I need to get a RLE chunk?
@ -3380,67 +3379,14 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
raw_data[j] = get8u(s); raw_data[j] = get8u(s);
} }
} }
// convert raw to the intermediate format
switch (tga_bits_per_pixel)
{
case 8:
// Luminous => RGBA
trans_data[0] = raw_data[0];
trans_data[1] = raw_data[0];
trans_data[2] = raw_data[0];
trans_data[3] = 255;
break;
case 16:
// Luminous,Alpha => RGBA
trans_data[0] = raw_data[0];
trans_data[1] = raw_data[0];
trans_data[2] = raw_data[0];
trans_data[3] = raw_data[1];
break;
case 24:
// BGR => RGBA
trans_data[0] = raw_data[2];
trans_data[1] = raw_data[1];
trans_data[2] = raw_data[0];
trans_data[3] = 255;
break;
case 32:
// BGRA => RGBA
trans_data[0] = raw_data[2];
trans_data[1] = raw_data[1];
trans_data[2] = raw_data[0];
trans_data[3] = raw_data[3];
break;
}
// clear the reading flag for the next pixel // clear the reading flag for the next pixel
read_next_pixel = 0; read_next_pixel = 0;
} // end of reading a pixel } // end of reading a pixel
// convert to final format
switch (req_comp) // copy data
{ for (j = 0; j < tga_comp; ++j)
case 1: tga_data[i*tga_comp+j] = raw_data[j];
// RGBA => Luminance
tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]);
break;
case 2:
// RGBA => Luminance,Alpha
tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]);
tga_data[i*req_comp+1] = trans_data[3];
break;
case 3:
// RGBA => RGB
tga_data[i*req_comp+0] = trans_data[0];
tga_data[i*req_comp+1] = trans_data[1];
tga_data[i*req_comp+2] = trans_data[2];
break;
case 4:
// RGBA => RGBA
tga_data[i*req_comp+0] = trans_data[0];
tga_data[i*req_comp+1] = trans_data[1];
tga_data[i*req_comp+2] = trans_data[2];
tga_data[i*req_comp+3] = trans_data[3];
break;
}
// in case we're in RLE mode, keep counting down // in case we're in RLE mode, keep counting down
--RLE_count; --RLE_count;
} }
@ -3466,6 +3412,25 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
{ {
free( tga_palette ); free( tga_palette );
} }
}
// swap RGB
if (tga_comp >= 3)
{
unsigned char* tga_pixel = tga_data;
for (i=0; i < tga_width * tga_height; ++i)
{
unsigned char temp = tga_pixel[0];
tga_pixel[0] = tga_pixel[2];
tga_pixel[2] = temp;
tga_pixel += tga_comp;
}
}
// convert to target component count
if (req_comp && req_comp != tga_comp)
tga_data = convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
// the things I do to get rid of an error message, and yet keep // the things I do to get rid of an error message, and yet keep
// Microsoft's C compilers happy... [8^( // Microsoft's C compilers happy... [8^(
tga_palette_start = tga_palette_len = tga_palette_bits = tga_palette_start = tga_palette_len = tga_palette_bits =
@ -4624,6 +4589,7 @@ int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int
fix broken STBI_SIMD path fix broken STBI_SIMD path
fix bug where stbi_load_from_file no longer left file pointer in correct place fix bug where stbi_load_from_file no longer left file pointer in correct place
fix broken non-easy path for 32-bit BMP (possibly never used) fix broken non-easy path for 32-bit BMP (possibly never used)
TGA optimization by Arseny Kapoulkine
1.34 (unknown) 1.34 (unknown)
use STBI_NOTUSED in resample_row_generic(), fix one more leak in tga failure case use STBI_NOTUSED in resample_row_generic(), fix one more leak in tga failure case
1.33 (2011-07-14) 1.33 (2011-07-14)