Mercurial > hg > orthanc
diff Core/Images/ImageProcessing.cpp @ 2981:eff50153a7b3 db-changes
integration mainline->db-changes
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 06 Dec 2018 15:58:08 +0100 |
parents | 7791eac62572 |
children | 4e43e67f8ecf |
line wrap: on
line diff
--- a/Core/Images/ImageProcessing.cpp Thu Oct 18 10:48:11 2018 +0200 +++ b/Core/Images/ImageProcessing.cpp Thu Dec 06 15:58:08 2018 +0100 @@ -53,12 +53,15 @@ 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++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; 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++) + for (unsigned int x = 0; x < width; x++, t++, s++) { if (static_cast<int32_t>(*s) < static_cast<int32_t>(minValue)) { @@ -83,12 +86,15 @@ { assert(sizeof(float) == 4); - for (unsigned int y = 0; y < source.GetHeight(); y++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { float* t = reinterpret_cast<float*>(target.GetRow(y)); const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + for (unsigned int x = 0; x < width; x++, t++, s++) { *t = static_cast<float>(*s); } @@ -96,6 +102,30 @@ } + template <PixelFormat TargetFormat> + static void ConvertFloatToGrayscale(ImageAccessor& target, + const ImageAccessor& source) + { + typedef typename PixelTraits<TargetFormat>::PixelType TargetType; + + assert(sizeof(float) == 4); + + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) + { + TargetType* q = reinterpret_cast<TargetType*>(target.GetRow(y)); + const float* p = reinterpret_cast<const float*>(source.GetConstRow(y)); + + for (unsigned int x = 0; x < width; x++, p++, q++) + { + PixelTraits<TargetFormat>::FloatToPixel(*q, *p); + } + } + } + + template <typename TargetType> static void ConvertColorToGrayscale(ImageAccessor& target, const ImageAccessor& source) @@ -105,12 +135,15 @@ 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++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y)); const uint8_t* s = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s += 3) + for (unsigned int x = 0; x < width; x++, t++, s += 3) { // Y = 0.2126 R + 0.7152 G + 0.0722 B int32_t v = (2126 * static_cast<int32_t>(s[0]) + @@ -134,17 +167,48 @@ } + static void MemsetZeroInternal(ImageAccessor& image) + { + const unsigned int height = image.GetHeight(); + const size_t lineSize = image.GetBytesPerPixel() * image.GetWidth(); + const size_t pitch = image.GetPitch(); + + uint8_t *p = reinterpret_cast<uint8_t*>(image.GetBuffer()); + + for (unsigned int y = 0; y < height; y++) + { + memset(p, 0, lineSize); + p += pitch; + } + } + + template <typename PixelType> static void SetInternal(ImageAccessor& image, int64_t constant) { - for (unsigned int y = 0; y < image.GetHeight(); y++) + if (constant == 0 && + (image.GetFormat() == PixelFormat_Grayscale8 || + image.GetFormat() == PixelFormat_Grayscale16 || + image.GetFormat() == PixelFormat_Grayscale32 || + image.GetFormat() == PixelFormat_Grayscale64 || + image.GetFormat() == PixelFormat_SignedGrayscale16)) { - PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); + MemsetZeroInternal(image); + } + else + { + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int y = 0; y < height; y++) { - *p = static_cast<PixelType>(constant); + PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); + + for (unsigned int x = 0; x < width; x++, p++) + { + *p = static_cast<PixelType>(constant); + } } } } @@ -167,9 +231,10 @@ minValue = std::numeric_limits<PixelType>::max(); maxValue = std::numeric_limits<PixelType>::min(); + const unsigned int height = source.GetHeight(); const unsigned int width = source.GetWidth(); - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y)); @@ -202,11 +267,14 @@ const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { int64_t v = static_cast<int64_t>(*p) + constant; @@ -240,9 +308,11 @@ const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); - const unsigned int width = image.GetWidth(); - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); @@ -334,7 +404,7 @@ throw OrthancException(ErrorCode_IncompatibleImageFormat); } - unsigned int lineSize = GetBytesPerPixel(source.GetFormat()) * source.GetWidth(); + unsigned int lineSize = source.GetBytesPerPixel() * source.GetWidth(); assert(source.GetPitch() >= lineSize && target.GetPitch() >= lineSize); @@ -354,6 +424,9 @@ throw OrthancException(ErrorCode_IncompatibleImageSize); } + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + if (source.GetFormat() == target.GetFormat()) { Copy(target, source); @@ -451,14 +524,15 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_RGBA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, q++) + for (unsigned int x = 0; x < width; x++, q++) { *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[0]) + 7152 * static_cast<uint32_t>(p[1]) + @@ -473,11 +547,11 @@ if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_BGRA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, q++) + for (unsigned int x = 0; x < width; x++, q++) { *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[2]) + 7152 * static_cast<uint32_t>(p[1]) + @@ -492,11 +566,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_RGBA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0]; q[1] = p[1]; @@ -512,11 +586,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_BGRA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[2]; q[1] = p[1]; @@ -532,11 +606,11 @@ if (target.GetFormat() == PixelFormat_RGBA32 && source.GetFormat() == PixelFormat_RGB24) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0]; q[1] = p[1]; @@ -553,11 +627,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_Grayscale8) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = *p; q[1] = *p; @@ -574,11 +648,11 @@ target.GetFormat() == PixelFormat_BGRA32) && source.GetFormat() == PixelFormat_Grayscale8) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = *p; q[1] = *p; @@ -595,11 +669,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_Grayscale16) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { uint8_t value = (*p < 256 ? *p : 255); q[0] = value; @@ -617,11 +691,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_SignedGrayscale16) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const int16_t* p = reinterpret_cast<const int16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { uint8_t value; if (*p < 0) @@ -652,11 +726,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_RGB24) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[2]; q[1] = p[1]; @@ -673,11 +747,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_RGB48) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0] >> 8; q[1] = p[1] >> 8; @@ -690,6 +764,20 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_Float32) + { + ConvertFloatToGrayscale<PixelFormat_Grayscale16>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_Float32) + { + ConvertFloatToGrayscale<PixelFormat_Grayscale8>(target, source); + return; + } + throw OrthancException(ErrorCode_NotImplemented); } @@ -701,51 +789,23 @@ switch (image.GetFormat()) { case PixelFormat_Grayscale8: - memset(image.GetBuffer(), static_cast<uint8_t>(value), image.GetPitch() * image.GetHeight()); + SetInternal<uint8_t>(image, value); return; case PixelFormat_Grayscale16: - if (value == 0) - { - memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); - } - else - { - SetInternal<uint16_t>(image, value); - } + SetInternal<uint16_t>(image, value); return; case PixelFormat_Grayscale32: - if (value == 0) - { - memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); - } - else - { - SetInternal<uint32_t>(image, value); - } + SetInternal<uint32_t>(image, value); return; case PixelFormat_Grayscale64: - if (value == 0) - { - memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); - } - else - { - SetInternal<uint64_t>(image, value); - } + SetInternal<uint64_t>(image, value); return; case PixelFormat_SignedGrayscale16: - if (value == 0) - { - memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight()); - } - else - { - SetInternal<int16_t>(image, value); - } + SetInternal<int16_t>(image, value); return; case PixelFormat_Float32: @@ -797,11 +857,14 @@ throw OrthancException(ErrorCode_NotImplemented); } - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { uint8_t* q = reinterpret_cast<uint8_t*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { for (unsigned int i = 0; i < size; i++) { @@ -885,7 +948,7 @@ { case PixelFormat_Float32: { - assert(sizeof(float) == 32); + assert(sizeof(float) == 4); float a, b; GetMinMaxValueInternal<float>(a, b, image); minValue = a; @@ -1016,15 +1079,18 @@ void ImageProcessing::Invert(ImageAccessor& image) { + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + switch (image.GetFormat()) { case PixelFormat_Grayscale8: { - for (unsigned int y = 0; y < image.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { uint8_t* p = reinterpret_cast<uint8_t*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { *p = 255 - (*p); }