Changed alpha mask scaling to use Lanczos. 95/138995/4
authorDavid Steele <david.steele@samsung.com>
Fri, 14 Jul 2017 14:58:58 +0000 (15:58 +0100)
committerDavid Steele <david.steele@samsung.com>
Mon, 17 Jul 2017 10:36:35 +0000 (11:36 +0100)
Increases the quality significantly.

Changed the outer sampling method to handle both 4 channel and 1 channel images
(in case the alpha mask is L8 only).
With some slight blurring of the alpha mask during scaling, have had to choose
different pixels in the test cases.

Change-Id: I348300cb4a28b1c0814495cc10ff589196b339e8
Signed-off-by: David Steele <david.steele@samsung.com>
automated-tests/src/dali-adaptor/utc-Dali-PixelBuffer.cpp
platform-abstractions/portable/alpha-mask.cpp
platform-abstractions/portable/image-operations.cpp
platform-abstractions/portable/image-operations.h

index 4a83d8f..98173db 100644 (file)
@@ -326,11 +326,11 @@ int UtcDaliPixelBufferMask03(void)
   DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
   DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
 
-  // Test that an odd pixel in the second quadrant has full alpha value
-  DALI_TEST_EQUALS( buffer[23], 0xffu, TEST_LOCATION );
+  // Test that an odd pixel in the fourth quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[(6*10+7)*4+3], 0xffu, TEST_LOCATION );
 
-  // Test that an even pixel in the second quadrant has full alpha value
-  DALI_TEST_EQUALS( buffer[27], 0xffu, TEST_LOCATION );
+  // Test that an even pixel in the fourth quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[(6*10+8)*4+3], 0xffu, TEST_LOCATION );
 
   END_TEST;
 }
@@ -377,7 +377,41 @@ int UtcDaliPixelBufferMask05(void)
 
   unsigned int width = 20u;
   unsigned int height = 20u;
