Mercurial > hg > orthanc
changeset 859:610a9a1ed855 jpeg
ImageProcessing::Convert
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 06 Jun 2014 18:12:31 +0200 |
parents | ebc41566f742 |
children | 80c7e53a69b5 |
files | Core/ImageFormats/ImageProcessing.cpp OrthancServer/FromDcmtkBridge.cpp OrthancServer/Internals/DicomImageDecoder.cpp OrthancServer/Internals/DicomImageDecoder.h |
diffstat | 4 files changed, 161 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/ImageFormats/ImageProcessing.cpp Fri Jun 06 15:25:31 2014 +0200 +++ b/Core/ImageFormats/ImageProcessing.cpp Fri Jun 06 18:12:31 2014 +0200 @@ -37,9 +37,45 @@ #include <cassert> #include <string.h> +#include <limits> +#include <stdint.h> + +#include <stdio.h> namespace Orthanc { + template <typename TargetType, typename SourceType> + static void ConvertInternal(ImageAccessor& target, + const ImageAccessor& source) + { + const TargetType minValue = std::numeric_limits<TargetType>::min(); + const TargetType maxValue = std::numeric_limits<TargetType>::max(); + + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y)); + const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y)); + + for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + { + if (static_cast<int32_t>(*s) < static_cast<int32_t>(minValue)) + { + *t = minValue; + } + else if (static_cast<int32_t>(*s) > static_cast<int32_t>(maxValue)) + { + *t = maxValue; + } + else + { + *t = static_cast<TargetType>(*s); + } + } + } + } + + + void ImageProcessing::Copy(ImageAccessor& target, const ImageAccessor& source) { @@ -80,6 +116,50 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_Grayscale8) + { + ConvertInternal<uint16_t, uint8_t>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_SignedGrayscale16 && + source.GetFormat() == PixelFormat_Grayscale8) + { + ConvertInternal<int16_t, uint8_t>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_Grayscale16) + { + printf("ICI\n"); + ConvertInternal<uint8_t, uint16_t>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_SignedGrayscale16 && + source.GetFormat() == PixelFormat_Grayscale16) + { + ConvertInternal<int16_t, uint16_t>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + printf("ICI2\n"); + ConvertInternal<uint8_t, int16_t>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + ConvertInternal<uint16_t, int16_t>(target, source); + return; + } + throw OrthancException(ErrorCode_NotImplemented); }
--- a/OrthancServer/FromDcmtkBridge.cpp Fri Jun 06 15:25:31 2014 +0200 +++ b/OrthancServer/FromDcmtkBridge.cpp Fri Jun 06 18:12:31 2014 +0200 @@ -526,6 +526,20 @@ unsigned int frame, ImageExtractionMode mode) { + // TODO CONTINUE THIS + if (mode == ImageExtractionMode_UInt8) + { + ImageBuffer tmp; + if (DicomImageDecoder::Decode(tmp, dataset, frame, PixelFormat_Grayscale8, DicomImageDecoder::Mode_Truncate)) + { + printf("%d %d %d\n", tmp.GetWidth(), tmp.GetHeight(), tmp.GetFormat()); + ImageAccessor accessor(tmp.GetAccessor()); + PngWriter writer; + writer.WriteToMemory(result, accessor); + return; + } + } + // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data std::auto_ptr<DicomIntegerPixelAccessor> accessor;
--- a/OrthancServer/Internals/DicomImageDecoder.cpp Fri Jun 06 15:25:31 2014 +0200 +++ b/OrthancServer/Internals/DicomImageDecoder.cpp Fri Jun 06 18:12:31 2014 +0200 @@ -447,14 +447,14 @@ } catch (OrthancException&) { - // Unsupported conversion + // Unsupported conversion, use the slow version } } /** - * Loop over the DICOM buffer, storing its value into the target - * image. + * Slow version : loop over the DICOM buffer, storing its value + * into the target image. **/ if (!fastVersionSuccess) @@ -536,6 +536,7 @@ + bool DicomImageDecoder::Decode(ImageBuffer& target, DcmDataset& dataset, unsigned int frame) @@ -585,4 +586,45 @@ return false; } + + + bool DicomImageDecoder::Decode(ImageBuffer& target, + DcmDataset& dataset, + unsigned int frame, + PixelFormat format, + Mode mode) + { + // TODO OPTIMIZE THIS !!! + + ImageBuffer tmp; + if (!Decode(tmp, dataset, frame)) + { + return false; + } + + target.SetFormat(format); + target.SetWidth(tmp.GetWidth()); + target.SetHeight(tmp.GetHeight()); + + switch (mode) + { + case Mode_Truncate: + { + ImageAccessor a(target.GetAccessor()); + ImageAccessor b(tmp.GetAccessor()); + printf("IN\n"); + ImageProcessing::Convert(a, b); + printf("OUT\n"); + return true; + } + + default: + throw OrthancException(ErrorCode_NotImplemented); + } + + return false; + } + + + }
--- a/OrthancServer/Internals/DicomImageDecoder.h Fri Jun 06 15:25:31 2014 +0200 +++ b/OrthancServer/Internals/DicomImageDecoder.h Fri Jun 06 18:12:31 2014 +0200 @@ -40,8 +40,14 @@ { class DicomImageDecoder { - public: // TODO SWITCH TO PRIVATE - //private: + public: + enum Mode + { + Mode_Truncate, + Mode_Stretch + }; + + private: class ImageSource; static void DecodeUncompressedImageInternal(ImageBuffer& target, @@ -53,6 +59,7 @@ static void SetupImageBuffer(ImageBuffer& target, DcmDataset& dataset); + public: // TODO SWITCH TO PRIVATE static bool DecodePsmctRle1(std::string& output, DcmDataset& dataset); @@ -65,6 +72,12 @@ DcmDataset& dataset, unsigned int frame); + static void DecodeUncompressedImage(ImageBuffer& target, + DcmDataset& dataset, + unsigned int frame, + PixelFormat format, + Mode mode); + #if ORTHANC_JPEG_LOSSLESS_ENABLED == 1 static void DecodeJpegLossless(ImageBuffer& target, DcmDataset& dataset, @@ -74,5 +87,12 @@ static bool Decode(ImageBuffer& target, DcmDataset& dataset, unsigned int frame); + + static bool Decode(ImageBuffer& target, + DcmDataset& dataset, + unsigned int frame, + PixelFormat format, + Mode mode); + }; }