Mercurial > hg > orthanc
changeset 5129:16138d6d568d
fix decoding of RLE images for which the "Planar Configuration" tag (0028,0006) equals 1
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 22 Dec 2022 15:28:14 +0100 |
parents | ede035d48b8e |
children | e107ff622e6d |
files | NEWS OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp |
diffstat | 2 files changed, 61 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Mon Dec 19 20:00:21 2022 +0100 +++ b/NEWS Thu Dec 22 15:28:14 2022 +0100 @@ -32,7 +32,12 @@ Common plugins code (C++) ------------------------- -* Added a 'header' argument to all OrthancPeers::DoPost, DoPut, ... +* Added a 'header' argument to all OrthancPeers::DoPost, DoPut, ... + +Maintenance +----------- + +* Fix decoding of RLE images for which the "Planar Configuration" tag (0028,0006) equals 1 version 1.11.2 (2022-08-30)
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Mon Dec 19 20:00:21 2022 +0100 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Thu Dec 22 15:28:14 2022 +0100 @@ -644,6 +644,51 @@ } + static ImageAccessor* DecodePlanarConfiguration(const ImageAccessor& source) + { + /** + * This function will interleave the RGB channels, if the source + * DICOM image has the "Planar Configuration" (0028,0006) tag that + * equals 1. This process was not applied to images using the RLE + * codec, which led to the following issue: + * https://groups.google.com/g/orthanc-users/c/CSVWfRasSR0/m/y1XDRXVnAgAJ + **/ + + const unsigned int height = source.GetHeight(); + const unsigned int width = source.GetWidth(); + const size_t size = static_cast<size_t>(height) * static_cast<size_t>(width); + + if (source.GetFormat() != PixelFormat_RGB24 || + 3 * width != source.GetPitch()) + { + throw OrthancException(ErrorCode_NotImplemented); + } + + std::unique_ptr<ImageAccessor> target(new Image(PixelFormat_RGB24, width, height, false)); + + const uint8_t* red = reinterpret_cast<const uint8_t*>(source.GetConstBuffer()); + const uint8_t* green = red + size; + const uint8_t* blue = red + 2 * size; + + for (unsigned int y = 0; y < height; y++) + { + uint8_t* interleaved = reinterpret_cast<uint8_t*>(target->GetRow(y)); + for (unsigned int x = 0; x < width; x++) + { + interleaved[0] = *red; + interleaved[1] = *green; + interleaved[2] = *blue; + interleaved += 3; + red++; + green++; + blue++; + } + } + + return target.release(); + } + + ImageAccessor* DicomImageDecoder::ApplyCodec (const DcmCodec& codec, const DcmCodecParameter& parameters, @@ -700,7 +745,16 @@ "Cannot decode a non-palette image"); } - return target.release(); + if (target->GetFormat() == PixelFormat_RGB24 && + Orthanc::Toolbox::StripSpaces(decompressedColorModel.c_str()) == "RGB" && + info.IsPlanar()) + { + return DecodePlanarConfiguration(*target); + } + else + { + return target.release(); + } } }