Changed alpha mask scaling to use Lanczos.
[platform/core/uifw/dali-adaptor.git] / platform-abstractions / portable / image-operations.cpp
index 81936fa..f759d39 100644 (file)
@@ -1523,45 +1523,51 @@ void LinearSample4BPP( const unsigned char * __restrict__ inPixels,
   LinearSampleGeneric<Pixel4Bytes, BilinearFilter4Bytes, true>( inPixels, inputDimensions, outPixels, desiredDimensions );
 }
 
-void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
-                        ImageDimensions inputDimensions,
-                        unsigned char * __restrict__ outPixels,
-                        ImageDimensions desiredDimensions )
+void LanczosSample( const unsigned char * __restrict__ inPixels,
+                    ImageDimensions inputDimensions,
+                    unsigned char * __restrict__ outPixels,
+                    ImageDimensions desiredDimensions,
+                    int numChannels, bool hasAlpha )
 {
   // Got from the test.cpp of the ImageResampler lib.
   const float ONE_DIV_255 = 1.0f / 255.0f;
   const int MAX_UNSIGNED_CHAR = std::numeric_limits<uint8_t>::max();
   const int LINEAR_TO_SRGB_TABLE_SIZE = 4096;
-  const int ALPHA_CHANNEL = 3;
-  const int NUMBER_OF_CHANNELS = 4;
-
-  float srgbToLinear[MAX_UNSIGNED_CHAR + 1];
-  for( int i = 0; i <= MAX_UNSIGNED_CHAR; ++i )
-  {
-    srgbToLinear[i] = pow( static_cast<float>( i ) * ONE_DIV_255, DEFAULT_SOURCE_GAMMA );
-  }
+  const int ALPHA_CHANNEL = hasAlpha ? (numChannels-1) : 0;
 
-  unsigned char linearToSrgb[LINEAR_TO_SRGB_TABLE_SIZE];
+  static bool loadColorSpaces = true;
+  static float srgbToLinear[MAX_UNSIGNED_CHAR + 1];
+  static unsigned char linearToSrgb[LINEAR_TO_SRGB_TABLE_SIZE];
 
-  const float invLinearToSrgbTableSize = 1.0f / static_cast<float>( LINEAR_TO_SRGB_TABLE_SIZE );
-  const float invSourceGamma = 1.0f / DEFAULT_SOURCE_GAMMA;
-
-  for( int i = 0; i < LINEAR_TO_SRGB_TABLE_SIZE; ++i )
+  if( loadColorSpaces ) // Only create the color space conversions on the first execution
   {
-    int k = static_cast<int>( 255.0f * pow( static_cast<float>( i ) * invLinearToSrgbTableSize, invSourceGamma ) + 0.5f );
-    if( k < 0 )
+    loadColorSpaces = false;
+
+    for( int i = 0; i <= MAX_UNSIGNED_CHAR; ++i )
     {
-      k = 0;
+      srgbToLinear[i] = pow( static_cast<float>( i ) * ONE_DIV_255, DEFAULT_SOURCE_GAMMA );
     }
-    else if( k > MAX_UNSIGNED_CHAR )
+
+    const float invLinearToSrgbTableSize = 1.0f / static_cast<float>( LINEAR_TO_SRGB_TABLE_SIZE );
+    const float invSourceGamma = 1.0f / DEFAULT_SOURCE_GAMMA;
+
+    for( int i = 0; i < LINEAR_TO_SRGB_TABLE_SIZE; ++i )
     {
-      k = MAX_UNSIGNED_CHAR;
+      int k = static_cast<int>( 255.0f * pow( static_cast<float>( i ) * invLinearToSrgbTableSize, invSourceGamma ) + 0.5f );
+      if( k < 0 )
+      {
+        k = 0;
+      }
+      else if( k > MAX_UNSIGNED_CHAR )
+      {
+        k = MAX_UNSIGNED_CHAR;
+      }
+      linearToSrgb[i] = static_cast<unsigned char>( k );
     }
-    linearToSrgb[i] = static_cast<unsigned char>( k );
   }
 
-  Resampler* resamplers[NUMBER_OF_CHANNELS] = { 0 };
-  Vector<float> samples[NUMBER_OF_CHANNELS];
+  Resampler* resamplers[numChannels];
+  Vector<float> samples[numChannels];
 
   const int srcWidth = inputDimensions.GetWidth();
   const int srcHeight = inputDimensions.GetHeight();
@@ -1583,7 +1589,7 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
                                  FILTER_SCALE,   // src_x_ofs,
                                  FILTER_SCALE ); // src_y_ofs. Offset input image by specified amount (fractional values okay).
   samples[0].Resize( srcWidth );
