# HG changeset patch # User Sebastien Jodogne # Date 1671719294 -3600 # Node ID 16138d6d568d7bb6cfffe6791250ecdfbb2ec248 # Parent ede035d48b8e29e9ab52554a5da20e88f558453e fix decoding of RLE images for which the "Planar Configuration" tag (0028,0006) equals 1 diff -r ede035d48b8e -r 16138d6d568d NEWS --- 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) diff -r ede035d48b8e -r 16138d6d568d OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp --- 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(height) * static_cast(width); + + if (source.GetFormat() != PixelFormat_RGB24 || + 3 * width != source.GetPitch()) + { + throw OrthancException(ErrorCode_NotImplemented); + } + + std::unique_ptr target(new Image(PixelFormat_RGB24, width, height, false)); + + const uint8_t* red = reinterpret_cast(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(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(); + } } }