Support UTF8 to UTF16 LE

This commit is contained in:
2026-03-31 14:10:21 +11:00
parent 0c24096c80
commit 70be68d0fc
14 changed files with 790 additions and 11 deletions

View File

@@ -750,6 +750,103 @@ extern "C" ANSFR_API double BlurCalculation(unsigned char* jpeg_string, un
}
// Unicode conversion utilities for LabVIEW wrapper classes
extern "C" ANSFR_API int ANSFR_ConvertUTF8ToUTF16LE(const char* utf8Str, LStrHandle result) {
try {
if (!utf8Str || !result) return -1;
int len = (int)strlen(utf8Str);
if (len == 0) return 0;
bool hasUnicodeEscapes = false;
bool hasNonAscii = false;
for (int i = 0; i < len; i++) {
if ((unsigned char)utf8Str[i] >= 0x80) hasNonAscii = true;
if (i + 1 < len && utf8Str[i] == '\\' && utf8Str[i + 1] == 'u') hasUnicodeEscapes = true;
}
if (!hasNonAscii && !hasUnicodeEscapes) {
MgErr error = DSSetHandleSize(result, sizeof(int32) + len * sizeof(uChar));
if (error != noErr) return -2;
(*result)->cnt = len;
memcpy((*result)->str, utf8Str, len);
return 1;
}
if (hasUnicodeEscapes) {
std::string utf16le;
utf16le.reserve(len * 2);
for (int i = 0; i < len; ) {
if (i + 5 < len && utf8Str[i] == '\\' && utf8Str[i + 1] == 'u') {
char hex[5] = { utf8Str[i + 2], utf8Str[i + 3], utf8Str[i + 4], utf8Str[i + 5], 0 };
uint16_t cp = (uint16_t)strtoul(hex, nullptr, 16);
utf16le += static_cast<char>(cp & 0xFF);
utf16le += static_cast<char>((cp >> 8) & 0xFF);
i += 6;
} else {
utf16le += utf8Str[i];
utf16le += '\0';
i++;
}
}
int size = (int)utf16le.size();
MgErr error = DSSetHandleSize(result, sizeof(int32) + size * sizeof(uChar));
if (error != noErr) return -2;
(*result)->cnt = size;
memcpy((*result)->str, utf16le.data(), size);
return 1;
}
#ifdef _WIN32
int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str, len, nullptr, 0);
if (wideLen <= 0) return 0;
std::wstring wideStr(wideLen, 0);
MultiByteToWideChar(CP_UTF8, 0, utf8Str, len, &wideStr[0], wideLen);
int size = wideLen * (int)sizeof(wchar_t);
MgErr error = DSSetHandleSize(result, sizeof(int32) + size * sizeof(uChar));
if (error != noErr) return -2;
(*result)->cnt = size;
memcpy((*result)->str, wideStr.data(), size);
return 1;
#else
return 0;
#endif
}
catch (...) { return -1; }
}
extern "C" ANSFR_API int ANSFR_ConvertUTF16LEToUTF8(const unsigned char* utf16leBytes, int byteLen, LStrHandle result) {
try {
if (!utf16leBytes || byteLen <= 0 || !result) return -1;
bool isUtf16le = (byteLen >= 2 && byteLen % 2 == 0);
if (isUtf16le) {
bool isAscii = true;
for (int i = 1; i < byteLen; i += 2) {
if (utf16leBytes[i] != 0x00) { isAscii = false; break; }
}
if (isAscii) {
int asciiLen = byteLen / 2;
MgErr error = DSSetHandleSize(result, sizeof(int32) + asciiLen * sizeof(uChar));
if (error != noErr) return -2;
(*result)->cnt = asciiLen;
for (int i = 0; i < asciiLen; i++) (*result)->str[i] = utf16leBytes[i * 2];
return 1;
}
}
#ifdef _WIN32
int wideLen = byteLen / (int)sizeof(wchar_t);
const wchar_t* wideStr = reinterpret_cast<const wchar_t*>(utf16leBytes);
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr, wideLen, nullptr, 0, nullptr, nullptr);
if (utf8Len <= 0) return 0;
std::string utf8Str(utf8Len, 0);
WideCharToMultiByte(CP_UTF8, 0, wideStr, wideLen, &utf8Str[0], utf8Len, nullptr, nullptr);
MgErr error = DSSetHandleSize(result, sizeof(int32) + utf8Len * sizeof(uChar));
if (error != noErr) return -2;
(*result)->cnt = utf8Len;
memcpy((*result)->str, utf8Str.data(), utf8Len);
return 1;
#else
return 0;
#endif
}
catch (...) { return -1; }
}
extern "C" ANSFR_API int UpdateParameters(ANSCENTER::ANSFacialRecognition** Handle, float knownPersonThreshold, int enableAgeGender, int enableFaceEmotions, int enableHeadPose, int minFaceSize, float faceDetectorThreshold, int enableFaceliveness, int antiSpoof, int removeFakeFaces) {
try {
if (!Handle || !*Handle) return -1;