-  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::L8 );
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::RGBA8888 );
+  Mask1stQuadrant(maskData);
+
+  width = 10u;
+  height = 10u;
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, Pixel::RGBA8888 );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[39], 0xffu, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has no alpha value
+  DALI_TEST_EQUALS( buffer[27], 0x00u, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferMask06(void)
+{
+  TestApplication application;
+  tet_infoline("Test application of alpha mask to same size RGBA8888 image");
+
+  unsigned int width = 10u;
+  unsigned int height = 10u;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::RGBA8888 );
   Mask1stQuadrant(maskData);
 
   width = 10u;
@@ -396,7 +430,7 @@ int UtcDaliPixelBufferMask05(void)
   DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
 
   // Test that an odd pixel in the second quadrant has full alpha value
-  DALI_TEST_EQUALS( buffer[23], 0xffu, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[39], 0xffu, TEST_LOCATION );
 
   // Test that an even pixel in the second quadrant has no alpha value
   DALI_TEST_EQUALS( buffer[27], 0x00u, TEST_LOCATION );
index e930fc6..3fdb96d 100644 (file)
@@ -17,6 +17,8 @@
 #include "pixel-manipulation.h"
 #include "alpha-mask.h"
 #include "pixel-buffer-impl.h"
+#include <dali/public-api/images/image-operations.h> // For ImageDimensions
+#include <platform-abstractions/portable/image-operations.h>
 
 namespace Dali
 {
@@ -25,23 +27,41 @@ namespace Internal
 namespace Adaptor
 {
 
-
-void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
+PixelBufferPtr ResizeMask( const PixelBuffer& inMask, ImageDimensions outDimensions )
 {
-  const float rowFactor = float(mask.GetHeight()) / (1.0f * buffer.GetHeight());
-  const float colFactor = float(mask.GetWidth()) / (1.0f * buffer.GetWidth()) ;
+  PixelBufferPtr mask;
+
+  if( inMask.GetWidth() != outDimensions.GetWidth() || inMask.GetHeight() != outDimensions.GetHeight() )
+  {
+    mask = PixelBuffer::New( outDimensions.GetWidth(), outDimensions.GetHeight(), inMask.GetPixelFormat() );
+    ImageDimensions inDimensions( inMask.GetWidth(), inMask.GetHeight() );
 
-  int numSamples = 1;
-  if( mask.GetHeight() > buffer.GetHeight() || mask.GetWidth() > buffer.GetWidth() )
+    if( Pixel::GetBytesPerPixel( inMask.GetPixelFormat() ) == 4 )
+    {
+      Dali::Internal::Platform::LanczosSample4BPP( inMask.GetBuffer(), inDimensions,
+                                                   mask->GetBuffer(), outDimensions );
+    }
+    else if( inMask.GetPixelFormat() == Pixel::L8 )
+    {
+      Dali::Internal::Platform::LanczosSample1BPP( inMask.GetBuffer(), inDimensions,
+                                                   mask->GetBuffer(), outDimensions );
+    }
+  }
+  else
   {
-    numSamples = 4;
+    mask = const_cast<PixelBuffer*>(&inMask);
   }
+  return mask;
+}
 
+void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& inMask )
+{
   int srcAlphaByteOffset=0;
   int srcAlphaMask=0;
-  Dali::Pixel::Format srcPixelFormat = mask.GetPixelFormat();
+  Dali::Pixel::Format srcPixelFormat = inMask.GetPixelFormat();
+
+  PixelBufferPtr mask = ResizeMask( inMask, ImageDimensions( buffer.GetWidth(), buffer.GetHeight() ) );
 
-  Channel alphaChannel = ALPHA;
   if( Pixel::HasAlpha(srcPixelFormat) )
   {
     Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
@@ -49,7 +69,6 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
   else if( srcPixelFormat == Pixel::L8 )
   {
     srcAlphaMask=0xFF;
-    alphaChannel = LUMINANCE;
   }
 
   int destAlphaByteOffset=0;
@@ -57,8 +76,7 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
   Dali::Pixel::GetAlphaOffsetAndMask( buffer.GetPixelFormat(), destAlphaByteOffset, destAlphaMask );
 
   unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
-  int srcStride = mask.GetWidth() * srcBytesPerPixel;
-  unsigned char* srcBuffer = mask.GetBuffer();
+  unsigned char* srcBuffer = mask->GetBuffer();
   unsigned char* destBuffer = buffer.GetBuffer();
 
   unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel( buffer.GetPixelFormat() );
@@ -72,16 +90,8 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
   {
     for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
     {
-      if( numSamples == 1 )
-      {
-        srcOffset = floorf(row * rowFactor) * srcStride + floorf(col * colFactor) * srcBytesPerPixel;
-        unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
-        srcAlphaValue = float(alpha)/255.0f;
-      }
-      else
-      {
-        srcAlphaValue = ReadWeightedSample( srcBuffer, srcPixelFormat, srcStride, col*colFactor, row*rowFactor, mask.GetWidth(), mask.GetHeight(), alphaChannel );
-      }
+      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);
@@ -89,27 +99,20 @@ void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
       destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
       destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
 
+      srcOffset  += srcBytesPerPixel;
       destOffset += destBytesPerPixel;
     }
   }
 }
 
-PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuffer& mask )
+PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuffer& inMask )
 {
-  const float rowFactor = float(mask.GetHeight()) / (1.0f * buffer.GetHeight());
-  const float colFactor = float(mask.GetWidth()) / (1.0f * buffer.GetWidth()) ;
-
-  int numSamples = 1;
-  if( mask.GetHeight() > buffer.GetHeight() || mask.GetWidth() > buffer.GetWidth() )
-  {
-    numSamples = 4;
-  }
-
   // Set up source alpha offsets
   int srcAlphaByteOffset=0;
   int srcAlphaMask=0;
-  Dali::Pixel::Format srcPixelFormat = mask.GetPixelFormat();
-  Channel alphaChannel = ALPHA;
+  Dali::Pixel::Format srcPixelFormat = inMask.GetPixelFormat();
+
+  PixelBufferPtr mask = ResizeMask( inMask, ImageDimensions( buffer.GetWidth(), buffer.GetHeight() ) );
   if( Pixel::HasAlpha(srcPixelFormat) )
   {
     Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
@@ -117,12 +120,10 @@ PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuff
   else if( srcPixelFormat == Pixel::L8 )
   {
     srcAlphaMask=0xFF;
-    alphaChannel = LUMINANCE;
   }
 
   unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
-  int srcStride = mask.GetWidth() * srcBytesPerPixel;
-  unsigned char* srcBuffer = mask.GetBuffer();
+  unsigned char* srcBuffer = mask->GetBuffer();
 
   // Set up source color offsets
   Dali::Pixel::Format srcColorPixelFormat = buffer.GetPixelFormat();
@@ -138,7 +139,6 @@ PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuff
   PixelBufferPtr newPixelBuffer = PixelBuffer::New( buffer.GetWidth(), buffer.GetHeight(),
                                                     destPixelFormat );
   unsigned char* destBuffer = newPixelBuffer->GetBuffer();
-
   unsigned char* oldBuffer = buffer.GetBuffer();
 
   int srcAlphaOffset=0;
@@ -153,16 +153,8 @@ PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuff
   {
     for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
     {
-      if( numSamples == 1 )
-      {
-        srcAlphaOffset = floorf(row * rowFactor) * srcStride + floorf(col * colFactor) * srcBytesPerPixel;
-        unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
-        srcAlphaValue = float(alpha)/255.0f;
-      }
-      else
-      {
-        srcAlphaValue = ReadWeightedSample( srcBuffer, srcPixelFormat, srcStride, col*colFactor, row*rowFactor, mask.GetWidth(), mask.GetHeight(), alphaChannel );
-      }
+      unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
+      srcAlphaValue = float(alpha)/255.0f;
 
       ConvertColorChannelsToRGBA8888(oldBuffer, srcColorOffset, srcColorPixelFormat, destBuffer, destOffset );
 
@@ -181,6 +173,7 @@ PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuff
       destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
 
       srcColorOffset += srcColorBytesPerPixel;
+      srcAlphaOffset += srcBytesPerPixel;
       destOffset += destBytesPerPixel;
     }
   }
@@ -188,56 +181,6 @@ PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuff
   return newPixelBuffer;
 }
 
-
-float ReadWeightedSample( unsigned char* buffer, Pixel::Format pixelFormat, int stride, float x, float y, int width, int height, Channel alphaChannel )
-{
-  int srcRow = floorf( y );
-  int srcCol = floorf( x );
-
-  int bytesPerPixel = Dali::Pixel::GetBytesPerPixel( pixelFormat );
-  int srcOffset = srcRow * stride + srcCol * bytesPerPixel;
-  float samples[4];
-
-  samples[0] = ReadChannel( buffer + srcOffset, pixelFormat, alphaChannel );
-
-  if( srcCol < width-1 )
-  {
-    samples[1] = ReadChannel( buffer + srcOffset+bytesPerPixel, pixelFormat, alphaChannel );
-  }
-  else
-  {
-    samples[1] = samples[0];
-  }
-
-  if( srcRow < height-1 )
-  {
-    samples[2] = ReadChannel( buffer + stride + srcOffset, pixelFormat, alphaChannel );
-  }
-  else
-  {
-    samples[2] = samples[0];
-  }
-
-  if( srcRow < height-1 && srcCol < width-1 )
-  {
-    samples[3] = ReadChannel( buffer + stride + srcOffset + bytesPerPixel, pixelFormat, alphaChannel );
-  }
-  else
-  {
-    samples[3] = samples[2];
-  }
-
-  // Bilinear interpolation:
-  float weight[4];
-  weight[0] = float(srcRow+1.0f) - y;
-  weight[1] = y - float(srcRow);
-  weight[2] = float(srcCol+1.0f) - x;
-  weight[3] = x - float(srcCol);
-
-  return ( weight[2] * (samples[0] * weight[0] + samples[1] * weight[1]) +
-           weight[3] * (samples[2] * weight[0] + samples[3] * weight[1]) ) / 255.0f;
-}
-
 } //namespace Adaptor
 
 }// namespace Internal
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,
index dd46ee4..3b2ac9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -329,7 +329,7 @@ void LinearSample4BPP( const unsigned char * __restrict__ inPixels,
  * @brief Resamples the input image with the Lanczos algorithm.
  *
  * @pre @p inPixels must not alias @p outPixels. The input image should be a totally
- * separate buffer from the input one.
+ * separate buffer from the output buffer.
  *
  * @param[in] inPixels Pointer to the input image buffer.
  * @param[in] inputDimensions The input dimensions of the image.
@@ -340,6 +340,23 @@ void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
                         ImageDimensions inputDimensions,
                         unsigned char * __restrict__ outPixels,
                         ImageDimensions desiredDimensions );
+
+/**
+ * @brief Resamples the input image with the Lanczos algorithm.
+ *
+ * @pre @p inPixels must not alias @p outPixels. The input image should be a totally
+ * separate buffer from the output buffer.
+ *
+ * @param[in] inPixels Pointer to the input image buffer.
+ * @param[in] inputDimensions The input dimensions of the image.
+ * @param[out] outPixels Pointer to the output image buffer.
+ * @param[in] desiredDimensions The output dimensions of the image.
+ */
+void LanczosSample1BPP( const unsigned char * __restrict__ inPixels,
+                        ImageDimensions inputDimensions,
+                        unsigned char * __restrict__ outPixels,
+                        ImageDimensions desiredDimensions );
+
 /**@}*/
 
 /**