-  for( int i = 1; i < NUMBER_OF_CHANNELS; ++i )
+  for( int i = 1; i < numChannels; ++i )
   {
     resamplers[i] = new Resampler( srcWidth,
                                    srcHeight,
@@ -1600,8 +1606,8 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
     samples[i].Resize( srcWidth );
   }
 
-  const int srcPitch = srcWidth * NUMBER_OF_CHANNELS;
-  const int dstPitch = dstWidth * NUMBER_OF_CHANNELS;
+  const int srcPitch = srcWidth * numChannels;
+  const int dstPitch = dstWidth * numChannels;
   int dstY = 0;
 
   for( int srcY = 0; srcY < srcHeight; ++srcY )
@@ -1610,9 +1616,9 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
 
     for( int x = 0; x < srcWidth; ++x )
     {
-      for( int c = 0; c < NUMBER_OF_CHANNELS; ++c )
+      for( int c = 0; c < numChannels; ++c )
       {
-        if( c == ALPHA_CHANNEL )
+        if( c == ALPHA_CHANNEL && hasAlpha )
         {
           samples[c][x] = *pSrc++ * ONE_DIV_255;
         }
@@ -1623,7 +1629,7 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
       }
     }
 
-    for( int c = 0; c < NUMBER_OF_CHANNELS; ++c )
+    for( int c = 0; c < numChannels; ++c )
     {
       if( !resamplers[c]->put_line( &samples[c][0] ) )
       {
@@ -1634,7 +1640,7 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
     for(;;)
     {
       int compIndex;
-      for( compIndex = 0; compIndex < NUMBER_OF_CHANNELS; ++compIndex )
+      for( compIndex = 0; compIndex < numChannels; ++compIndex )
       {
         const float* pOutputSamples = resamplers[compIndex]->get_line();
         if( !pOutputSamples )
@@ -1642,7 +1648,7 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
           break;
         }
 
-        const bool isAlphaChannel = ( compIndex == ALPHA_CHANNEL );
+        const bool isAlphaChannel = ( compIndex == ALPHA_CHANNEL && hasAlpha );
         DALI_ASSERT_DEBUG( dstY < dstHeight );
         unsigned char* pDst = &outPixels[dstY * dstPitch + compIndex];
 
@@ -1675,10 +1681,10 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
             *pDst = linearToSrgb[j];
           }
 
-          pDst += NUMBER_OF_CHANNELS;
+          pDst += numChannels;
         }
       }
-      if( compIndex < NUMBER_OF_CHANNELS )
+      if( compIndex < numChannels )
       {
         break;
       }
@@ -1688,12 +1694,29 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
   }
 
   // Delete the resamplers.
-  for( int i = 0; i < NUMBER_OF_CHANNELS; ++i )
+  for( int i = 0; i < numChannels; ++i )
   {
     delete resamplers[i];
   }
 }
 
+void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
+                        ImageDimensions inputDimensions,
+                        unsigned char * __restrict__ outPixels,
+                        ImageDimensions desiredDimensions )
+{
+  LanczosSample( inPixels, inputDimensions, outPixels, desiredDimensions, 4, true );
+}
+
+void LanczosSample1BPP( const unsigned char * __restrict__ inPixels,
+                        ImageDimensions inputDimensions,
+                        unsigned char * __restrict__ outPixels,
+                        ImageDimensions desiredDimensions )
+{
+  // For L8 images
+  LanczosSample( inPixels, inputDimensions, outPixels, desiredDimensions, 1, false );
+}
+
 // Dispatch to a format-appropriate linear sampling function:
 void LinearSample( const unsigned char * __restrict__ inPixels,
                    ImageDimensions inDimensions,