|
8 | 8 | #include "libnsbmp.h" |
9 | 9 | #include "nsgif.h" |
10 | 10 | #include "log.h" |
| 11 | + |
| 12 | +// STB |
| 13 | +#define STB_IMAGE_IMPLEMENTATION |
| 14 | +#define STBI_NO_STDIO |
| 15 | +#define STBI_NO_BMP |
| 16 | +#define STBI_NO_GIF |
| 17 | +#define STBI_NO_HDR |
| 18 | +#define STBI_NO_JPEG |
| 19 | +#define STBI_NO_PIC |
| 20 | +#define STBI_NO_PNG |
| 21 | +#define STBI_ONLY_PNM |
| 22 | +#define STBI_ONLY_PSD |
| 23 | +#define STBI_ONLY_TGA |
| 24 | +#include "stb_image.h" |
| 25 | + |
| 26 | +// TIFF |
| 27 | +#include "tiffio.h" |
| 28 | +#include "tiffiop.h" |
| 29 | + |
11 | 30 | #include "textures.h" |
12 | 31 | #include "utils.h" |
13 | 32 |
|
@@ -240,30 +259,99 @@ namespace Textures { |
240 | 259 | return tex; |
241 | 260 | } |
242 | 261 |
|
243 | | - g2dTexture *LoadImage(const std::string &path, int size) { |
244 | | - int ret = 0; |
245 | | - unsigned char *data = static_cast<unsigned char *>(std::malloc(size)); |
246 | | - |
247 | | - if (R_FAILED(ret = FS::ReadFile(path, data, size))) { |
248 | | - Log::Error("%s(FS::ReadFile) failed: 0x%08x\n", __func__, ret); |
249 | | - std::free(data); |
| 262 | + static g2dTexture *LoadImageBuffer(const unsigned char *data, int size) { |
| 263 | + int width = 0, height = 0, channels = 0; |
| 264 | + g2dTexture *tex = nullptr; |
| 265 | + |
| 266 | + unsigned char *img = stbi_load_from_memory(data, size, &width, &height, &channels, STBI_rgb_alpha); |
| 267 | + |
| 268 | + if (!img) { |
| 269 | + Log::Error("%s(stbi_load_from_memory) failed: %s\n", __func__, stbi_failure_reason()); |
250 | 270 | return nullptr; |
251 | 271 | } |
| 272 | + |
| 273 | + if (width > 512 || height > 512) { |
| 274 | + Log::Error("%s g2d does not support images greater than 512x512\n", __func__); |
| 275 | + stbi_image_free(img); |
| 276 | + return nullptr; |
| 277 | + } |
| 278 | + |
| 279 | + tex = g2dTexLoad(img, width, height, G2D_SWIZZLE); |
| 280 | + stbi_image_free(img); |
| 281 | + return tex; |
| 282 | + } |
252 | 283 |
|
| 284 | + static g2dTexture *LoadImageTIFF(const std::string &path) { |
| 285 | + TIFF *tif = TIFFOpen(path.c_str(), "r"); |
253 | 286 | g2dTexture *tex = nullptr; |
254 | | - const char *ext = FS::GetFileExt(path.c_str()); |
255 | 287 |
|
256 | | - if (strncasecmp(ext, "bmp", 3) == 0) { |
257 | | - tex = Textures::LoadImageBufferBMP(data, size); |
| 288 | + if (tif) { |
| 289 | + std::size_t pixelCount = 0; |
| 290 | + u32 *raster = nullptr; |
| 291 | + int width = 0, height = 0; |
| 292 | + |
| 293 | + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); |
| 294 | + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); |
| 295 | + pixelCount = width * height; |
| 296 | + |
| 297 | + raster = (u32 *)_TIFFCheckMalloc(tif, pixelCount, sizeof(u32), "raster buffer"); |
| 298 | + if (raster != nullptr) { |
| 299 | + if (TIFFReadRGBAImageOriented(tif, width, height, raster, ORIENTATION_TOPLEFT)) { |
| 300 | + tex = g2dTexLoad(reinterpret_cast<unsigned char*>(raster), width, height, G2D_SWIZZLE); |
| 301 | + _TIFFfree(raster); |
| 302 | + } |
| 303 | + else { |
| 304 | + Log::Error("%s(TIFFReadRGBAImage) failed\n", __func__); |
| 305 | + } |
| 306 | + |
| 307 | + } |
| 308 | + else { |
| 309 | + Log::Error("%s(_TIFFmalloc) failed\n", __func__); |
| 310 | + } |
| 311 | + |
| 312 | + TIFFClose(tif); |
| 313 | + return tex; |
258 | 314 | } |
259 | | - else if (strncasecmp(ext, "gif", 3) == 0) { |
260 | | - tex = Textures::LoadImageBufferGIF(data, size); |
| 315 | + else { |
| 316 | + Log::Error("%s(TIFFOpen) failed\n", __func__); |
261 | 317 | } |
262 | | - else if ((strncasecmp(ext, "jpeg", 4) == 0) || (strncasecmp(ext, "jpg", 3) == 0)) { |
263 | | - tex = Textures::LoadImageBufferJPEG(data, size); |
| 318 | + |
| 319 | + return tex; |
| 320 | + } |
| 321 | + |
| 322 | + g2dTexture *LoadImage(const std::string &path, int size) { |
| 323 | + int ret = 0; |
| 324 | + unsigned char *data = static_cast<unsigned char *>(std::malloc(size)); |
| 325 | + |
| 326 | + g2dTexture *tex = nullptr; |
| 327 | + const char *ext = FS::GetFileExt(path.c_str()); |
| 328 | + |
| 329 | + if ((strncasecmp(ext, "tif", 3) == 0) || (strncasecmp(ext, "tiff", 4) == 0)) { |
| 330 | + tex = Textures::LoadImageTIFF(path); |
264 | 331 | } |
265 | | - else if (strncasecmp(ext, "png", 3) == 0) { |
266 | | - tex = Textures::LoadImageBufferPNG(data, size); |
| 332 | + else { |
| 333 | + if (R_FAILED(ret = FS::ReadFile(path, data, size))) { |
| 334 | + Log::Error("%s(FS::ReadFile) failed: 0x%08x\n", __func__, ret); |
| 335 | + std::free(data); |
| 336 | + return nullptr; |
| 337 | + } |
| 338 | + |
| 339 | + if (strncasecmp(ext, "bmp", 3) == 0) { |
| 340 | + tex = Textures::LoadImageBufferBMP(data, size); |
| 341 | + } |
| 342 | + else if (strncasecmp(ext, "gif", 3) == 0) { |
| 343 | + tex = Textures::LoadImageBufferGIF(data, size); |
| 344 | + } |
| 345 | + else if ((strncasecmp(ext, "jpeg", 4) == 0) || (strncasecmp(ext, "jpg", 3) == 0)) { |
| 346 | + tex = Textures::LoadImageBufferJPEG(data, size); |
| 347 | + } |
| 348 | + else if (strncasecmp(ext, "png", 3) == 0) { |
| 349 | + tex = Textures::LoadImageBufferPNG(data, size); |
| 350 | + } |
| 351 | + else if ((strncasecmp(ext, "pgm", 3) == 0) || (strncasecmp(ext, "ppm", 3) == 0) || (strncasecmp(ext, "psd", 3) == 0) |
| 352 | + || (strncasecmp(ext, "tga", 3) == 0)) { |
| 353 | + tex = Textures::LoadImageBuffer(data, size); |
| 354 | + } |
267 | 355 | } |
268 | 356 |
|
269 | 357 | std::free(data); |
|
0 commit comments