Mercurial > hg > orthanc
changeset 7023:cb751bdccb15
support of big endian architectures in DICOMweb
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Wed, 08 Jul 2026 10:17:35 +0200 |
| parents | 91b3be9a243a |
| children | a412fcd67ae6 |
| files | OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp OrthancFramework/Sources/Toolbox.cpp OrthancFramework/Sources/Toolbox.h OrthancFramework/UnitTestsSources/DicomMapTests.cpp OrthancFramework/UnitTestsSources/ToolboxTests.cpp |
| diffstat | 5 files changed, 133 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- 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<SourceType>& 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<MemoryType*>(&raw[0]); for (size_t i = 0; i < values.size(); i++, p++) { *p = static_cast<MemoryType>(values[i]); } + + if (endianness == Endianness_Big) + { + Toolbox::SwapEndianness(raw, sizeof(MemoryType)); + } } std::string base64;
--- 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<uint8_t*>(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); + } + } }
--- 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); }; }
--- 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));
--- 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<int32_t>(16 * 1024 * 1024) * KILOBYTE)); ASSERT_EQ(8, sizeof(KILOBYTE * static_cast<int32_t>(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); + } +}
