# HG changeset patch # User Sebastien Jodogne # Date 1610453235 -3600 # Node ID fd958175c5b96ee31f0c8ce8086dc604a74831db # Parent f77ee6e6cf47d8d3dab480412d083c999207c01b ImageProcessing::ConvertJpegYCbCrToRgb() diff -r f77ee6e6cf47 -r fd958175c5b9 OrthancFramework/Sources/Images/ImageProcessing.cpp --- a/OrthancFramework/Sources/Images/ImageProcessing.cpp Mon Jan 11 14:32:44 2021 +0100 +++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp Tue Jan 12 13:07:15 2021 +0100 @@ -2570,4 +2570,60 @@ return target.release(); } + + + void ImageProcessing::ConvertJpegYCbCrToRgb(ImageAccessor& image) + { + // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2 + // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion + + // TODO - Check out the outcome of Mathieu's discussion about + // truncation of YCbCr-to-RGB conversion: + // https://groups.google.com/forum/#!msg/comp.protocols.dicom/JHuGeyWbTz8/ARoTWrJzAQAJ + + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + const unsigned int pitch = image.GetPitch(); + uint8_t* buffer = reinterpret_cast(image.GetBuffer()); + + if (image.GetFormat() != PixelFormat_RGB24 || + pitch < 3 * width) + { + throw OrthancException(ErrorCode_IncompatibleImageFormat); + } + + for (unsigned int y = 0; y < height; y++) + { + uint8_t* p = buffer + y * pitch; + + for (unsigned int x = 0; x < width; x++, p += 3) + { + const float Y = p[0]; + const float Cb = p[1]; + const float Cr = p[2]; + + const float result[3] = { + Y + 1.402f * (Cr - 128.0f), + Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f), + Y + 1.772f * (Cb - 128.0f) + }; + + for (uint8_t i = 0; i < 3 ; i++) + { + if (result[i] < 0) + { + p[i] = 0; + } + else if (result[i] > 255) + { + p[i] = 255; + } + else + { + p[i] = static_cast(result[i]); + } + } + } + } + } } diff -r f77ee6e6cf47 -r fd958175c5b9 OrthancFramework/Sources/Images/ImageProcessing.h --- a/OrthancFramework/Sources/Images/ImageProcessing.h Mon Jan 11 14:32:44 2021 +0100 +++ b/OrthancFramework/Sources/Images/ImageProcessing.h Tue Jan 12 13:07:15 2021 +0100 @@ -197,5 +197,8 @@ static ImageAccessor* FitSizeKeepAspectRatio(const ImageAccessor& source, unsigned int width, unsigned int height); + + // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion + static void ConvertJpegYCbCrToRgb(ImageAccessor& image /* inplace */); }; }