// Copyright 2023 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #define DDSKTX_IMPLEMENT #include #include #include "common/file_util.h" #include "common/logging/log.h" #include "core/frontend/image_interface.h" namespace Frontend { bool ImageInterface::DecodePNG(std::vector& dst, u32& width, u32& height, std::span src) { const u32 lodepng_ret = lodepng::decode(dst, width, height, src.data(), src.size()); if (lodepng_ret) { LOG_ERROR(Frontend, "Failed to decode because {}", lodepng_error_text(lodepng_ret)); return false; } return true; } bool ImageInterface::DecodeDDS(std::vector& dst, u32& width, u32& height, ddsktx_format& format, std::span src) { ddsktx_texture_info tc{}; const int size = static_cast(src.size()); if (!ddsktx_parse(&tc, src.data(), size, nullptr)) { LOG_ERROR(Frontend, "Failed to decode"); return false; } width = tc.width; height = tc.height; format = tc.format; ddsktx_sub_data sub_data{}; ddsktx_get_sub(&tc, &sub_data, src.data(), size, 0, 0, 0); dst.resize(sub_data.size_bytes); std::memcpy(dst.data(), sub_data.buff, sub_data.size_bytes); return true; } bool ImageInterface::EncodePNG(const std::string& path, u32 width, u32 height, std::span src) { std::vector out; const u32 lodepng_ret = lodepng::encode(out, src.data(), width, height); if (lodepng_ret) { LOG_ERROR(Frontend, "Failed to encode {} because {}", path, lodepng_error_text(lodepng_ret)); return false; } FileUtil::IOFile file{path, "wb"}; if (file.WriteBytes(out.data(), out.size()) != out.size()) { LOG_ERROR(Frontend, "Failed to save encode to path {}", path); return false; } return true; } } // namespace Frontend