use STB for TGA as well
This commit is contained in:
parent
45fd6ac588
commit
3f3b765780
154
common/imglib.cc
154
common/imglib.cc
|
|
@ -253,160 +253,6 @@ std::optional<texture> load_mip(
|
|||
return tex;
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
TARGA IMAGE
|
||||
============================================================================
|
||||
*/
|
||||
struct targa_t
|
||||
{
|
||||
uint8_t id_length, colormap_type, image_type;
|
||||
uint16_t colormap_index, colormap_length;
|
||||
uint8_t colormap_size;
|
||||
uint16_t x_origin, y_origin, width, height;
|
||||
uint8_t pixel_size, attributes;
|
||||
|
||||
auto stream_data()
|
||||
{
|
||||
return std::tie(id_length, colormap_type, image_type, colormap_index, colormap_length, colormap_size, x_origin,
|
||||
y_origin, width, height, pixel_size, attributes);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadTGA
|
||||
=============
|
||||
*/
|
||||
std::optional<texture> load_tga(
|
||||
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
|
||||
{
|
||||
imemstream stream(file->data(), file->size(), std::ios_base::in | std::ios_base::binary);
|
||||
stream >> endianness<std::endian::little>;
|
||||
|
||||
// Parse TGA
|
||||
targa_t targa_header;
|
||||
stream >= targa_header;
|
||||
|
||||
if (targa_header.image_type != 2 && targa_header.image_type != 10) {
|
||||
logging::funcprint("Failed to load {}. Only type 2 and 10 targa RGB images supported.\n", name);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24)) {
|
||||
logging::funcprint("Failed to load {}. Only 32 or 24 bit images supported (no colormaps).\n", name);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int32_t columns = targa_header.width;
|
||||
int32_t rows = targa_header.height;
|
||||
uint32_t numPixels = columns * rows;
|
||||
|
||||
texture tex;
|
||||
|
||||
tex.meta.extension = ext::TGA;
|
||||
|
||||
tex.meta.name = name;
|
||||
tex.meta.width = tex.width = columns;
|
||||
tex.meta.height = tex.height = rows;
|
||||
|
||||
if (!meta_only) {
|
||||
tex.pixels.resize(numPixels);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
stream.seekg(targa_header.id_length, std::ios_base::cur); // skip TARGA image comment
|
||||
|
||||
if (targa_header.image_type == 2) { // Uncompressed, RGB images
|
||||
for (int32_t row = rows - 1; row >= 0; row--) {
|
||||
qvec4b *pixbuf = tex.pixels.data() + row * columns;
|
||||
for (int32_t column = 0; column < columns; column++) {
|
||||
uint8_t red, green, blue, alphabyte;
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
stream >= blue >= green >= red;
|
||||
*pixbuf++ = {red, green, blue, 255};
|
||||
break;
|
||||
case 32:
|
||||
stream >= blue >= green >= red >= alphabyte;
|
||||
*pixbuf++ = {red, green, blue, alphabyte};
|
||||
break;
|
||||
default:
|
||||
logging::funcprint(
|
||||
"TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (targa_header.image_type == 10) { // Runlength encoded RGB images
|
||||
unsigned char red, green, blue, alphabyte, j;
|
||||
for (int32_t row = rows - 1; row >= 0; row--) {
|
||||
qvec4b *pixbuf = tex.pixels.data() + row * columns;
|
||||
for (int32_t column = 0; column < columns;) {
|
||||
uint8_t packetHeader;
|
||||
stream >= packetHeader;
|
||||
uint8_t packetSize = 1 + (packetHeader & 0x7f);
|
||||
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
stream >= blue >= green >= red;
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32: stream >= blue >= green >= red >= alphabyte; break;
|
||||
default:
|
||||
logging::funcprint(
|
||||
"TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
for (j = 0; j < packetSize; j++) {
|
||||
*pixbuf++ = {red, green, blue, alphabyte};
|
||||
column++;
|
||||
if (column == columns) { // run spans across rows
|
||||
column = 0;
|
||||
if (row > 0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = tex.pixels.data() + row * columns;
|
||||
}
|
||||
}
|
||||
} else { // non run-length packet
|
||||
for (j = 0; j < packetSize; j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
stream >= blue >= green >= red;
|
||||
*pixbuf++ = {red, green, blue, 255};
|
||||
break;
|
||||
case 32:
|
||||
stream >= blue >= green >= red >= alphabyte;
|
||||
*pixbuf++ = {red, green, blue, alphabyte};
|
||||
break;
|
||||
default:
|
||||
logging::funcprint(
|
||||
"TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd
|
||||
return std::nullopt;
|
||||
}
|
||||
column++;
|
||||
if (column == columns) { // pixel packet run spans across rows
|
||||
column = 0;
|
||||
if (row > 0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = tex.pixels.data() + row * columns;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tex; // mxd
|
||||
}
|
||||
|
||||
std::optional<texture> load_stb(
|
||||
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -95,10 +95,6 @@ const texture *find(const std::string_view &str);
|
|||
std::optional<texture> load_wal(
|
||||
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
|
||||
|
||||
// Load TGA
|
||||
std::optional<texture> load_tga(
|
||||
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
|
||||
|
||||
// Load Quake/Half Life mip (raw data)
|
||||
std::optional<texture> load_mip(
|
||||
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
|
||||
|
|
@ -113,7 +109,7 @@ constexpr struct
|
|||
const char *suffix;
|
||||
ext id;
|
||||
decltype(load_wal) *loader;
|
||||
} extension_list[] = {{".png", ext::STB, load_stb}, {".jpg", ext::STB, load_stb}, {".tga", ext::TGA, load_tga},
|
||||
} extension_list[] = {{".png", ext::STB, load_stb}, {".jpg", ext::STB, load_stb}, {".tga", ext::TGA, load_stb},
|
||||
{".wal", ext::WAL, load_wal}, {".mip", ext::MIP, load_mip}, {"", ext::MIP, load_mip}};
|
||||
|
||||
// Attempt to load a texture from the specified name.
|
||||
|
|
|
|||
Loading…
Reference in New Issue