#include "SceTypes.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include "Decoder/Jpeg.hpp" #include #include #include #include #include extern "C" { std::int32_t APS5_VABI sceJpegDecQueryMemorySize(const JpegDecCreateParam*); std::int32_t APS5_VABI sceJpegDecCreate(const JpegDecCreateParam*, void*, std::uint32_t, void**); std::int32_t APS5_VABI sceJpegDecDelete(void*); std::int32_t APS5_VABI sceJpegDecParseHeader(const JpegDecParseParam*, JpegDecImageInfo*); std::int32_t APS5_VABI sceJpegDecDecode(void*, const JpegDecDecodeParam*, JpegDecImageInfo*); } static void Require(bool value) { if (!value) std::abort(); } static std::vector TestJpeg(std::uint32_t width, std::uint32_t height) { std::vector rgb(static_cast(width) * height * 3); for (std::size_t i = 0; i < rgb.size(); ++i) rgb[i] = static_cast(10 + i * 13); return Decoder::Jpeg::Encode(rgb, width, height, 3, 90); } static JpegDecDecodeParam DecodeParam(const std::vector& jpeg, std::vector& image) { JpegDecDecodeParam param{}; param.jpeg_mem_addr = jpeg.data(); param.image_mem_addr = image.data(); param.jpeg_mem_size = static_cast(jpeg.size()); param.image_mem_size = static_cast(image.size()); param.pixel_format = 0; param.reserved0 = 0; param.image_pitch = 0; return param; } int main() { constexpr std::int32_t invalidAddr = static_cast(0x80690001); constexpr std::int32_t invalidSize = static_cast(0x80690002); constexpr std::int32_t invalidParam = static_cast(0x80690003); constexpr std::int32_t invalidHandle = static_cast(0x80690004); constexpr std::int32_t invalidWorkMemory = static_cast(0x80690005); constexpr std::int32_t invalidData = static_cast(0x80690010); const JpegDecCreateParam param{sizeof(JpegDecCreateParam), 0}; const std::int32_t memorySize = sceJpegDecQueryMemorySize(¶m); Require(memorySize > 0); Require(sceJpegDecQueryMemorySize(nullptr) == invalidParam); const JpegDecCreateParam badSize{sizeof(JpegDecCreateParam) - 1, 0}; Require(sceJpegDecQueryMemorySize(&badSize) == invalidSize); const JpegDecCreateParam badAttribute{sizeof(JpegDecCreateParam), 1}; Require(sceJpegDecQueryMemorySize(&badAttribute) == invalidParam); std::vector memory(static_cast(memorySize) + 8); void* handle = nullptr; Require(sceJpegDecCreate(¶m, memory.data(), 0, &handle) == invalidWorkMemory); Require(sceJpegDecCreate(¶m, memory.data(), static_cast(memorySize), nullptr) == invalidAddr); Require(sceJpegDecCreate(¶m, memory.data(), static_cast(memorySize), &handle) == 0); Require(handle != nullptr); Require(sceJpegDecDelete(nullptr) == invalidHandle); Require(sceJpegDecDelete(handle) == 0); Require(sceJpegDecCreate(¶m, memory.data(), static_cast(memorySize), &handle) == 0); const std::vector jpeg = TestJpeg(7, 5); JpegDecImageInfo info{}; const JpegDecParseParam parseParam{jpeg.data(), static_cast(jpeg.size()), 0}; Require(sceJpegDecParseHeader(nullptr, &info) == invalidParam); Require(sceJpegDecParseHeader(&parseParam, nullptr) == invalidAddr); const JpegDecParseParam emptyParam{nullptr, 0, 0}; Require(sceJpegDecParseHeader(&emptyParam, &info) == invalidAddr); Require(sceJpegDecParseHeader(&parseParam, &info) == 0); Require(info.image_width == 7); Require(info.image_height == 5); std::vector image(7 * 5 * 4, 0xCC); JpegDecDecodeParam decodeParam = DecodeParam(jpeg, image); Require(sceJpegDecDecode(nullptr, &decodeParam, &info) == invalidHandle); Require(sceJpegDecDecode(handle, nullptr, &info) == invalidParam); JpegDecDecodeParam badFormat = decodeParam; badFormat.pixel_format = 2; Require(sceJpegDecDecode(handle, &badFormat, &info) == invalidParam); const std::int32_t packed = sceJpegDecDecode(handle, &decodeParam, &info); Require(packed == static_cast(7 << 16 | 5)); Require(info.image_width == 7); Require(info.image_height == 5); Require(image[3] == 0xFF); std::vector bgra(7 * 5 * 4, 0); JpegDecDecodeParam bgraParam = DecodeParam(jpeg, bgra); bgraParam.pixel_format = 1; Require(sceJpegDecDecode(handle, &bgraParam, nullptr) == static_cast(7 << 16 | 5)); Require(bgra[0] == image[2]); Require(bgra[2] == image[0]); const std::vector garbage{0x00, 0x01, 0x02, 0x03}; JpegDecParseParam garbageParam{garbage.data(), static_cast(garbage.size()), 0}; Require(sceJpegDecParseHeader(&garbageParam, &info) == invalidData); std::vector garbageOut(64, 0); JpegDecDecodeParam garbageDecode = DecodeParam(garbage, garbageOut); Require(sceJpegDecDecode(handle, &garbageDecode, &info) == invalidData); Require(sceJpegDecDelete(handle) == 0); return 0; }