Multiply the Alpha of mask to the premultiplied image 76/209676/6
authorSunghyun kim <scholb.kim@samsung.com>
Wed, 10 Jul 2019 03:41:46 +0000 (12:41 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Tue, 16 Jul 2019 01:22:46 +0000 (01:22 +0000)
After move MultiplyColorByAlpha() from main thread to resource thread, MultiplyColorByAlpha() is called first than ApplyMask().
In this case, the alpha value of mask is not multiplied properly to other channels in the image.
Therefore, if image is premultiplied, the other channels of the image need to multiply by alpha of mask.

Change-Id: I60c056460537db604566f080302be09a6f88d047

dali/internal/imaging/common/alpha-mask.cpp

index c6cfe31..e2e0b25 100644 (file)
@@ -44,7 +44,8 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
 
   int destAlphaByteOffset=0;
   int destAlphaMask=0;
-  Dali::Pixel::GetAlphaOffsetAndMask( buffer.GetPixelFormat(), destAlphaByteOffset, destAlphaMask );
+  Dali::Pixel::Format destPixelFormat = buffer.GetPixelFormat();
+  Dali::Pixel::GetAlphaOffsetAndMask( destPixelFormat, destAlphaByteOffset, destAlphaMask );
 
   unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
   unsigned char* srcBuffer = mask.GetBuffer();
@@ -57,21 +58,49 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
 
   float srcAlphaValue = 1.0f;
 
-  for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
+  // if image is premultiplied, the other channels of the image need to multiply by alpha.
+  if( buffer.IsAlphaPreMultiplied() )
   {
-    for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
+    for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
     {
-      unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
-      srcAlphaValue = float(alpha)/255.0f;
+      for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
+      {
+        auto srcAlpha      = ReadChannel( srcBuffer + srcOffset, srcPixelFormat, Adaptor::ALPHA);
+        auto destRed       = ReadChannel( destBuffer + destOffset, destPixelFormat, Adaptor::RED);
+        auto destGreen     = ReadChannel( destBuffer + destOffset, destPixelFormat, Adaptor::GREEN);
+        auto destBlue      = ReadChannel( destBuffer + destOffset, destPixelFormat, Adaptor::BLUE);
+        auto destLuminance = ReadChannel( destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE);
+        auto destAlpha     = ReadChannel( destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA);
+
+        WriteChannel( destBuffer + destOffset, destPixelFormat, Adaptor::RED, destRed*srcAlpha / 255 );
+        WriteChannel( destBuffer + destOffset, destPixelFormat, Adaptor::GREEN, destGreen*srcAlpha/255 );
+        WriteChannel( destBuffer + destOffset, destPixelFormat, Adaptor::BLUE, destBlue*srcAlpha/255 );
+        WriteChannel( destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE, destLuminance*srcAlpha/255 );
+        WriteChannel( destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA, destAlpha*srcAlpha/255 );
+
+        srcOffset  += srcBytesPerPixel;
+        destOffset += destBytesPerPixel;
+      }
+    }
+  }
+  else
+  {
+    for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
+    {
+      for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
+      {
+        unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
+        srcAlphaValue = float(alpha)/255.0f;
 
-      unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
-      float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
-      destAlpha = destAlphaValue;
-      destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
-      destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
+        unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
+        float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
+        destAlpha = destAlphaValue;
+        destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
+        destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
 
-      srcOffset  += srcBytesPerPixel;
-      destOffset += destBytesPerPixel;
+        srcOffset  += srcBytesPerPixel;
+        destOffset += destBytesPerPixel;
+      }
     }
   }
 }