Revert "Revert "[4.0] Exposing Exif Image metadata""
[platform/core/uifw/dali-adaptor.git] / automated-tests / src / dali-adaptor-internal / utc-Dali-ImageOperations.cpp
index 7127312..ec480f0 100644 (file)
  */
 
 #include <dali-test-suite-utils.h>
-
 #include "platform-abstractions/portable/image-operations.h"
+#include <dali/devel-api/common/ref-counted-dali-vector.h>
+
+#include <sys/mman.h>
+#include <unistd.h>
 
 using namespace Dali::Internal::Platform;
 
@@ -344,19 +347,24 @@ int UtcDaliImageOperationsAveragePixelRGB565(void)
 /**
  * @brief Build a square bitmap, downscale it and assert the resulting bitmap has the right dimensions.
  */
-void TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::Format format, uint32_t sourceDimension, uint32_t targetDimension, uint32_t expectedDimension, const char * const location )
+void TestDownscaledBitmapHasRightDimensionsAndFormat(
+    Pixel::Format format,
+    uint32_t sourceDimension,
+    uint32_t targetDimension,
+    uint32_t expectedDimension,
+    const char * const location )
 {
-  ImageAttributes attributes;
-  attributes.SetScalingMode( ImageAttributes::ShrinkToFit );
-  attributes.SetSize( targetDimension, targetDimension );
+  ImageDimensions desired( targetDimension, targetDimension );
+  FittingMode::Type fittingMode( FittingMode::SHRINK_TO_FIT );
+  SamplingMode::Type samplingMode( SamplingMode::BOX );
+
+  Dali::Devel::PixelBuffer sourceBitmap = Dali::Devel::PixelBuffer::New( sourceDimension, sourceDimension, format );
 
-  Integration::BitmapPtr sourceBitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
-  sourceBitmap->GetPackedPixelsProfile()->ReserveBuffer( format, sourceDimension, sourceDimension, sourceDimension, sourceDimension );
+  Dali::Devel::PixelBuffer downScaled = DownscaleBitmap( sourceBitmap, desired, fittingMode, samplingMode );
 
-  Integration::BitmapPtr downScaled = DownscaleBitmap( *sourceBitmap, attributes );
-  DALI_TEST_EQUALS( downScaled->GetImageWidth(), expectedDimension, location );
-  DALI_TEST_EQUALS( downScaled->GetImageHeight(), expectedDimension, location );
-  DALI_TEST_EQUALS( downScaled->GetPixelFormat(), format, location );
+  DALI_TEST_EQUALS( downScaled.GetWidth(), expectedDimension, location );
+  DALI_TEST_EQUALS( downScaled.GetHeight(), expectedDimension, location );
+  DALI_TEST_EQUALS( downScaled.GetPixelFormat(), format, location );
 }
 
 /**
@@ -411,7 +419,7 @@ int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
   Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
   DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
   DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
-  DALI_TEST_EQUALS( check_4x4[0], 0x7f, TEST_LOCATION );
+  DALI_TEST_EQUALS( check_4x4[0], (unsigned char)0x7f, TEST_LOCATION );
 
   // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
   unsigned char single_4x4 [16 * 3] = {
@@ -423,7 +431,7 @@ int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
   Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
   DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
   DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
-  DALI_TEST_EQUALS( single_4x4[0], 0xf, TEST_LOCATION );
+  DALI_TEST_EQUALS( single_4x4[0], (unsigned char)0xf, TEST_LOCATION );
 
   // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
   // (white pixel at bottom-right of image)
@@ -436,7 +444,7 @@ int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
   Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
   DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
   DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
-  DALI_TEST_EQUALS( single_4x4_2[0], 0xf, TEST_LOCATION );
+  DALI_TEST_EQUALS( single_4x4_2[0], (unsigned char)0xf, TEST_LOCATION );
 
   // Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
 
@@ -845,7 +853,7 @@ int UtcDaliImageOperationsHalveScanlineInPlaceRGBA8888(void)
   // Test for no beyond-bounds writes:
   for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
   {
-    DALI_TEST_EQUALS( reference[i],  0xEEEEEEEE, TEST_LOCATION );
+    DALI_TEST_EQUALS( reference[i],  (uint32_t)0xEEEEEEEE, TEST_LOCATION );
   }
 
   END_TEST;
@@ -875,7 +883,7 @@ int UtcDaliImageOperationsHalveScanlineInPlaceRGB565(void)
   // Test for no beyond-bounds writes:
   for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
   {
-    DALI_TEST_EQUALS( reference[i],  0xEEEE, TEST_LOCATION );
+    DALI_TEST_EQUALS( reference[i],  (uint16_t)0xEEEE, TEST_LOCATION );
   }
 
   END_TEST;
@@ -1075,8 +1083,344 @@ int UtcDaliImageOperationsAverageScanlinesRGB565(void)
   }
 
   // Check for buffer overrun:
-  DALI_TEST_EQUALS( outputBuffer[arrayLength], 0xDEAD, TEST_LOCATION );
-  DALI_TEST_EQUALS( outputBuffer[arrayLength+1], 0xDEAD, TEST_LOCATION );
+  DALI_TEST_EQUALS( outputBuffer[arrayLength], (uint16_t)0xDEAD, TEST_LOCATION );
+  DALI_TEST_EQUALS( outputBuffer[arrayLength+1], (uint16_t)0xDEAD, TEST_LOCATION );
+
+  END_TEST;
+}
+
+namespace
+{
+
+void MakeSingleColorImageRGBA8888( unsigned int width, unsigned int height, uint32_t *inputImage )
+{
+  const uint32_t inPixel = PixelRGBA8888( 255, 192, 128, 64 );
+  for( unsigned int i = 0; i < width * height; ++i )
+  {
+    inputImage[i] = inPixel;
+  }
+}
+
+/*
+ * @brief Make an image with a checkerboard pattern.
+ * @note This is an easy pattern to scan for correctness after a downscaling test.
+ */
+Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > MakeCheckerboardImageRGBA8888( unsigned int width,  unsigned int height, unsigned int checkerSize )
+{
+  const unsigned int imageWidth = width * checkerSize;
+  const unsigned int imageHeight = height * checkerSize;
+  Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = new Dali::RefCountedVector<uint32_t>;
+  image->GetVector().Resize( imageWidth * imageHeight );
+
+  uint32_t rowColor = 0xffffffff;
+  for( unsigned int cy = 0; cy < height; ++cy )
+  {
+    rowColor = rowColor == 0xffffffff ? 0xff000000 : 0xffffffff;
+    uint32_t checkColor = rowColor;
+    for( unsigned int cx = 0; cx < width; ++cx )
+    {
+      checkColor = checkColor == 0xffffffff ? 0xff000000 : 0xffffffff;
+      uint32_t paintedColor = checkColor;
+      // Draw 3 special case checks as r,g,b:
+      if(cx == 0 && cy == 0)
+      {
+        paintedColor = 0xff0000ff;// Red
+      }
+      else if(cx == 7 && cy == 0)
+      {
+        paintedColor = 0xff00ff00;// Green
+      }
+      else if(cx == 7 && cy == 7)
+      {
+        paintedColor = 0xffff0000;// blue
+      }
+      uint32_t * check = &image->GetVector()[ (cy * checkerSize * imageWidth) + (cx * checkerSize)];
+      for( unsigned int py = 0; py < checkerSize; ++py )
+      {
+        uint32_t * checkLine = check +  py * imageWidth;
+        for( unsigned int px = 0; px < checkerSize; ++px )
+        {
+          checkLine[px] = paintedColor;
+        }
+      }
+    }
+  }
+
+  return image;
+}
+
+}
+
+/**
+ * @brief Test the right pixels are generated when downsampling a checkerboard into a small image.
+ */
+int UtcDaliImageOperationsPointSampleCheckerboardRGBA888(void)
+{
+  Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = MakeCheckerboardImageRGBA8888( 8, 8, 32 );
+  const unsigned int desiredWidth = 8;
+  const unsigned int desiredHeight = 8;
+
+  uint32_t outputImage[ desiredWidth * desiredHeight ];
+
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) &image->GetVector()[0], 256, 256, (unsigned char*) outputImage, desiredWidth, desiredHeight );
+
+  DALI_TEST_EQUALS( outputImage[0], (uint32_t)0xff0000ff, TEST_LOCATION ); // < Red corner pixel
+  DALI_TEST_EQUALS( outputImage[7], (uint32_t)0xff00ff00, TEST_LOCATION ); // < Green corner pixel
+  DALI_TEST_EQUALS( outputImage[8*8-1], (uint32_t)0xffff0000, TEST_LOCATION ); // < Blue corner pixel
+
+  DALI_TEST_EQUALS( outputImage[1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+
+  // Second scanline:
+  DALI_TEST_EQUALS( outputImage[8+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[8+1], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[8+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[8+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[8+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[8+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[8+6], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[8+7], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+
+  // Third scanline:
+  DALI_TEST_EQUALS( outputImage[16+0], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[16+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[16+2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[16+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[16+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[16+5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[16+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[16+7], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+
+  // ... could do more scanlines (there are 8)
+
+  // Sample a few more pixels:
+
+  // Diagonals:
+  DALI_TEST_EQUALS( outputImage[24+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[32+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[40+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[48+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
+  DALI_TEST_EQUALS( outputImage[24+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[32+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[40+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[48+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+  DALI_TEST_EQUALS( outputImage[56+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
+
+  END_TEST;
+}
+
+/**
+ * @brief Test that a scaling preserves input color in destination image.
+ */
+int UtcDaliImageOperationsPointSampleRGBA888PixelsCorrectColor(void)
+{
+  const unsigned int inputWidth = 137;
+  const unsigned int inputHeight = 571;
+  const unsigned int desiredWidth = 59;
+  const unsigned int desiredHeight = 257;
+
+  uint32_t inputImage[ inputWidth * inputHeight ];
+  MakeSingleColorImageRGBA8888( inputWidth, inputHeight, inputImage );
+
+  const size_t outputBufferSize = desiredWidth * desiredHeight;
+  std::vector< uint32_t > buffer;
+  buffer.resize( outputBufferSize );
+  uint32_t* outputImage = &buffer[0];
+
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, inputWidth, inputHeight, (unsigned char*) outputImage, desiredWidth, desiredHeight );
+
+  // Check that all the output pixels are the right color:
+  const uint32_t reference = inputImage[ inputWidth * inputHeight / 2];
+  unsigned int differentColorCount = 0;
+  for( unsigned int i = 0; i < desiredWidth * desiredHeight; ++i )
+  {
+    if( outputImage[i] != reference )
+    {
+      ++differentColorCount;
+    }
+  }
+
+  DALI_TEST_EQUALS( 0U, differentColorCount, TEST_LOCATION );
+
+  END_TEST;
+}
+
+/**
+ * @brief Test that scaling down to a 1x1 image works.
+ */
+int UtcDaliImageOperationsPointSampleRGBA888ScaleToSinglePixel(void)
+{
+  const unsigned int desiredWidth = 1;
+  const unsigned int desiredHeight = 1;
+
+  uint32_t inputImage[ 1024 * 1024 ];
+  MakeSingleColorImageRGBA8888( 1024, 1024, inputImage );
+  uint32_t outputImage = 0;
+
+  // Try several different starting image sizes:
+
+  // 1x1 -> 1x1:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,    1,    1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // Single-pixel wide tall stripe:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,    1, 1024, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // Single-pixel tall, wide strip:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1024,    1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // Square mid-size image:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,  103,  103, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // Wide mid-size image:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,  313,  79, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // Tall mid-size image:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,   53,  467, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
+  outputImage = 0;
+
+  // 0 x 0 input image (make sure output not written to):
+  outputImage = 0xDEADBEEF;
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,    0,    0, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
+  DALI_TEST_EQUALS( outputImage, (uint32_t)0xDEADBEEF, TEST_LOCATION );
+  outputImage = 0;
+
+  END_TEST;
+}
+
+/**
+ * @brief Test that downsampling to 0 - area images is a NOP and does not modify the destination.
+ * (edge-case)
+ */
+int UtcDaliImageOperationsPointSampleRGBA888N(void)
+{
+  uint32_t inputImage[ 128 * 128 ];
+  MakeSingleColorImageRGBA8888( 128, 128, inputImage );
+  uint32_t outputImage[ 128 * 128 ];
+  memset( outputImage, 0xaa, 128 * 128 * sizeof(uint32_t) );
+
+  // Try several different starting image sizes:
+
+  // 1x1 -> 1x1:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,   1,   1, (unsigned char*) outputImage, 0, 0 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // Single-pixel wide tall stripe:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,   1, 102, (unsigned char*) outputImage, 0, 33 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // Single-pixel tall, wide strip:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 102,   1, (unsigned char*) outputImage, 0, 67 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // Square mid-size image:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 103, 103, (unsigned char*) outputImage, 21, 0 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // Wide mid-size image to 0 height
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 313,  79, (unsigned char*) outputImage, 99, 0 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // Tall mid-size image to 0 height, over width
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,  53,  46, (unsigned char*) outputImage, 9999, 0 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  // 0 x 0 input image:
+  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage,   0,   0, (unsigned char*) outputImage, 200, 99 );
+  DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
+
+  END_TEST;
+}
+
+/**
+ * @brief Test the small int (x,y) tuple.
+ */
+int UtcDaliImageOperationsUint16Pair(void)
+{
+  Uint16Pair vec1( 2, 3 );
+
+  DALI_TEST_EQUALS( vec1.GetWidth(), (uint16_t)2, TEST_LOCATION );
+  DALI_TEST_EQUALS( vec1.GetX(),     (uint16_t)2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( vec1.GetHeight(), (uint16_t)3, TEST_LOCATION );
+  DALI_TEST_EQUALS( vec1.GetY(),      (uint16_t)3, TEST_LOCATION );
+
+  Uint16Pair vec1Copy = vec1;
+
+  DALI_TEST_EQUALS( vec1Copy.GetWidth(), (uint16_t)2, TEST_LOCATION );
+  DALI_TEST_EQUALS( vec1Copy.GetX(),     (uint16_t)2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( vec1Copy.GetHeight(), (uint16_t)3, TEST_LOCATION );
+  DALI_TEST_EQUALS( vec1Copy.GetY(),      (uint16_t)3, TEST_LOCATION );
+
+  Uint16Pair vec2( 65535u, 65535u );
+
+  DALI_TEST_EQUALS( vec2.GetX(), (uint16_t)65535u, TEST_LOCATION );
+  DALI_TEST_EQUALS( vec2.GetY(), (uint16_t)65535u, TEST_LOCATION );
+
+  END_TEST;
+}
+
+/**
+ * @brief Test the four-tap linear blending for single-byte modes.
+ */
+int UtcDaliImageOperationsBilinearFilter1BPP(void)
+{
+  // Zeros blend to zero:
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 0 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 32768, 0 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 65535, 0 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 65535 ), TEST_LOCATION );
+
+  // Ones and zeros average to 0.5:
+  DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 255, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 0, 255, 0, 255, 32768, 32768 ), TEST_LOCATION );
+
+  // Quarters ones average to 0.25:
+  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 255, 0, 0, 0, 32768, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 255, 0, 0, 32768, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 255, 0, 32768, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
+
+  // Horizontal blends:
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, 32768 ), TEST_LOCATION );
+  for( unsigned y = 0; y < 65536u; y += 256 )
+  {
+    // Vertical blends don't change result in this case as there is no vertical gradient in inputs:
+    DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, y ), TEST_LOCATION );
+  }
+  DALI_TEST_EQUALS( 5u, BilinearFilter1Component( 0, 255, 0, 255, 1233, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 67u, BilinearFilter1Component( 0, 255, 0, 255, 17291, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 123u, BilinearFilter1Component( 0, 255, 0, 255, 31671, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 184u, BilinearFilter1Component( 0, 255, 0, 255, 47231, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 207u, BilinearFilter1Component( 0, 255, 0, 255, 53129, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 239u, BilinearFilter1Component( 0, 255, 0, 255, 61392, 32768 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 255, 0, 255, 65535, 32768 ), TEST_LOCATION );
+
+  // Vertical Blends:
+  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 0 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 60u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 15379 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 130u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 33451 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 186u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 47836 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 244u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 62731 ), TEST_LOCATION );
+  DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 65535 ), TEST_LOCATION );
 
   END_TEST;
 }