# HG changeset patch # User Sebastien Jodogne # Date 1783498655 -7200 # Node ID cb751bdccb15f5502ec79d562fdf91f2917763e0 # Parent 91b3be9a243a8fa77aeda9e2192fb6354ec463cf support of big endian architectures in DICOMweb diff -r 91b3be9a243a -r cb751bdccb15 OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Tue Jul 07 15:51:59 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Wed Jul 08 10:17:35 2026 +0200 @@ -417,6 +417,8 @@ const std::string& bulkDataUri, const std::vector& values) { + static const Endianness endianness = Toolbox::DetectEndianness(); + switch (mode) { case DicomWebJsonVisitor::BinaryMode_Ignore: @@ -438,14 +440,17 @@ if (!raw.empty()) { - assert(Toolbox::DetectEndianness() == Endianness_Little); // TODO - Add support for big endian - MemoryType *p = reinterpret_cast(&raw[0]); for (size_t i = 0; i < values.size(); i++, p++) { *p = static_cast(values[i]); } + + if (endianness == Endianness_Big) + { + Toolbox::SwapEndianness(raw, sizeof(MemoryType)); + } } std::string base64; diff -r 91b3be9a243a -r cb751bdccb15 OrthancFramework/Sources/Toolbox.cpp --- a/OrthancFramework/Sources/Toolbox.cpp Tue Jul 07 15:51:59 2026 +0200 +++ b/OrthancFramework/Sources/Toolbox.cpp Wed Jul 08 10:17:35 2026 +0200 @@ -313,6 +313,8 @@ pimpl_->md5_.get_digest(digest); target.resize(32); + +# if BOOST_ENDIAN_LITTLE_BYTE sprintf(&target[0], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", (digest[0] >> 0) & 0xFF, (digest[0] >> 8) & 0xFF, @@ -330,6 +332,25 @@ (digest[3] >> 8) & 0xFF, (digest[3] >> 16) & 0xFF, (digest[3] >> 24) & 0xFF); +# else + sprintf(&target[0], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + (digest[0] >> 24) & 0xFF, + (digest[0] >> 16) & 0xFF, + (digest[0] >> 8) & 0xFF, + (digest[0] >> 0) & 0xFF, + (digest[1] >> 24) & 0xFF, + (digest[1] >> 16) & 0xFF, + (digest[1] >> 8) & 0xFF, + (digest[1] >> 0) & 0xFF, + (digest[2] >> 24) & 0xFF, + (digest[2] >> 16) & 0xFF, + (digest[2] >> 8) & 0xFF, + (digest[2] >> 0) & 0xFF, + (digest[3] >> 24) & 0xFF, + (digest[3] >> 16) & 0xFF, + (digest[3] >> 8) & 0xFF, + (digest[3] >> 0) & 0xFF); +# endif # endif //BOOST_VERSION >= 108600 } @@ -3315,6 +3336,47 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Not a valid version: " + std::string(version)); } } + + + void Toolbox::SwapEndianness(void* data, + size_t dataSize, + size_t itemSize) + { + if (itemSize == 0 || + dataSize % itemSize != 0) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + if (itemSize != 1) + { + uint8_t* p = reinterpret_cast(data); + const size_t count = dataSize / itemSize; + + for (size_t i = 0; i < count; i++) + { + for (size_t b1 = 0; b1 < itemSize / 2; b1++) + { + size_t b2 = itemSize - 1 - b1; + uint8_t tmp = p[b1]; + p[b1] = p[b2]; + p[b2] = tmp; + } + + p += itemSize; + } + } + } + + + void Toolbox::SwapEndianness(std::string& buffer, + size_t itemSize) + { + if (!buffer.empty()) + { + SwapEndianness(&buffer[0], buffer.size(), itemSize); + } + } } diff -r 91b3be9a243a -r cb751bdccb15 OrthancFramework/Sources/Toolbox.h --- a/OrthancFramework/Sources/Toolbox.h Tue Jul 07 15:51:59 2026 +0200 +++ b/OrthancFramework/Sources/Toolbox.h Wed Jul 08 10:17:35 2026 +0200 @@ -432,6 +432,13 @@ unsigned int major, unsigned int minor, unsigned int revision); + + static void SwapEndianness(void* data, + size_t dataSize, + size_t itemSize); + + static void SwapEndianness(std::string& buffer, + size_t itemSize); }; } diff -r 91b3be9a243a -r cb751bdccb15 OrthancFramework/UnitTestsSources/DicomMapTests.cpp --- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Tue Jul 07 15:51:59 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Jul 08 10:17:35 2026 +0200 @@ -1372,6 +1372,13 @@ Toolbox::DecodeBase64(decoded, result["00660041"]["InlineBinary"].asString()); ASSERT_EQ(3 * sizeof(uint16_t), decoded.size()); + if (Toolbox::DetectEndianness() == Endianness_Big) + { + std::swap(decoded[0], decoded[1]); + std::swap(decoded[2], decoded[3]); + std::swap(decoded[4], decoded[5]); + } + uint16_t f0, f1, f2; memcpy(&f0, decoded.c_str(), sizeof(uint16_t)); memcpy(&f1, decoded.c_str() + sizeof(uint16_t), sizeof(uint16_t)); @@ -1400,6 +1407,11 @@ Toolbox::DecodeBase64(decoded, result["00660041"]["InlineBinary"].asString()); ASSERT_EQ(3 * sizeof(uint32_t), decoded.size()); + if (Toolbox::DetectEndianness() == Endianness_Big) + { + Toolbox::SwapEndianness(decoded, sizeof(uint32_t)); + } + uint32_t f0, f1, f2; memcpy(&f0, decoded.c_str(), sizeof(uint32_t)); memcpy(&f1, decoded.c_str() + sizeof(uint32_t), sizeof(uint32_t)); @@ -1429,6 +1441,11 @@ Toolbox::DecodeBase64(decoded, result["00660041"]["InlineBinary"].asString()); ASSERT_EQ(3 * sizeof(uint64_t), decoded.size()); + if (Toolbox::DetectEndianness() == Endianness_Big) + { + Toolbox::SwapEndianness(decoded, sizeof(uint64_t)); + } + uint64_t f0, f1, f2; memcpy(&f0, decoded.c_str(), sizeof(uint64_t)); memcpy(&f1, decoded.c_str() + sizeof(uint64_t), sizeof(uint64_t)); @@ -1584,6 +1601,11 @@ Toolbox::DecodeBase64(decoded, result["00660027"]["InlineBinary"].asString()); ASSERT_EQ(2 * sizeof(float), decoded.size()); + if (Toolbox::DetectEndianness() == Endianness_Big) + { + Toolbox::SwapEndianness(decoded, sizeof(float)); + } + float f0, f1; memcpy(&f0, decoded.c_str(), sizeof(float)); memcpy(&f1, decoded.c_str() + sizeof(float), sizeof(float)); @@ -1610,6 +1632,11 @@ Toolbox::DecodeBase64(decoded, result["00660027"]["InlineBinary"].asString()); ASSERT_EQ(2 * sizeof(double), decoded.size()); + if (Toolbox::DetectEndianness() == Endianness_Big) + { + Toolbox::SwapEndianness(decoded, sizeof(double)); + } + double f0, f1; memcpy(&f0, decoded.c_str(), sizeof(double)); memcpy(&f1, decoded.c_str() + sizeof(double), sizeof(double)); diff -r 91b3be9a243a -r cb751bdccb15 OrthancFramework/UnitTestsSources/ToolboxTests.cpp --- a/OrthancFramework/UnitTestsSources/ToolboxTests.cpp Tue Jul 07 15:51:59 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/ToolboxTests.cpp Wed Jul 08 10:17:35 2026 +0200 @@ -499,3 +499,33 @@ ASSERT_EQ(8, sizeof(static_cast(16 * 1024 * 1024) * KILOBYTE)); ASSERT_EQ(8, sizeof(KILOBYTE * static_cast(16 * 1024 * 1024))); } + + +TEST(Toolbox, SwapEndianness) +{ + const std::string s = "abcdefgh"; + + { + std::string t = s; + Toolbox::SwapEndianness(t, 1); + ASSERT_EQ("abcdefgh", t); + } + + { + std::string t = s; + Toolbox::SwapEndianness(t, 2); + ASSERT_EQ("badcfehg", t); + } + + { + std::string t = s; + Toolbox::SwapEndianness(t, 4); + ASSERT_EQ("dcbahgfe", t); + } + + { + std::string t = s; + Toolbox::SwapEndianness(t, 8); + ASSERT_EQ("hgfedcba", t); + } +}