# HG changeset patch # User Sebastien Jodogne # Date 1402071151 -7200 # Node ID 610a9a1ed85570c3a0adffa58a43bc9ca5035a2f # Parent ebc41566f742f8c0b3486c0532bad2d6a8cadd7b ImageProcessing::Convert diff -r ebc41566f742 -r 610a9a1ed855 Core/ImageFormats/ImageProcessing.cpp --- 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 #include +#include +#include + +#include namespace Orthanc { + template + static void ConvertInternal(ImageAccessor& target, + const ImageAccessor& source) + { + const TargetType minValue = std::numeric_limits::min(); + const TargetType maxValue = std::numeric_limits::max(); + + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + TargetType* t = reinterpret_cast(target.GetRow(y)); + const SourceType* s = reinterpret_cast(source.GetConstRow(y)); + + for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + { + if (static_cast(*s) < static_cast(minValue)) + { + *t = minValue; + } + else if (static_cast(*s) > static_cast(maxValue)) + { + *t = maxValue; + } + else + { + *t = static_cast(*s); + } + } + } + } + + + void ImageProcessing::Copy(ImageAccessor& target, const ImageAccessor& source) { @@ -80,6 +116,50 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_Grayscale8) + { + ConvertInternal(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_SignedGrayscale16 && + source.GetFormat() == PixelFormat_Grayscale8) + { + ConvertInternal(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_Grayscale16) + { + printf("ICI\n"); + ConvertInternal(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_SignedGrayscale16 && + source.GetFormat() == PixelFormat_Grayscale16) + { + ConvertInternal(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + printf("ICI2\n"); + ConvertInternal(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_SignedGrayscale16) + { + ConvertInternal(target, source); + return; + } + throw OrthancException(ErrorCode_NotImplemented); } diff -r ebc41566f742 -r 610a9a1ed855 OrthancServer/FromDcmtkBridge.cpp --- 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 accessor; diff -r ebc41566f742 -r 610a9a1ed855 OrthancServer/Internals/DicomImageDecoder.cpp --- 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; + } + + + } diff -r ebc41566f742 -r 610a9a1ed855 OrthancServer/Internals/DicomImageDecoder.h --- 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); + }; }