comparison OrthancFramework/Sources/Images/ImageProcessing.cpp @ 4443:fd958175c5b9

ImageProcessing::ConvertJpegYCbCrToRgb()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 Jan 2021 13:07:15 +0100
parents d9473bd5ed43
children 19e8540064d8
comparison
equal deleted inserted replaced
4442:f77ee6e6cf47 4443:fd958175c5b9
2568 Copy(region, *resized); 2568 Copy(region, *resized);
2569 } 2569 }
2570 2570
2571 return target.release(); 2571 return target.release();
2572 } 2572 }
2573
2574
2575 void ImageProcessing::ConvertJpegYCbCrToRgb(ImageAccessor& image)
2576 {
2577 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
2578 // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
2579
2580 // TODO - Check out the outcome of Mathieu's discussion about
2581 // truncation of YCbCr-to-RGB conversion:
2582 // https://groups.google.com/forum/#!msg/comp.protocols.dicom/JHuGeyWbTz8/ARoTWrJzAQAJ
2583
2584 const unsigned int width = image.GetWidth();
2585 const unsigned int height = image.GetHeight();
2586 const unsigned int pitch = image.GetPitch();
2587 uint8_t* buffer = reinterpret_cast<uint8_t*>(image.GetBuffer());
2588
2589 if (image.GetFormat() != PixelFormat_RGB24 ||
2590 pitch < 3 * width)
2591 {
2592 throw OrthancException(ErrorCode_IncompatibleImageFormat);
2593 }
2594
2595 for (unsigned int y = 0; y < height; y++)
2596 {
2597 uint8_t* p = buffer + y * pitch;
2598
2599 for (unsigned int x = 0; x < width; x++, p += 3)
2600 {
2601 const float Y = p[0];
2602 const float Cb = p[1];
2603 const float Cr = p[2];
2604
2605 const float result[3] = {
2606 Y + 1.402f * (Cr - 128.0f),
2607 Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f),
2608 Y + 1.772f * (Cb - 128.0f)
2609 };
2610
2611 for (uint8_t i = 0; i < 3 ; i++)
2612 {
2613 if (result[i] < 0)
2614 {
2615 p[i] = 0;
2616 }
2617 else if (result[i] > 255)
2618 {
2619 p[i] = 255;
2620 }
2621 else
2622 {
2623 p[i] = static_cast<uint8_t>(result[i]);
2624 }
2625 }
2626 }
2627 }
2628 }
2573 } 2629 }