Mercurial > hg > orthanc
diff OrthancServer/Internals/DicomImageDecoder.cpp @ 1826:ac5b0b4e2434
refactoring of DicomImageDecoder
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Nov 2015 16:00:57 +0100 |
parents | b530c3dfe2a6 |
children | b1291df2f780 |
line wrap: on
line diff
--- a/OrthancServer/Internals/DicomImageDecoder.cpp Wed Nov 25 14:24:26 2015 +0100 +++ b/OrthancServer/Internals/DicomImageDecoder.cpp Wed Nov 25 16:00:57 2015 +0100 @@ -82,8 +82,8 @@ #include "../../Core/Logging.h" #include "../../Core/OrthancException.h" +#include "../../Core/Images/Image.h" #include "../../Core/Images/ImageProcessing.h" -#include "../../Core/Images/PngWriter.h" // TODO REMOVE THIS #include "../../Core/DicomFormat/DicomIntegerPixelAccessor.h" #include "../ToDcmtkBridge.h" #include "../FromDcmtkBridge.h" @@ -91,6 +91,8 @@ #include <boost/lexical_cast.hpp> +#include <dcmtk/dcmdata/dcfilefo.h> + #if ORTHANC_JPEG_LOSSLESS_ENABLED == 1 #include <dcmtk/dcmjpls/djcodecd.h> #include <dcmtk/dcmjpls/djcparam.h> @@ -304,8 +306,7 @@ }; - void DicomImageDecoder::SetupImageBuffer(ImageBuffer& target, - DcmDataset& dataset) + ImageAccessor* DicomImageDecoder::CreateImage(DcmDataset& dataset) { DicomMap m; FromDcmtkBridge::Convert(m, dataset); @@ -324,9 +325,7 @@ throw OrthancException(ErrorCode_NotImplemented); } - target.SetHeight(info.GetHeight()); - target.SetWidth(info.GetWidth()); - target.SetFormat(format); + return new Image(format, info.GetWidth(), info.GetHeight()); } @@ -374,22 +373,20 @@ } - void DicomImageDecoder::DecodeUncompressedImage(ImageBuffer& target, - DcmDataset& dataset, - unsigned int frame) + ImageAccessor* DicomImageDecoder::DecodeUncompressedImage(DcmDataset& dataset, + unsigned int frame) { if (!IsUncompressedImage(dataset)) { throw OrthancException(ErrorCode_BadParameterType); } - DecodeUncompressedImageInternal(target, dataset, frame); + return DecodeUncompressedImageInternal(dataset, frame); } - void DicomImageDecoder::DecodeUncompressedImageInternal(ImageBuffer& target, - DcmDataset& dataset, - unsigned int frame) + ImageAccessor* DicomImageDecoder::DecodeUncompressedImageInternal(DcmDataset& dataset, + unsigned int frame) { ImageSource source; source.Setup(dataset, frame); @@ -399,10 +396,10 @@ * Resize the target image. **/ - SetupImageBuffer(target, dataset); + std::auto_ptr<ImageAccessor> target(CreateImage(dataset)); - if (source.GetWidth() != target.GetWidth() || - source.GetHeight() != target.GetHeight()) + if (source.GetWidth() != target->GetWidth() || + source.GetHeight() != target->GetHeight()) { throw OrthancException(ErrorCode_InternalError); } @@ -413,7 +410,6 @@ * direct access to copy its values. **/ - ImageAccessor targetAccessor(target.GetAccessor()); const DicomImageInformation& info = source.GetAccessor().GetInformation(); bool fastVersionSuccess = false; @@ -435,8 +431,8 @@ info.GetWidth() * GetBytesPerPixel(sourceFormat), buffer + frame * frameSize); - ImageProcessing::Convert(targetAccessor, sourceImage); - ImageProcessing::ShiftRight(targetAccessor, info.GetShift()); + ImageProcessing::Convert(*target, sourceImage); + ImageProcessing::ShiftRight(*target, info.GetShift()); fastVersionSuccess = true; } } @@ -453,33 +449,34 @@ if (!fastVersionSuccess) { - switch (target.GetFormat()) + switch (target->GetFormat()) { case PixelFormat_RGB24: case PixelFormat_RGBA32: case PixelFormat_Grayscale8: - CopyPixels<uint8_t>(targetAccessor, source.GetAccessor()); + CopyPixels<uint8_t>(*target, source.GetAccessor()); break; case PixelFormat_Grayscale16: - CopyPixels<uint16_t>(targetAccessor, source.GetAccessor()); + CopyPixels<uint16_t>(*target, source.GetAccessor()); break; case PixelFormat_SignedGrayscale16: - CopyPixels<int16_t>(targetAccessor, source.GetAccessor()); + CopyPixels<int16_t>(*target, source.GetAccessor()); break; default: throw OrthancException(ErrorCode_InternalError); } } + + return target.release(); } #if ORTHANC_JPEG_LOSSLESS_ENABLED == 1 - void DicomImageDecoder::DecodeJpegLossless(ImageBuffer& target, - DcmDataset& dataset, - unsigned int frame) + ImageAccessor* DicomImageDecoder::DecodeJpegLossless(DcmDataset& dataset, + unsigned int frame) { if (!IsJpegLossless(dataset)) { @@ -500,9 +497,7 @@ throw OrthancException(ErrorCode_BadFileFormat); } - SetupImageBuffer(target, dataset); - - ImageAccessor targetAccessor(target.GetAccessor()); + std::auto_ptr<ImageAccessor> target(CreateImage(dataset)); /** * The "DJLSLosslessDecoder" and "DJLSNearLosslessDecoder" in DCMTK @@ -518,38 +513,36 @@ OFString decompressedColorModel; // Out DJ_RPLossless representationParameter; OFCondition c = decoder.decodeFrame(&representationParameter, pixelSequence, ¶meters, - &dataset, frame, startFragment, targetAccessor.GetBuffer(), - targetAccessor.GetSize(), decompressedColorModel); + &dataset, frame, startFragment, target->GetBuffer(), + target->GetSize(), decompressedColorModel); if (!c.good()) { throw OrthancException(ErrorCode_InternalError); } + + return target.release(); } #endif - bool DicomImageDecoder::Decode(ImageBuffer& target, - ParsedDicomFile& dicom, - unsigned int frame) + ImageAccessor* DicomImageDecoder::Decode(ParsedDicomFile& dicom, + unsigned int frame) { DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset(); if (IsUncompressedImage(dataset)) { - DecodeUncompressedImage(target, dataset, frame); - return true; + return DecodeUncompressedImage(dataset, frame); } - #if ORTHANC_JPEG_LOSSLESS_ENABLED == 1 if (IsJpegLossless(dataset)) { LOG(INFO) << "Decoding a JPEG-LS image"; - DecodeJpegLossless(target, dataset, frame); - return true; + return DecodeJpegLossless(dataset, frame); } #endif @@ -558,7 +551,6 @@ // TODO Implement this part to speed up JPEG decompression #endif - /** * This DICOM image format is not natively supported by * Orthanc. As a last resort, try and decode it through @@ -575,12 +567,11 @@ if (converted->canWriteXfer(EXS_LittleEndianExplicit)) { - DecodeUncompressedImageInternal(target, *converted, frame); - return true; + return DecodeUncompressedImageInternal(*converted, frame); } } - return false; + return NULL; } @@ -591,14 +582,13 @@ } - bool DicomImageDecoder::TruncateDecodedImage(ImageBuffer& target, - ImageBuffer& source, + bool DicomImageDecoder::TruncateDecodedImage(std::auto_ptr<ImageAccessor>& image, PixelFormat format, bool allowColorConversion) { // If specified, prevent the conversion between color and // grayscale images - bool isSourceColor = IsColorImage(source.GetFormat()); + bool isSourceColor = IsColorImage(image->GetFormat()); bool isTargetColor = IsColorImage(format); if (!allowColorConversion) @@ -609,34 +599,25 @@ } } - if (source.GetFormat() == format) + if (image->GetFormat() != format) { - // No conversion is required, return the temporary image - target.AcquireOwnership(source); - return true; + // A conversion is required + std::auto_ptr<ImageAccessor> target(new Image(format, image->GetWidth(), image->GetHeight())); + ImageProcessing::Convert(*target, *image); + image = target; } - target.SetFormat(format); - target.SetWidth(source.GetWidth()); - target.SetHeight(source.GetHeight()); - - ImageAccessor targetAccessor(target.GetAccessor()); - ImageAccessor sourceAccessor(source.GetAccessor()); - ImageProcessing::Convert(targetAccessor, sourceAccessor); - return true; } - bool DicomImageDecoder::PreviewDecodedImage(ImageBuffer& target, - ImageBuffer& source) + bool DicomImageDecoder::PreviewDecodedImage(std::auto_ptr<ImageAccessor>& image) { - switch (source.GetFormat()) + switch (image->GetFormat()) { case PixelFormat_RGB24: { - // Directly return color images (RGB) - target.AcquireOwnership(source); + // Directly return color images without modification (RGB) return true; } @@ -645,32 +626,24 @@ case PixelFormat_SignedGrayscale16: { // Grayscale image: Stretch its dynamics to the [0,255] range - target.SetFormat(PixelFormat_Grayscale8); - target.SetWidth(source.GetWidth()); - target.SetHeight(source.GetHeight()); + int64_t a, b; + ImageProcessing::GetMinMaxValue(a, b, *image); - ImageAccessor targetAccessor(target.GetAccessor()); - ImageAccessor sourceAccessor(source.GetAccessor()); - - int64_t a, b; - ImageProcessing::GetMinMaxValue(a, b, sourceAccessor); - if (a == b) { - ImageProcessing::Set(targetAccessor, 0); + ImageProcessing::Set(*image, 0); } else { - ImageProcessing::ShiftScale(sourceAccessor, static_cast<float>(-a), 255.0f / static_cast<float>(b - a)); + ImageProcessing::ShiftScale(*image, static_cast<float>(-a), 255.0f / static_cast<float>(b - a)); + } - if (source.GetFormat() == PixelFormat_Grayscale8) - { - target.AcquireOwnership(source); - } - else - { - ImageProcessing::Convert(targetAccessor, sourceAccessor); - } + // If the source image is not grayscale 8bpp, convert it + if (image->GetFormat() != PixelFormat_Grayscale8) + { + std::auto_ptr<ImageAccessor> target(new Image(PixelFormat_Grayscale8, image->GetWidth(), image->GetHeight())); + ImageProcessing::Convert(*target, *image); + image = target; } return true;