# HG changeset patch # User Sebastien Jodogne # Date 1584032314 -3600 # Node ID accf1b60b1083fe515cc019ca38a836e128a78c3 # Parent 33c19a6643e11cdd89069cc47f62aa76d43cb2bd accessing raw pixel data diff -r 33c19a6643e1 -r accf1b60b108 Core/DicomParsing/Internals/DicomImageDecoder.cpp --- a/Core/DicomParsing/Internals/DicomImageDecoder.cpp Thu Mar 12 16:08:08 2020 +0100 +++ b/Core/DicomParsing/Internals/DicomImageDecoder.cpp Thu Mar 12 17:58:34 2020 +0100 @@ -34,6 +34,8 @@ #include "../../PrecompiledHeaders.h" #include "DicomImageDecoder.h" +#include "../ParsedDicomFile.h" + /*========================================================================= @@ -84,7 +86,6 @@ #include "../../DicomFormat/DicomIntegerPixelAccessor.h" #include "../ToDcmtkBridge.h" #include "../FromDcmtkBridge.h" -#include "../ParsedDicomFile.h" #if ORTHANC_ENABLE_PNG == 1 # include "../../Images/PngWriter.h" @@ -98,7 +99,6 @@ #include #include -#include #include #include #include @@ -662,7 +662,20 @@ ImageAccessor* DicomImageDecoder::Decode(ParsedDicomFile& dicom, unsigned int frame) { - DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset(); + if (dicom.GetDcmtkObject().getDataset() == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + else + { + return Decode(*dicom.GetDcmtkObject().getDataset(), frame); + } + } + + + ImageAccessor* DicomImageDecoder::Decode(DcmDataset& dataset, + unsigned int frame) + { E_TransferSyntax syntax = dataset.getOriginalXfer(); /** diff -r 33c19a6643e1 -r accf1b60b108 Core/DicomParsing/Internals/DicomImageDecoder.h --- a/Core/DicomParsing/Internals/DicomImageDecoder.h Thu Mar 12 16:08:08 2020 +0100 +++ b/Core/DicomParsing/Internals/DicomImageDecoder.h Thu Mar 12 17:58:34 2020 +0100 @@ -34,7 +34,7 @@ #pragma once #include "../../Compatibility.h" -#include "../ParsedDicomFile.h" +#include "../../Images/ImageAccessor.h" #include @@ -62,6 +62,8 @@ namespace Orthanc { + class ParsedDicomFile; + class DicomImageDecoder : public boost::noncopyable { private: @@ -102,6 +104,9 @@ static ImageAccessor *Decode(ParsedDicomFile& dicom, unsigned int frame); + static ImageAccessor *Decode(DcmDataset& dataset, + unsigned int frame); + static void ExtractPamImage(std::string& result, std::unique_ptr& image, ImageExtractionMode mode, diff -r 33c19a6643e1 -r accf1b60b108 UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Thu Mar 12 16:08:08 2020 +0100 +++ b/UnitTestsSources/FromDcmtkTests.cpp Thu Mar 12 17:58:34 2020 +0100 @@ -1919,6 +1919,11 @@ #include "../Core/DicomFormat/DicomImageInformation.h" +#include +#include +#include + + namespace Orthanc { class IDicomTranscoder : public boost::noncopyable @@ -1936,13 +1941,13 @@ virtual unsigned int GetFramesCount() = 0; - virtual IDicomTranscoder* Transcode(std::set syntaxes, - bool allowNewSopInstanceUid) = 0; - virtual ImageAccessor* DecodeFrame(unsigned int frame) = 0; virtual void GetCompressedFrame(std::string& target, unsigned int frame) = 0; + + virtual IDicomTranscoder* Transcode(std::set syntaxes, + bool allowNewSopInstanceUid) = 0; }; @@ -2012,11 +2017,6 @@ Setup(FromDcmtkBridge::LoadFromMemoryBuffer(dicom, size)); } - DcmtkTranscoder(const ParsedDicomFile& dicom) - { - Setup(new DcmFileFormat(dicom.GetDcmtkObject())); - } - virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE { return transferSyntax_; @@ -2037,20 +2037,83 @@ return info_->GetNumberOfFrames(); } - virtual IDicomTranscoder* Transcode(std::set syntaxes, - bool allowNewSopInstanceUid) ORTHANC_OVERRIDE - { - throw OrthancException(ErrorCode_NotImplemented); - } - virtual ImageAccessor* DecodeFrame(unsigned int frame) ORTHANC_OVERRIDE { - throw OrthancException(ErrorCode_NotImplemented); + assert(dicom_->getDataset() != NULL); + return DicomImageDecoder::Decode(*dicom_->getDataset(), frame); } virtual void GetCompressedFrame(std::string& target, unsigned int frame) ORTHANC_OVERRIDE { + assert(dicom_->getDataset() != NULL); + DcmDataset& dataset = *dicom_->getDataset(); + + DcmPixelSequence* pixelSequence = FromDcmtkBridge::GetPixelSequence(dataset); + + if (pixelSequence == NULL) + { + // This is an uncompressed frame + + DcmElement* element = NULL; + if (dataset.findAndGetElement(DCM_PixelData, element).good() && + element != NULL) + { + Uint8* pixelData = NULL; + + if (element->getUint8Array(pixelData).good() && + pixelData != NULL) + { + // TODO => use "pixelData" + printf("RAW %d\n", element->getLength()); + } + else + { + throw OrthancException(ErrorCode_BadFileFormat, + "Cannot access uncompressed pixel data"); + } + } + else + { + std::string decoded; + if (DicomImageDecoder::DecodePsmctRle1(decoded, dataset)) + { + // TODO => use "decoded" + } + else + { + throw OrthancException(ErrorCode_BadFileFormat, + "Cannot access uncompressed pixel data"); + } + } + } + else + { + printf("COMPRESSED\n"); + + // Check out "djcodecd.cc" + + printf("%d fragments\n", pixelSequence->card()); + + // Skip the first fragment, that is the offset table + for (unsigned long i = 1; ;i++) + { + DcmPixelItem *fragment = NULL; + if (pixelSequence->getItem(fragment, i).good()) + { + printf("fragment %d %d\n", i, fragment->getLength()); + } + else + { + break; + } + } + } + } + + virtual IDicomTranscoder* Transcode(std::set syntaxes, + bool allowNewSopInstanceUid) ORTHANC_OVERRIDE + { throw OrthancException(ErrorCode_NotImplemented); } }; @@ -2058,7 +2121,6 @@ -#include static bool Transcode(std::string& buffer, DcmDataset& dataSet, @@ -2144,9 +2206,14 @@ Orthanc::DcmtkTranscoder transcoder(s.c_str(), s.size()); - printf("[%s] [%s] [%s] %d\n\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()), + printf("[%s] [%s] [%s] %d\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()), transcoder.GetSopClassUid().c_str(), transcoder.GetSopInstanceUid().c_str(), transcoder.GetFramesCount()); + + std::string f; + transcoder.GetCompressedFrame(f, 0); + + printf("\n"); } TEST(Toto, Transcode)