imglib: add jpg/png loading using stb_image

This commit is contained in:
Eric Wasylishen 2023-03-25 15:01:40 -06:00
parent c10aee46bc
commit 3997e8c9bc
2 changed files with 51 additions and 3 deletions

View File

@ -4,6 +4,9 @@
#include <common/entdata.h> #include <common/entdata.h>
#include <common/json.hh> #include <common/json.hh>
#define STB_IMAGE_IMPLEMENTATION
#include "../3rdparty/stb_image.h"
/* /*
============================================================================ ============================================================================
PALETTE PALETTE
@ -404,6 +407,42 @@ breakOut:;
return tex; // mxd return tex; // mxd
} }
std::optional<texture> load_stb(
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
{
int x, y, channels_in_file;
stbi_uc *rgba_data = stbi_load_from_memory(file->data(), file->size(), &x, &y, &channels_in_file, 4);
if (!rgba_data) {
logging::funcprint("stbi error: {}\n", stbi_failure_reason());
return {};
}
texture tex;
tex.meta.extension = ext::STB;
tex.meta.name = name;
tex.meta.width = tex.width = x;
tex.meta.height = tex.height = y;
if (!meta_only) {
int num_pixels = x * y;
if (num_pixels < 0) {
return {};
}
tex.pixels.resize(num_pixels);
qvec4b *out = tex.pixels.data();
for (int i = 0; i < num_pixels; ++i) {
out[i] = {rgba_data[4 * i], rgba_data[4 * i + 1], rgba_data[4 * i + 2], rgba_data[4 * i + 3]};
}
}
stbi_image_free(rgba_data);
return tex;
}
// texture cache // texture cache
std::unordered_map<std::string, texture, case_insensitive_hash, case_insensitive_equal> textures; std::unordered_map<std::string, texture, case_insensitive_hash, case_insensitive_equal> textures;

View File

@ -31,7 +31,11 @@ enum class ext
{ {
TGA, TGA,
WAL, WAL,
MIP MIP,
/**
* Anything loadable by stb_image.h
*/
STB
}; };
extern std::vector<qvec3b> palette; extern std::vector<qvec3b> palette;
@ -66,6 +70,7 @@ struct texture
// the width/height of the metadata. // the width/height of the metadata.
uint32_t width = 0, height = 0; uint32_t width = 0, height = 0;
// RGBA order
std::vector<qvec4b> pixels; std::vector<qvec4b> pixels;
// the scale required to map a pixel from the // the scale required to map a pixel from the
@ -95,14 +100,18 @@ std::optional<texture> load_tga(
std::optional<texture> load_mip( std::optional<texture> load_mip(
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
// stb_image.h loaders
std::optional<texture> load_stb(
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
// list of supported extensions and their loaders // list of supported extensions and their loaders
constexpr struct constexpr struct
{ {
const char *suffix; const char *suffix;
ext id; ext id;
decltype(load_wal) *loader; decltype(load_wal) *loader;
} extension_list[] = { } extension_list[] = {{".png", ext::STB, load_stb}, {".jpg", ext::STB, load_stb}, {".tga", ext::TGA, load_tga},
{".tga", ext::TGA, load_tga}, {".wal", ext::WAL, load_wal}, {".mip", ext::MIP, load_mip}, {"", ext::MIP, load_mip}}; {".wal", ext::WAL, load_wal}, {".mip", ext::MIP, load_mip}, {"", ext::MIP, load_mip}};
// Attempt to load a texture from the specified name. // Attempt to load a texture from the specified name.
std::tuple<std::optional<texture>, fs::resolve_result, fs::data> load_texture( std::tuple<std::optional<texture>, fs::resolve_result, fs::data> load_texture(