Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp @ 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 | 5e7404f23fa8 |
children | 0ea402b4d901 |
comparison
equal
deleted
inserted
replaced
5128:ede035d48b8e | 5129:16138d6d568d |
---|---|
642 | 642 |
643 return target.release(); | 643 return target.release(); |
644 } | 644 } |
645 | 645 |
646 | 646 |
647 static ImageAccessor* DecodePlanarConfiguration(const ImageAccessor& source) | |
648 { | |
649 /** | |
650 * This function will interleave the RGB channels, if the source | |
651 * DICOM image has the "Planar Configuration" (0028,0006) tag that | |
652 * equals 1. This process was not applied to images using the RLE | |
653 * codec, which led to the following issue: | |
654 * https://groups.google.com/g/orthanc-users/c/CSVWfRasSR0/m/y1XDRXVnAgAJ | |
655 **/ | |
656 | |
657 const unsigned int height = source.GetHeight(); | |
658 const unsigned int width = source.GetWidth(); | |
659 const size_t size = static_cast<size_t>(height) * static_cast<size_t>(width); | |
660 | |
661 if (source.GetFormat() != PixelFormat_RGB24 || | |
662 3 * width != source.GetPitch()) | |
663 { | |
664 throw OrthancException(ErrorCode_NotImplemented); | |
665 } | |
666 | |
667 std::unique_ptr<ImageAccessor> target(new Image(PixelFormat_RGB24, width, height, false)); | |
668 | |
669 const uint8_t* red = reinterpret_cast<const uint8_t*>(source.GetConstBuffer()); | |
670 const uint8_t* green = red + size; | |
671 const uint8_t* blue = red + 2 * size; | |
672 | |
673 for (unsigned int y = 0; y < height; y++) | |
674 { | |
675 uint8_t* interleaved = reinterpret_cast<uint8_t*>(target->GetRow(y)); | |
676 for (unsigned int x = 0; x < width; x++) | |
677 { | |
678 interleaved[0] = *red; | |
679 interleaved[1] = *green; | |
680 interleaved[2] = *blue; | |
681 interleaved += 3; | |
682 red++; | |
683 green++; | |
684 blue++; | |
685 } | |
686 } | |
687 | |
688 return target.release(); | |
689 } | |
690 | |
691 | |
647 ImageAccessor* DicomImageDecoder::ApplyCodec | 692 ImageAccessor* DicomImageDecoder::ApplyCodec |
648 (const DcmCodec& codec, | 693 (const DcmCodec& codec, |
649 const DcmCodecParameter& parameters, | 694 const DcmCodecParameter& parameters, |
650 const DcmRepresentationParameter& representationParameter, | 695 const DcmRepresentationParameter& representationParameter, |
651 DcmDataset& dataset, | 696 DcmDataset& dataset, |
698 { | 743 { |
699 throw OrthancException(ErrorCode_BadFileFormat, | 744 throw OrthancException(ErrorCode_BadFileFormat, |
700 "Cannot decode a non-palette image"); | 745 "Cannot decode a non-palette image"); |
701 } | 746 } |
702 | 747 |
703 return target.release(); | 748 if (target->GetFormat() == PixelFormat_RGB24 && |
749 Orthanc::Toolbox::StripSpaces(decompressedColorModel.c_str()) == "RGB" && | |
750 info.IsPlanar()) | |
751 { | |
752 return DecodePlanarConfiguration(*target); | |
753 } | |
754 else | |
755 { | |
756 return target.release(); | |
757 } | |
704 } | 758 } |
705 } | 759 } |
706 | 760 |
707 | 761 |
708 static void UndoBigEndianSwapping(ImageAccessor& decoded) | 762 static void UndoBigEndianSwapping(ImageAccessor& decoded) |