feat(libSceJxr): implement pixel format lookup

This commit is contained in:
Kraken authored and Adrià Franch committed 2026-10-26 13:34:43 +01:00
1 parent 2cce8bc51d
commit 5aa1f6fd44
12 files changed
+447 -10

No files matched your search

+3
View File
@@ -61,3 +61,6 @@
[submodule "3rdparty/vorbis"]
path = 3rdparty/vorbis
url = https://github.com/xiph/vorbis.git
[submodule "3rdparty/jxrlib"]
path = 3rdparty/jxrlib
url = https://github.com/4creators/jxrlib.git
Vendored Submodule
+1
Submodule 3rdparty/jxrlib added at f752187986.
+1
View File
@@ -385,6 +385,7 @@ set_target_properties(usb-1.0 PROPERTIES POSITION_INDEPENDENT_CODE ON)
include(cmake/ZArchive.cmake)
include(cmake/Opus.cmake)
include(cmake/Jxr.cmake)
if(WIN32)
set(MI_BUILD_SHARED ON CACHE BOOL "" FORCE)
set(MI_BUILD_STATIC OFF CACHE BOOL "" FORCE)
+43
View File
@@ -0,0 +1,43 @@
enable_language(C)
set(JXR_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/jxrlib)
function(configure_jxr_native target)
target_include_directories(${target} SYSTEM PRIVATE
${JXR_SOURCE_DIR}/common/include ${JXR_SOURCE_DIR}/image/sys ${JXR_SOURCE_DIR}/jxrgluelib)
target_compile_definitions(${target} PRIVATE DISABLE_PERF_MEASUREMENT)
if(WIN32)
target_compile_definitions(${target} PRIVATE WIN32 __in=)
target_compile_options(${target} PRIVATE -include ${JXR_SOURCE_DIR}/image/sys/strcodec.h)
else()
target_compile_definitions(${target} PRIVATE __ANSI__)
endif()
set_target_properties(${target} PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON C_VISIBILITY_PRESET hidden)
endfunction()
add_library(jxr STATIC EXCLUDE_FROM_ALL
${JXR_SOURCE_DIR}/image/sys/adapthuff.c
${JXR_SOURCE_DIR}/image/sys/image.c
${JXR_SOURCE_DIR}/image/sys/strcodec.c
${JXR_SOURCE_DIR}/image/sys/strPredQuant.c
${JXR_SOURCE_DIR}/image/sys/strTransform.c
${JXR_SOURCE_DIR}/image/decode/decode.c
${JXR_SOURCE_DIR}/image/decode/JXRTranscode.c
${JXR_SOURCE_DIR}/image/decode/postprocess.c
${JXR_SOURCE_DIR}/image/decode/segdec.c
${JXR_SOURCE_DIR}/image/decode/strdec.c
${JXR_SOURCE_DIR}/image/decode/strInvTransform.c
${JXR_SOURCE_DIR}/image/decode/strPredQuantDec.c
${JXR_SOURCE_DIR}/image/encode/encode.c
${JXR_SOURCE_DIR}/image/encode/segenc.c
${JXR_SOURCE_DIR}/image/encode/strenc.c
${JXR_SOURCE_DIR}/image/encode/strFwdTransform.c
${JXR_SOURCE_DIR}/image/encode/strPredQuantEnc.c
${JXR_SOURCE_DIR}/jxrgluelib/JXRGlue.c
${JXR_SOURCE_DIR}/jxrgluelib/JXRGlueJxr.c
${JXR_SOURCE_DIR}/jxrgluelib/JXRGluePFC.c
${JXR_SOURCE_DIR}/jxrgluelib/JXRMeta.c)
configure_jxr_native(jxr)
if(UNIX)
target_link_libraries(jxr PRIVATE m)
endif()
+31 -1
View File
@@ -1,8 +1,38 @@
add_library(libSceJxr SHARED EXCLUDE_FROM_ALL Export.cpp)
add_library(jxr_lookup_native STATIC src/NativeLookup.c)
configure_jxr_native(jxr_lookup_native)
target_include_directories(jxr_lookup_native PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(jxr_lookup_native PRIVATE jxr)
add_library(libSceJxr SHARED EXCLUDE_FROM_ALL Export.cpp src/PixelFormatLookup.cpp)
target_link_libraries(libSceJxr PRIVATE jxr_lookup_native)
if(NOT APPLE)
target_link_options(libSceJxr PRIVATE LINKER:--exclude-libs,ALL)
endif()
target_include_directories(libSceJxr PRIVATE ${LIBS_INCLUDE_DIR})
configure_windows_unwind(libSceJxr)
if(BUILD_TESTING)
add_library(jxr_lookup_reference STATIC ${LIBS_INCLUDE_DIR}/tests/GuestJxrLookupReference.c)
configure_jxr_native(jxr_lookup_reference)
target_link_libraries(jxr_lookup_reference PRIVATE jxr)
add_test_executable(guest_jxr_lookup_tests ${LIBS_INCLUDE_DIR}/tests/GuestJxrLookup.cpp)
target_include_directories(guest_jxr_lookup_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_jxr_lookup_tests PRIVATE jxr_lookup_reference ${CMAKE_DL_LIBS})
if(WIN32)
target_link_libraries(guest_jxr_lookup_tests PRIVATE libc)
endif()
configure_windows_unwind(guest_jxr_lookup_tests)
add_custom_target(jxr_lookup_patched DEPENDS ${PATCHED_DIR}/libSceJxr.prx ${LIBC_PATCHED})
add_dependencies(guest_jxr_lookup_tests jxr_lookup_patched)
add_test(NAME guest_jxr_lookup_reference COMMAND guest_jxr_lookup_tests reference)
add_test(NAME guest_jxr_lookup COMMAND guest_jxr_lookup_tests $<TARGET_FILE:libSceJxr> raw)
add_test(NAME guest_jxr_lookup_patched COMMAND guest_jxr_lookup_tests ${PATCHED_DIR}/libSceJxr.prx patched)
set_tests_properties(guest_jxr_lookup_reference guest_jxr_lookup guest_jxr_lookup_patched PROPERTIES TIMEOUT 20)
if(WIN32)
set_tests_properties(guest_jxr_lookup_reference guest_jxr_lookup PROPERTIES
ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceJxr>")
set_tests_properties(guest_jxr_lookup_patched PROPERTIES
ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:${PATCHED_DIR}")
endif()
add_test_executable(guest_jxr_tests ${LIBS_INCLUDE_DIR}/tests/GuestJxr.cpp)
target_include_directories(guest_jxr_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_jxr_tests PRIVATE libSceJxr libc)
-5
View File
@@ -24,11 +24,6 @@ std::int64_t APS5_VABI PKFree_nid_postfix(void** memory) {
return WmpErrSuccess;
}
int APS5_VABI PixelFormatLookup_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::int64_t APS5_VABI readIS_nid_postfix(void*, Jxr::BitIo* io) {
if (!io) NotImplemented_nid_no_patch(__func__);
constexpr std::uintptr_t packetSize = 4096;
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
typedef struct JxrPixelInfo {
const void* guid;
uint64_t channels;
int32_t colorFormat;
int32_t bitDepth;
uint32_t bitsPerUnit;
uint64_t flags;
uint32_t interpretation;
uint32_t samplesPerPixel;
uint32_t bitsPerSample;
uint32_t sampleFormat;
} JxrPixelInfo;
@@ -0,0 +1,40 @@
#include "strcodec.h"
#include "JXRGlue.h"
#include "prx/libSceJxr/GuestPixelInfo.h"
#include <stddef.h>
#include <string.h>
_Static_assert(sizeof(GUID) == 16, "GUID size");
_Static_assert(sizeof(COLORFORMAT) == 4 && sizeof(BITDEPTH_BITS) == 4, "enum size");
_Static_assert(sizeof(U32) == 4 && sizeof(JxrPixelInfo) == 56, "pixel info layout");
_Static_assert(offsetof(JxrPixelInfo, flags) == 32 && offsetof(JxrPixelInfo, interpretation) == 40, "LP64 offsets");
int64_t JxrLookup_nid_no_patch(JxrPixelInfo* value, uint8_t mode) {
PKPixelInfo native = {0};
GUID guid;
ERR result;
if (mode > LOOKUP_BACKWARD_TIF) return PixelFormatLookup(NULL, mode);
if (mode == LOOKUP_FORWARD) {
memcpy(&guid, value->guid, sizeof(guid));
native.pGUIDPixFmt = &guid;
} else {
native.grBit = (WMP_GRBIT)value->flags;
native.uInterpretation = value->interpretation;
native.uSamplePerPixel = value->samplesPerPixel;
native.uBitsPerSample = value->bitsPerSample;
native.uSampleFormat = value->sampleFormat;
}
result = PixelFormatLookup(&native, mode);
if (result != WMP_errSuccess) return result;
value->guid = native.pGUIDPixFmt;
value->channels = native.cChannel;
value->colorFormat = native.cfColorFormat;
value->bitDepth = native.bdBitDepth;
value->bitsPerUnit = native.cbitUnit;
value->flags = native.grBit;
value->interpretation = native.uInterpretation;
value->samplesPerPixel = native.uSamplePerPixel;
value->bitsPerSample = native.uBitsPerSample;
value->sampleFormat = native.uSampleFormat;
return result;
}
@@ -0,0 +1,31 @@
#include "prx/libSceJxr/GuestPixelInfo.h"
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <stdexcept>
extern "C" std::int64_t JxrLookup_nid_no_patch(JxrPixelInfo* value, std::uint8_t mode);
static_assert(sizeof(JxrPixelInfo) == 56 && alignof(JxrPixelInfo) == 8);
static_assert(offsetof(JxrPixelInfo, flags) == 32 && offsetof(JxrPixelInfo, interpretation) == 40);
extern "C" std::int64_t APS5_VABI PixelFormatLookup_nid_postfix(JxrPixelInfo* value, std::uint8_t mode) {
if (mode > 1) return JxrLookup_nid_no_patch(nullptr, mode);
if (value == nullptr) throw std::invalid_argument("PixelFormatLookup: null record behavior is unknown");
JxrPixelInfo local{};
auto* bytes = reinterpret_cast<std::byte*>(value);
if (mode == 0) {
std::memcpy(&local.guid, bytes, sizeof(local.guid));
if (local.guid == nullptr) throw std::invalid_argument("PixelFormatLookup: null GUID behavior is unknown");
} else {
std::memcpy(&local.flags, bytes + offsetof(JxrPixelInfo, flags), sizeof(local.flags));
std::memcpy(&local.interpretation, bytes + offsetof(JxrPixelInfo, interpretation), 4 * sizeof(std::uint32_t));
}
const auto result = JxrLookup_nid_no_patch(&local, mode);
if (result == 0) {
std::memcpy(bytes, &local, offsetof(JxrPixelInfo, bitsPerUnit) + sizeof(local.bitsPerUnit));
std::memcpy(bytes + offsetof(JxrPixelInfo, flags), &local.flags, sizeof(local) - offsetof(JxrPixelInfo, flags));
}
return result;
}
+249
View File
@@ -0,0 +1,249 @@
#include "prx/libSceJxr/GuestPixelInfo.h"
#include "prx/libc/include/general/VabiMacros.hpp"
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <stdexcept>
#include <thread>
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#include <sys/mman.h>
#include <unistd.h>
#endif
extern "C" int JxrReferenceCase_nid_no_patch(std::uint8_t, int, int, std::uint8_t*, std::uint64_t*);
using Query = std::int64_t (APS5_VABI*)(JxrPixelInfo*, std::uint8_t);
static_assert(sizeof(JxrPixelInfo) == 56 && alignof(JxrPixelInfo) == 8);
static_assert(offsetof(JxrPixelInfo, guid) == 0 && offsetof(JxrPixelInfo, channels) == 8);
static_assert(offsetof(JxrPixelInfo, colorFormat) == 16 && offsetof(JxrPixelInfo, bitDepth) == 20);
static_assert(offsetof(JxrPixelInfo, bitsPerUnit) == 24 && offsetof(JxrPixelInfo, flags) == 32);
static_assert(offsetof(JxrPixelInfo, interpretation) == 40 && offsetof(JxrPixelInfo, sampleFormat) == 52);
namespace {
void Require(bool condition, const char* message) {
if (condition) return;
std::fprintf(stderr, "JXR lookup: %s\n", message);
std::exit(1);
}
struct Reference {
std::array<std::uint8_t, 16> guid{};
std::array<std::uint64_t, 9> fields{};
};
bool ReadReference(unsigned hash, bool reverse, bool white, Reference& expected) {
const auto result = JxrReferenceCase_nid_no_patch(static_cast<std::uint8_t>(hash), reverse, white,
expected.guid.data(), expected.fields.data());
Require(result >= 0, "native lookup reference failed");
return result != 0;
}
JxrPixelInfo BackwardInput(const Reference& source) {
JxrPixelInfo input{};
input.guid = reinterpret_cast<void*>(std::uintptr_t{1});
input.channels = UINT64_MAX;
input.colorFormat = -1;
input.bitDepth = -1;
input.bitsPerUnit = UINT32_MAX;
input.flags = source.fields[4] | UINT64_C(0xfedcba9880000040);
input.interpretation = static_cast<std::uint32_t>(source.fields[5]);
input.samplesPerPixel = static_cast<std::uint32_t>(source.fields[6]);
input.bitsPerSample = static_cast<std::uint32_t>(source.fields[7]);
input.sampleFormat = static_cast<std::uint32_t>(source.fields[8]);
return input;
}
void CheckValue(const JxrPixelInfo& actual, const Reference& expected) {
const std::array<std::uint64_t, 9> fields{{actual.channels, static_cast<std::uint32_t>(actual.colorFormat),
static_cast<std::uint32_t>(actual.bitDepth), actual.bitsPerUnit, actual.flags, actual.interpretation,
actual.samplesPerPixel, actual.bitsPerSample, actual.sampleFormat}};
Require(fields == expected.fields, "metadata differs from pinned native reference");
Require(actual.guid != nullptr, "successful lookup returned null GUID");
Require(std::memcmp(actual.guid, expected.guid.data(), 16) == 0, "GUID differs from pinned native reference");
}
class GuardedTail {
void* memory;
std::size_t page;
void* data;
public:
GuardedTail(const void* source, std::size_t bytes) {
#ifdef _WIN32
SYSTEM_INFO info;
GetSystemInfo(&info);
page = info.dwPageSize;
memory = VirtualAlloc(nullptr, page * 2, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
Require(memory != nullptr, "guard allocation");
DWORD previous;
Require(VirtualProtect(static_cast<unsigned char*>(memory) + page, page, PAGE_NOACCESS, &previous) != 0, "guard protection");
#else
page = static_cast<std::size_t>(sysconf(_SC_PAGESIZE));
memory = mmap(nullptr, page * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Require(memory != MAP_FAILED, "guard allocation");
Require(mprotect(static_cast<unsigned char*>(memory) + page, page, PROT_NONE) == 0, "guard protection");
#endif
Require(bytes <= page, "guard fixture size");
data = static_cast<unsigned char*>(memory) + page - bytes;
std::memcpy(data, source, bytes);
}
void ReadOnly() {
#ifdef _WIN32
DWORD previous;
Require(VirtualProtect(memory, page, PAGE_READONLY, &previous) != 0, "read-only protection");
#else
Require(mprotect(memory, page, PROT_READ) == 0, "read-only protection");
#endif
}
~GuardedTail() {
#ifdef _WIN32
VirtualFree(memory, 0, MEM_RELEASE);
#else
munmap(memory, page * 2);
#endif
}
template<class T> T* As() const { return static_cast<T*>(data); }
};
void Cases(Query query) {
Require(query(nullptr, 2) == -106, "invalid mode has signed 64-bit unsupported-format result");
Reference forward;
unsigned formats = 0;
for (unsigned hash = 0; hash < 256; ++hash) {
if (!ReadReference(hash, false, false, forward)) continue;
++formats;
JxrPixelInfo input;
std::memset(&input, 0xa5, sizeof(input));
input.guid = forward.guid.data();
const auto originalGuid = forward.guid;
Require(query(&input, 0) == 0, "forward lookup");
CheckValue(input, forward);
Require(forward.guid == originalGuid, "lookup modified input GUID");
Reference backward;
Require(ReadReference(hash, true, false, backward), "backward native case missing");
input = BackwardInput(forward);
Require(query(&input, 1) == 0, "backward lookup ignores GUID and high flag bits");
CheckValue(input, backward);
}
Require(formats != 0, "reference format inventory empty");
Reference white;
Require(ReadReference(5, false, false, forward), "black-white reference");
Require(ReadReference(5, true, true, white), "white-is-zero reference");
Require(forward.fields[5] == 1 && white.fields[5] == 0, "duplicate GUID reference order");
auto input = BackwardInput(forward);
input.interpretation = 0;
Require(query(&input, 1) == 0, "backward white-is-zero lookup");
CheckValue(input, white);
Require(query(&input, 0) == 0, "forward lookup selects first duplicate GUID");
CheckValue(input, forward);
for (unsigned mode = 2; mode < 256; ++mode) {
std::memset(&input, 0xa5, sizeof(input));
std::array<std::byte, sizeof(input)> before;
std::memcpy(before.data(), &input, sizeof(input));
Require(query(&input, static_cast<std::uint8_t>(mode)) == -106, "invalid mode error");
Require(std::memcmp(&input, before.data(), sizeof(input)) == 0, "invalid mode changed record");
Require(query(reinterpret_cast<JxrPixelInfo*>(std::uintptr_t{1}), static_cast<std::uint8_t>(mode)) == -106,
"invalid mode must not read inaccessible record");
}
std::array<std::uint8_t, 16> unknown{};
std::memset(&input, 0xff, sizeof(input));
input.guid = unknown.data();
std::array<std::byte, sizeof(input)> before;
std::memcpy(before.data(), &input, sizeof(input));
Require(query(&input, 0) == -106 && std::memcmp(&input, before.data(), sizeof(input)) == 0, "unknown GUID unchanged");
Require(query(&input, 1) == -106 && std::memcmp(&input, before.data(), sizeof(input)) == 0, "unknown TIFF fields unchanged");
GuardedTail failedRecord(&input, sizeof(input));
failedRecord.ReadOnly();
Require(query(failedRecord.As<JxrPixelInfo>(), 0) == -106, "failed lookup does not write read-only record");
const void* unknownPointer = unknown.data();
GuardedTail failedPrefix(&unknownPointer, sizeof(unknownPointer));
failedPrefix.ReadOnly();
Require(query(failedPrefix.As<JxrPixelInfo>(), 0) == -106, "failed forward lookup only reads GUID pointer");
Require(ReadReference(8, false, false, forward), "Gray8 reference");
Require(forward.fields[0] == 1 && forward.fields[7] == 8, "Gray8 reference values");
GuardedTail guid(forward.guid.data(), 16);
guid.ReadOnly();
input = {};
input.guid = guid.As<void>();
GuardedTail record(&input, sizeof(input));
Require(query(record.As<JxrPixelInfo>(), 0) == 0, "bounded record and read-only GUID");
CheckValue(*record.As<JxrPixelInfo>(), forward);
input = BackwardInput(forward);
input.guid = nullptr;
Require(query(&input, 1) == 0, "backward lookup ignores null GUID");
CheckValue(input, forward);
alignas(16) std::array<std::uint8_t, 17> unalignedGuid{};
std::memcpy(unalignedGuid.data() + 1, forward.guid.data(), 16);
input = {};
input.guid = unalignedGuid.data() + 1;
Require(query(&input, 0) == 0, "unaligned GUID lookup");
CheckValue(input, forward);
const auto borrowedGuid = record.As<JxrPixelInfo>()->guid;
std::array<std::thread, 4> threads;
for (auto& thread : threads) thread = std::thread([&] {
for (unsigned i = 0; i < 32; ++i) {
JxrPixelInfo value{};
value.guid = forward.guid.data();
Require(query(&value, 0) == 0, "concurrent independent lookup");
CheckValue(value, forward);
Require(value.guid == borrowedGuid, "borrowed GUID pointer changed across calls");
}
});
for (auto& thread : threads) thread.join();
for (const bool nullGuid : {false, true}) {
bool threw = false;
input = {};
try { query(nullGuid ? &input : nullptr, 0); } catch (const std::invalid_argument&) { threw = true; }
Require(threw, "valid-mode null record/GUID is explicitly unsupported");
}
bool threw = false;
try { query(nullptr, 1); } catch (const std::invalid_argument&) { threw = true; }
Require(threw, "backward null record is explicitly unsupported");
std::printf("JXR guest lookup cases passed across %u reference hashes\n", formats);
}
}
int main(int argc, char** argv) {
#ifdef _WIN32
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#endif
try {
if (argc == 2 && std::strcmp(argv[1], "reference") == 0) {
Reference gray;
Require(ReadReference(8, false, false, gray) && gray.fields[0] == 1 && gray.fields[7] == 8, "native Gray8 reference");
unsigned formats = 0;
for (unsigned hash = 0; hash < 256; ++hash) { Reference item; if (ReadReference(hash, false, false, item)) ++formats; }
std::printf("Pinned native JXR reference passed with %u hashes\n", formats);
return 0;
}
Require(argc == 3, "expected library and export mode");
const char* name = std::strcmp(argv[2], "patched") == 0 ? "5Gjz1nLOKvo" : "PixelFormatLookup_nid_postfix";
#ifdef _WIN32
const auto library = LoadLibraryA(argv[1]);
Require(library != nullptr, "load requested library");
const auto query = reinterpret_cast<Query>(GetProcAddress(library, name));
#else
const auto library = dlopen(argv[1], RTLD_NOW | RTLD_LOCAL);
Require(library != nullptr, "load requested library");
const auto query = reinterpret_cast<Query>(dlsym(library, name));
#endif
Require(query != nullptr, "missing lookup export");
Cases(query);
#ifdef _WIN32
FreeLibrary(library);
#else
dlclose(library);
#endif
return 0;
} catch (const std::exception& error) {
std::fprintf(stderr, "JXR lookup exception: %s\n", error.what());
return 1;
}
}
+31
View File
@@ -0,0 +1,31 @@
#include "strcodec.h"
#include "JXRGlue.h"
#include <stdint.h>
#include <string.h>
_Static_assert(sizeof(GUID) == 16, "GUID size");
_Static_assert(sizeof(U32) == 4, "U32 size");
int JxrReferenceCase_nid_no_patch(uint8_t hash, int reverse, int white, uint8_t* guid, uint64_t* fields) {
PKPixelInfo native = {0};
native.pGUIDPixFmt = GetPixelFormatFromHash(hash);
if (!native.pGUIDPixFmt) return 0;
if (PixelFormatLookup(&native, LOOKUP_FORWARD) != 0) return -1;
if (reverse) {
native.pGUIDPixFmt = NULL;
native.grBit |= PK_pixfmtBGR | PK_pixfmtNeedConvert;
if (white) native.uInterpretation = 0;
if (PixelFormatLookup(&native, LOOKUP_BACKWARD_TIF) != 0) return -1;
}
memcpy(guid, native.pGUIDPixFmt, 16);
fields[0] = native.cChannel;
fields[1] = native.cfColorFormat;
fields[2] = native.bdBitDepth;
fields[3] = native.cbitUnit;
fields[4] = native.grBit;
fields[5] = native.uInterpretation;
fields[6] = native.uSamplePerPixel;
fields[7] = native.uBitsPerSample;
fields[8] = native.uSampleFormat;
return 1;
}
+2 -4
View File
@@ -1,11 +1,9 @@
# libSceJxr technical debt
### Unknown function info
- [PixelFormatLookup](../../../core/libs/prx/libSceJxr/Export.cpp) is listed in the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceJxr.c) and was cross-checked against firmware 13.60. Its signature and behaviour remain unverified; the declaration uses the no-parameter unknown-signature convention and throws through `NotImplemented_nid_no_patch`.
### Functional
- [PixelFormatLookup](../../../core/libs/prx/libSceJxr/src/PixelFormatLookup.cpp) uses the pinned public jxrlib table and lookup algorithm through a C bridge. The signed 64-bit result and 56-byte LP64 pixel-info model, 16-byte GUID, 32-bit enums and TIFF fields, module/library versions and Sony table/configuration equivalence are inferred or unknown, not console-measured. Modes 0/1 follow forward GUID/reverse TIFF lookup; other modes and misses return the public unsupported-format error without modifying the record. Valid-mode null records and forward null GUIDs throw because console behavior is unknown. Success returns a borrowed read-only static GUID valid while the module remains loaded; the caller must not free it. Closes when: Sony prototypes, layouts, configuration, table and invalid-argument behavior are verified by attributable disassembly or console measurements
- [PKFree](../../../core/libs/prx/libSceJxr/Export.cpp) (libSceJxr) follows Microsoft's jxrlib [JXRGlue.c](https://github.com/4creators/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/jxrgluelib/JXRGlue.c#L53-L62), whose four exported names the module shares: a non-null `ppv` has `*ppv` released with the guest `free` and set to null, and the result is always `WMP_errSuccess` (0) as a 64-bit `ERR` (`long`). That the console's module is built from jxrlib, and that its `PKFree` releases through libc's `free`, is inferred from the export names and not checked against the console's code. Closes when: the console's `PKFree` is disassembled or measured on a PS5
- [readIS and writeIS](../../../core/libs/prx/libSceJxr/Export.cpp) use the non-ARM, LP64 `BitIOInfo` and `WMPStream` ABI and packet algorithm from [Microsoft's JPEG XR reference implementation](https://github.com/4creators/jxrlib/blob/f7521879862b9085318e814c6157490dd9dbbdb4/image/sys/strcodec.c#L1090-L1177). Console structure layouts and execution remain unverified. Profiling callbacks are omitted as in the reference Unix build with `DISABLE_PERF_MEASUREMENT`; the codec argument is unused. Invalid null state or required callbacks throw instead of dereferencing them. No codec is instantiated by these helpers; callers must supply the reference ring buffer and guest-ABI stream callbacks.