Support UTF8 to UTF16 LE
This commit is contained in:
@@ -177,6 +177,60 @@ namespace ANSCENTER {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Helper: convert non-ASCII UTF-8 chars to literal \\uXXXX text so that
|
||||
// JSON parsers (e.g., LabVIEW) preserve them as displayable escape sequences.
|
||||
// Pure ASCII strings pass through unchanged (zero overhead).
|
||||
static std::string DoubleEscapeUnicode(const std::string& utf8Str) {
|
||||
bool hasNonAscii = false;
|
||||
for (unsigned char c : utf8Str) {
|
||||
if (c >= 0x80) { hasNonAscii = true; break; }
|
||||
}
|
||||
if (!hasNonAscii) return utf8Str;
|
||||
|
||||
std::string result;
|
||||
result.reserve(utf8Str.size() * 2);
|
||||
size_t i = 0;
|
||||
while (i < utf8Str.size()) {
|
||||
unsigned char c = static_cast<unsigned char>(utf8Str[i]);
|
||||
if (c < 0x80) {
|
||||
result += utf8Str[i++];
|
||||
} else {
|
||||
// Decode UTF-8 codepoint
|
||||
uint32_t cp = 0;
|
||||
if ((c & 0xE0) == 0xC0 && i + 1 < utf8Str.size()) {
|
||||
cp = ((c & 0x1F) << 6) | (static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F);
|
||||
i += 2;
|
||||
} else if ((c & 0xF0) == 0xE0 && i + 2 < utf8Str.size()) {
|
||||
cp = ((c & 0x0F) << 12) | ((static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F) << 6)
|
||||
| (static_cast<unsigned char>(utf8Str[i + 2]) & 0x3F);
|
||||
i += 3;
|
||||
} else if ((c & 0xF8) == 0xF0 && i + 3 < utf8Str.size()) {
|
||||
cp = ((c & 0x07) << 18) | ((static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F) << 12)
|
||||
| ((static_cast<unsigned char>(utf8Str[i + 2]) & 0x3F) << 6)
|
||||
| (static_cast<unsigned char>(utf8Str[i + 3]) & 0x3F);
|
||||
i += 4;
|
||||
} else {
|
||||
i++; continue; // skip invalid byte
|
||||
}
|
||||
// Encode as \\uXXXX (literal backslash + u + 4 hex digits)
|
||||
if (cp <= 0xFFFF) {
|
||||
char buf[8];
|
||||
snprintf(buf, sizeof(buf), "\\u%04x", cp);
|
||||
result += buf;
|
||||
} else {
|
||||
// Surrogate pair for codepoints > 0xFFFF
|
||||
cp -= 0x10000;
|
||||
uint16_t hi = 0xD800 + (uint16_t)(cp >> 10);
|
||||
uint16_t lo = 0xDC00 + (uint16_t)(cp & 0x3FF);
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "\\u%04x\\u%04x", hi, lo);
|
||||
result += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ANSCENTER::ANSOCRUtility::OCRDetectionToJsonString(const std::vector<OCRObject>& dets)
|
||||
{
|
||||
if (dets.empty()) {
|
||||
@@ -191,7 +245,7 @@ namespace ANSCENTER {
|
||||
results.push_back({
|
||||
{"class_id", std::to_string(det.classId)},
|
||||
{"track_id", std::to_string(det.trackId)},
|
||||
{"class_name", det.className},
|
||||
{"class_name", DoubleEscapeUnicode(det.className)},
|
||||
{"prob", std::to_string(det.confidence)},
|
||||
{"x", std::to_string(det.box.x)},
|
||||
{"y", std::to_string(det.box.y)},
|
||||
@@ -205,7 +259,6 @@ namespace ANSCENTER {
|
||||
});
|
||||
}
|
||||
|
||||
// ensure_ascii=true escapes non-ASCII chars as \uXXXX for LabVIEW compatibility
|
||||
return root.dump(-1, ' ', true);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
@@ -846,7 +899,7 @@ namespace ANSCENTER {
|
||||
jsonResults.push_back({
|
||||
{"class_id", "0"},
|
||||
{"track_id", "0"},
|
||||
{"class_name", res.fullPlateText},
|
||||
{"class_name", DoubleEscapeUnicode(res.fullPlateText)},
|
||||
{"prob", std::to_string(res.confidence)},
|
||||
{"x", std::to_string(res.plateBox.x)},
|
||||
{"y", std::to_string(res.plateBox.y)},
|
||||
|
||||
Reference in New Issue
Block a user