2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-test-suite-utils.h>
19 #include "platform-abstractions/portable/image-operations.h"
20 #include <dali/devel-api/common/ref-counted-dali-vector.h>
25 using namespace Dali::Internal::Platform;
31 * @brief Generate a random integer between zero and the parameter passed in.
33 uint32_t RandomInRange( uint32_t max )
35 const uint32_t randToMax = lrand48() % (max + 1);
40 * @brief Random number representable in an 8 bit color component.
42 inline uint32_t RandomComponent8()
44 return RandomInRange( 255u );
48 * @brief Random number representable in a 5 bit color component.
50 inline uint32_t RandomComponent5()
52 return RandomInRange( 31u );
56 * @brief Random number representable in a 6 bit color component.
58 inline uint32_t RandomComponent6()
60 return RandomInRange( 63u );
64 * @brief RGBA8888 Pixels from separate color components.
66 inline uint32_t PixelRGBA8888( uint32_t r, uint32_t g, uint32_t b, uint32_t a )
68 return (r << 24) + (g << 16) + (b << 8) + a;
72 * @brief RGB565 Pixels from color components in the low bits of passed-in words.
74 inline uint16_t PixelRGB565( uint32_t r, uint32_t g, uint32_t b )
76 return (r << 11) + (g << 5) + b;
80 * @brief RGBA8888 Pixels with random color components.
82 inline uint32_t RandomPixelRGBA8888( )
84 const uint32_t randomPixel = PixelRGBA8888( RandomComponent8(), RandomComponent8(), RandomComponent8(), RandomComponent8() );
89 * @brief Return a hash over a set of pixels.
91 * Used to check a buffer of pixels is unmodified by an operation given inputs
92 * that should mean that it is not changed.
94 inline uint32_t HashPixels( const uint32_t* const pixels, unsigned int numPixels )
98 for( unsigned int i = 0; i < numPixels; ++i )
100 hash = hash * 33 + pixels[i];
107 * @brief Build some dummy scanlines to exercise scanline averaging code on.
109 void SetupScanlineForHalvingTestsRGBA8888( size_t scanlineLength, Dali::Vector<uint32_t>& scanline, Dali::Vector<uint32_t>& reference )
111 scanline.Resize( scanlineLength );
112 reference.Reserve( scanlineLength / 2 + 32 );
114 // Prepare some random pixels:
115 srand( 19 * 23 * 47 * 53 );
116 for( size_t i = 0; i < scanlineLength / 2; ++i )
118 // Generate random colors:
119 const uint32_t red1 = RandomComponent8();
120 const uint32_t red2 = RandomComponent8();
121 const uint32_t green1 = RandomComponent8();
122 const uint32_t green2 = RandomComponent8();
123 const uint32_t blue1 = RandomComponent8();
124 const uint32_t blue2 = RandomComponent8();
125 const uint32_t alpha1 = RandomComponent8();
126 const uint32_t alpha2 = RandomComponent8();
128 // The average of these pixels should equal the reference:
129 scanline[i * 2] = PixelRGBA8888( red1, green1, blue1, alpha1 );
130 scanline[i * 2 + 1] = PixelRGBA8888( red2, green2, blue2, alpha2 );
132 // Average the two pixels manually as a reference:
133 reference.PushBack( PixelRGBA8888( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u ) );
136 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
138 reference[i] = 0xEEEEEEEE;
143 * @brief Build some dummy scanlines to exercise scanline averaging code on.
145 void SetupScanlineForHalvingTestsRGB565( size_t scanlineLength, Dali::Vector<uint16_t>& scanline, Dali::Vector<uint16_t>& reference )
147 scanline.Resize( scanlineLength );
148 reference.Reserve( scanlineLength / 2 + 32 );
150 // Prepare some random pixels:
151 srand48( 19 * 23 * 47 * 53 );
152 for( size_t i = 0; i < scanlineLength / 2; ++i )
154 // Generate random colors:
155 const uint32_t red1 = RandomComponent5();
156 const uint32_t red2 = RandomComponent5();
157 const uint32_t green1 = RandomComponent6();
158 const uint32_t green2 = RandomComponent6();
159 const uint32_t blue1 = RandomComponent5();
160 const uint32_t blue2 = RandomComponent5();
162 // The average of these pixels should equal the reference:
163 scanline[i * 2] = PixelRGB565( red1, green1, blue1 );
164 scanline[i * 2 + 1] = PixelRGB565( red2, green2, blue2 );
166 // Average the two pixels manually as a reference:
167 reference.PushBack( PixelRGB565( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u ) );
170 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
172 reference[i] = 0xEEEE;
177 * @brief Build some dummy scanlines to exercise scanline averaging code on.
179 void SetupScanlineForHalvingTests2Bytes( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
181 scanline.Resize( scanlineLength * 2 );
182 reference.Reserve( scanlineLength + 32 );
184 // Prepare some random pixels:
185 srand48( 19 * 23 * 47 * 53 * 59 );
186 for( size_t i = 0; i < scanlineLength / 2; ++i )
188 // Generate random colors:
189 const uint32_t c11 = RandomComponent8();
190 const uint32_t c12 = RandomComponent8();
191 const uint32_t c21 = RandomComponent8();
192 const uint32_t c22 = RandomComponent8();
194 // The average of these pixels should equal the reference:
195 scanline[i * 4] = c11;
196 scanline[i * 4 + 1] = c12;
197 scanline[i * 4 + 2] = c21;
198 scanline[i * 4 + 3] = c22;
200 // Average the two pixels manually as a reference:
201 reference.PushBack( (c11 + c21) >> 1u );
202 reference.PushBack( (c12 + c22) >> 1u );
205 for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
212 * @brief Build some dummy 1 byte per pixel scanlines to exercise scanline averaging code on.
214 void SetupScanlineForHalvingTests1Byte( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
216 scanline.Resize( scanlineLength * 2 );
217 reference.Reserve( scanlineLength + 32 );
219 // Prepare some random pixels:
220 srand48( 19 * 23 * 47 * 53 * 63 );
221 for( size_t i = 0; i < scanlineLength / 2; ++i )
223 // Generate random colors:
224 const uint32_t c1 = RandomComponent8();
225 const uint32_t c2 = RandomComponent8();
227 // The average of these pixels should equal the reference:
228 scanline[i * 2] = c1;
229 scanline[i * 2 + 1] = c2;
231 // Average the two pixels manually as a reference:
232 reference.PushBack( (c1 + c2) >> 1u );
236 for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
243 * @brief Build some dummy scanlines to exercise vertical averaging code on.
245 * All tested formats bar RGB565 can share this setup.
247 void SetupScanlinesRGBA8888( size_t scanlineLength, Dali::Vector<uint32_t>& scanline1, Dali::Vector<uint32_t>& scanline2, Dali::Vector<uint32_t>& reference, Dali::Vector<uint32_t>& output )
249 scanline1.Reserve( scanlineLength );
250 scanline2.Reserve( scanlineLength );
251 reference.Reserve( scanlineLength + 32 );
252 output.Reserve( scanlineLength + 32 );
254 for( size_t i = scanlineLength; i < output.Capacity(); ++i )
256 output[i] = 0xDEADBEEF;
257 reference[i] = 0xDEADBEEF;
260 // Prepare some random pixels:
261 srand48( 19 * 23 * 47 );
262 for( size_t i = 0; i < scanlineLength; ++i )
264 // Generate random colors:
265 const uint32_t red1 = RandomComponent8();
266 const uint32_t red2 = RandomComponent8();
267 const uint32_t green1 = RandomComponent8();
268 const uint32_t green2 = RandomComponent8();
269 const uint32_t blue1 = RandomComponent8();
270 const uint32_t blue2 = RandomComponent8();
271 const uint32_t alpha1 = RandomComponent8();
272 const uint32_t alpha2 = RandomComponent8();
274 // The average of these pixels should equal the reference:
275 scanline1.PushBack( PixelRGBA8888( red1, green1, blue1, alpha1 ) );
276 scanline2.PushBack( PixelRGBA8888( red2, green2, blue2, alpha2 ) );
278 // Average the two pixels manually as a reference:
279 reference.PushBack( PixelRGBA8888( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u ) );
284 * @brief Compares a scanline of interest to a reference, testing each pixel is the same.
286 void MatchScanlinesRGBA8888( Dali::Vector<uint32_t>& reference, Dali::Vector<uint32_t>& output, size_t& numMatches, const char * const location )
289 for( size_t i = 0, length = reference.Capacity(); i < length; ++i )
291 DALI_TEST_EQUALS( output[i], reference[i], location );
292 numMatches += output[i] == reference[i];
296 } //< namespace unnamed
299 * @brief Test component averaging code.
301 int UtcDaliImageOperationsAverageComponent(void)
303 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0u, 0u ), 0u, TEST_LOCATION );
304 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 1u, 1u ), 1u, TEST_LOCATION );
305 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0xffffffffu >> 1u, 0xffffffffu >> 1u ), 0xffffffffu >> 1u, TEST_LOCATION );
306 const unsigned int avg3 = Dali::Internal::Platform::AverageComponent( 0xfffffffeu, 1u );
307 DALI_TEST_EQUALS( avg3, 0x7fffffffu, TEST_LOCATION );
308 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 255u, 255u ), 255u, TEST_LOCATION );
309 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 512u, 0u ), 256u, TEST_LOCATION );
310 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 511u, 0u ), 255u, TEST_LOCATION );
311 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 510u, 0u ), 255u, TEST_LOCATION );
312 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 509u, 0u ), 254u, TEST_LOCATION );
313 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0u, 509u ), 254u, TEST_LOCATION );
318 * @brief Test Pixel averaging code.
320 int UtcDaliImageOperationsAveragePixelRGBA8888(void)
322 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0u, 0u ), 0u, TEST_LOCATION );
323 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0x01010101, 0x01010101 ), 0x01010101u, TEST_LOCATION );
324 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0x01010101, 0x03030303 ), 0x02020202u, TEST_LOCATION );
325 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0xffffffff, 0xffffffff ), 0xffffffffu, TEST_LOCATION );
326 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0xffffffff, 0u ), 0x7f7f7f7fu, TEST_LOCATION );
331 * @brief Test RGBA565 pixel averaging function.
333 int UtcDaliImageOperationsAveragePixelRGB565(void)
335 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0u, 0u ), 0u, TEST_LOCATION );
336 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0xf800u ), 0xf800u, TEST_LOCATION );
337 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0x800u ), 1u << 15, TEST_LOCATION );
338 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x7e0u, 0x7e0u ), 0x7e0u, TEST_LOCATION );
339 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x7e0u, 0x20u ), 1u << 10, TEST_LOCATION );
340 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x1f, 0x1f ), 0x1fu, TEST_LOCATION );
341 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x1f, 0x1 ), 1u << 4, TEST_LOCATION );
342 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0x7e0u ), 0x7800u + 0x3e0u, TEST_LOCATION );
343 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xffff, 0xffff ), 0xffffu, TEST_LOCATION );
348 * @brief Build a square bitmap, downscale it and assert the resulting bitmap has the right dimensions.
350 void TestDownscaledBitmapHasRightDimensionsAndFormat(
351 Pixel::Format format,
352 uint32_t sourceDimension,
353 uint32_t targetDimension,
354 uint32_t expectedDimension,
355 const char * const location )
357 ImageDimensions desired( targetDimension, targetDimension );
358 FittingMode::Type fittingMode( FittingMode::SHRINK_TO_FIT );
359 SamplingMode::Type samplingMode( SamplingMode::BOX );
361 Integration::BitmapPtr sourceBitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
362 sourceBitmap->GetPackedPixelsProfile()->ReserveBuffer( format, sourceDimension, sourceDimension, sourceDimension, sourceDimension );
364 Integration::BitmapPtr downScaled = DownscaleBitmap( *sourceBitmap, desired, fittingMode, samplingMode );
366 DALI_TEST_EQUALS( downScaled->GetImageWidth(), expectedDimension, location );
367 DALI_TEST_EQUALS( downScaled->GetImageHeight(), expectedDimension, location );
368 DALI_TEST_EQUALS( downScaled->GetPixelFormat(), format, location );
372 * @brief Test the top-level function for reducing the dimension of a bitmap,
373 * feeding it each of the five pixel formats that are output by image loaders.
374 * Simply assert that the resulting bitmaps have the expected dimensions and
377 int UtcDaliImageOperationsDownscaleBitmap(void)
379 // Do Scalings that are expected to work for all pixels modes and assert the resulting bitmap dimensions:
381 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 1024, 8, 8, TEST_LOCATION );
382 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 1024, 8, 8, TEST_LOCATION );
383 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 1024, 8, 8, TEST_LOCATION );
384 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 1024, 8, 8, TEST_LOCATION );
385 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 1024, 8, 8, TEST_LOCATION );
387 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 773, 1, 1, TEST_LOCATION );
388 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 787, 1, 1, TEST_LOCATION );
389 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 797, 1, 1, TEST_LOCATION );
390 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 809, 1, 1, TEST_LOCATION );
391 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 811, 1, 1, TEST_LOCATION );
393 // Do Scalings that are expected to produce a slightly larger than requested image:
394 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 47, 7, 11, TEST_LOCATION );
395 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 73, 17, 18, TEST_LOCATION );
396 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 61, 8, 15, TEST_LOCATION );
397 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 19, 5, 9, TEST_LOCATION );
398 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 353, 23, 44, TEST_LOCATION );
404 * @brief Test downscaling of RGB888 images as raw pixel arrays.
406 int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
408 unsigned outWidth = -1, outHeight = -1;
410 // Do downscaling to 1 x 1 so we can easily assert the value of the single pixel produced:
412 // Scale down a black/white checkerboard to mid-grey:
413 unsigned char check_4x4 [16 * 3] = {
414 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
416 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
420 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
421 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
422 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
423 DALI_TEST_EQUALS( check_4x4[0], (unsigned char)0x7f, TEST_LOCATION );
425 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
426 unsigned char single_4x4 [16 * 3] = {
427 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
432 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
433 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
434 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
435 DALI_TEST_EQUALS( single_4x4[0], (unsigned char)0xf, TEST_LOCATION );
437 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
438 // (white pixel at bottom-right of image)
439 unsigned char single_4x4_2 [16 * 3] = {
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
445 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
446 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
447 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
448 DALI_TEST_EQUALS( single_4x4_2[0], (unsigned char)0xf, TEST_LOCATION );
450 // Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
452 unsigned char magenta_600_x_600[608*608 * 3];
453 for( unsigned int i = 0; i < sizeof(magenta_600_x_600); i += 3 )
455 magenta_600_x_600[i] = 0xff;
456 magenta_600_x_600[i + 1] = 0;
457 magenta_600_x_600[i + 2] = 0xff;
460 // Scaling to 0 x 0 should stop at 1 x 1:
461 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
462 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
463 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
465 // Scaling to 1 x 1 should hit 1 x 1:
466 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 608, 608, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
467 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
468 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
470 // Scaling to original dimensions should NOP:
471 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 384, 384, BoxDimensionTestBoth, outWidth, outHeight );
472 DALI_TEST_EQUALS( outWidth, 384u, TEST_LOCATION );
473 DALI_TEST_EQUALS( outHeight, 384u, TEST_LOCATION );
475 // More dimension tests:
477 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 44, 11, BoxDimensionTestBoth, outWidth, outHeight );
478 DALI_TEST_EQUALS( outWidth, 44u, TEST_LOCATION );
479 DALI_TEST_EQUALS( outHeight, 44u, TEST_LOCATION );
481 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 3, 48, BoxDimensionTestBoth, outWidth, outHeight );
482 DALI_TEST_EQUALS( outWidth, 48u, TEST_LOCATION );
483 DALI_TEST_EQUALS( outHeight, 48u, TEST_LOCATION );
485 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 3, 3, BoxDimensionTestBoth, outWidth, outHeight );
486 DALI_TEST_CHECK( outWidth == 3u && outHeight == 3u );
488 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 320, 320, 5, 5, BoxDimensionTestBoth, outWidth, outHeight );
489 DALI_TEST_CHECK( outWidth == 5u && outHeight == 5u );
491 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 448, 448, 7, 7, BoxDimensionTestBoth, outWidth, outHeight );
492 DALI_TEST_CHECK( outWidth == 7u && outHeight == 7u );
494 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 11, 11, BoxDimensionTestBoth, outWidth, outHeight );
495 DALI_TEST_CHECK( outWidth == 11u && outHeight == 11u );
497 // Check that no pixel values were modified by the repeated averaging of identical pixels in tests above:
498 unsigned int numNonMagenta = 0u;
499 for( unsigned i = 0; i < sizeof(magenta_600_x_600); i += 3 )
501 numNonMagenta += magenta_600_x_600[i] == 0xff && magenta_600_x_600[i + 1] == 0x00 && magenta_600_x_600[i + 2] == 0xff ? 0 : 1;
503 DALI_TEST_EQUALS( numNonMagenta, 0u, TEST_LOCATION );
509 * @brief Test that resizing RGBA8888 images as raw pixel arrays produces a result of the correct dimensions.
511 void TestDownscaleOutputsExpectedDimensionsRGBA8888( uint32_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char * const location )
513 unsigned int resultingWidth = -1, resultingHeight = -1;
514 Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
515 reinterpret_cast<unsigned char *> (pixels),
516 inputWidth, inputHeight,
517 desiredWidth, desiredHeight, BoxDimensionTestBoth,
518 resultingWidth, resultingHeight );
520 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
521 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
525 * @brief Test that resizing RGB565 images as raw pixel arrays produces a result of the correct dimensions.
527 void TestDownscaleOutputsExpectedDimensionsRGB565( uint16_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char * const location )
529 unsigned int resultingWidth = -1, resultingHeight = -1;
530 Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
531 reinterpret_cast<unsigned char *> (pixels),
532 inputWidth, inputHeight,
533 desiredWidth, desiredHeight, BoxDimensionTestBoth,
534 resultingWidth, resultingHeight );
536 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
537 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
541 * @brief Test that resizing 2-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
543 void TestDownscaleOutputsExpectedDimensions2ComponentPair( uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char * const location )
545 unsigned int resultingWidth = -1, resultingHeight = -1;
546 Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
548 inputWidth, inputHeight,
549 desiredWidth, desiredHeight, BoxDimensionTestBoth,
550 resultingWidth, resultingHeight );
552 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
553 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
557 * @brief Test that resizing single-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
559 void TestDownscaleOutputsExpectedDimensionsSingleComponent( uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char * const location )
561 unsigned int resultingWidth = -1, resultingHeight = -1;
562 Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
564 inputWidth, inputHeight,
565 desiredWidth, desiredHeight, BoxDimensionTestBoth,
566 resultingWidth, resultingHeight );
568 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
569 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
573 * @brief Test downscaling of RGBA8888 images in raw image arrays.
575 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888(void)
577 uint32_t image[608*608];
578 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
580 image[i] = 0xffffffff;
582 unsigned char* const pixels = reinterpret_cast<unsigned char *> (image);
583 unsigned int resultingWidth = -1, resultingHeight = -1;
585 // Test downscaling where the input size is an exact multiple of the desired size:
586 // (We expect a perfect result here)
588 DownscaleInPlacePow2RGBA8888( pixels, 600, 600, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight );
589 DALI_TEST_EQUALS( resultingWidth, 75u, TEST_LOCATION );
590 DALI_TEST_EQUALS( resultingHeight, 75u, TEST_LOCATION );
592 DownscaleInPlacePow2RGBA8888( pixels, 512, 512, 16, 16, BoxDimensionTestBoth, resultingWidth, resultingHeight );
593 DALI_TEST_EQUALS( resultingWidth, 16u, TEST_LOCATION );
594 DALI_TEST_EQUALS( resultingHeight, 16u, TEST_LOCATION );
596 DownscaleInPlacePow2RGBA8888( pixels, 512, 64, 16, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight );
597 DALI_TEST_EQUALS( resultingWidth, 16u, TEST_LOCATION );
598 DALI_TEST_EQUALS( resultingHeight, 2u, TEST_LOCATION );
600 DownscaleInPlacePow2RGBA8888( pixels, 64, 1024, 4, 64, BoxDimensionTestBoth, resultingWidth, resultingHeight );
601 DALI_TEST_EQUALS( resultingWidth, 4u, TEST_LOCATION );
602 DALI_TEST_EQUALS( resultingHeight, 64u, TEST_LOCATION );
604 // Test downscaling where the input size is slightly off being an exact multiple of the desired size:
605 // (We expect a perfect match at the end because of rounding-down to an even width and height at each step)
607 DownscaleInPlacePow2RGBA8888( pixels, 601, 603, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight );
608 DALI_TEST_EQUALS( resultingWidth, 75u, TEST_LOCATION );
609 DALI_TEST_EQUALS( resultingHeight, 75u, TEST_LOCATION );
611 DownscaleInPlacePow2RGBA8888( pixels, 736 + 1, 352 + 3, 23, 11, BoxDimensionTestBoth, resultingWidth, resultingHeight );
612 DALI_TEST_EQUALS( resultingWidth, 23u, TEST_LOCATION );
613 DALI_TEST_EQUALS( resultingHeight, 11u, TEST_LOCATION );
615 DownscaleInPlacePow2RGBA8888( pixels, 384 + 3, 896 + 1, 3, 7, BoxDimensionTestBoth, resultingWidth, resultingHeight );
616 DALI_TEST_EQUALS( resultingWidth, 3u, TEST_LOCATION );
617 DALI_TEST_EQUALS( resultingHeight, 7u, TEST_LOCATION );
619 // Test downscales with source dimensions which are under a nice power of two by one:
621 // The target is hit exactly due to losing spare columns or rows at each iteration:
622 DownscaleInPlacePow2RGBA8888( pixels, 63, 31, 7, 3, BoxDimensionTestBoth, resultingWidth, resultingHeight );
623 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
624 DALI_TEST_EQUALS( resultingHeight, 3u, TEST_LOCATION );
626 // Asking to downscale a bit smaller should stop at the dimensions of the last test as one more halving would go down to 3 x 1, which is too small.
627 DownscaleInPlacePow2RGBA8888( pixels, 63, 31, 4, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight );
628 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
629 DALI_TEST_EQUALS( resultingHeight, 3u, TEST_LOCATION );
631 // Should stop at almost twice the requested dimensions:
632 DownscaleInPlacePow2RGBA8888( pixels, 15, 127, 4, 32, BoxDimensionTestBoth, resultingWidth, resultingHeight );
633 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
634 DALI_TEST_EQUALS( resultingHeight, 63u, TEST_LOCATION );
636 // Test downscales to 1 in one or both dimensions:
637 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
638 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 512, 1, 1, 1, 1, TEST_LOCATION );
639 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 16, 1, 16, 1, TEST_LOCATION );
640 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 7, 1, 16, 1, TEST_LOCATION );
641 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 7, 1, 16, 1, TEST_LOCATION );
642 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 5, 1, 16, 1, TEST_LOCATION );
643 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 3, 1, 16, 1, TEST_LOCATION );
644 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 1, 1, 16, TEST_LOCATION );
645 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 16, 1, 16, TEST_LOCATION );
646 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 3, 1, 16, TEST_LOCATION );
647 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 33, 1, 1, 1, 1, TEST_LOCATION );
648 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 17*19, 17*19, 1, 1, 1, 1, TEST_LOCATION );
649 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 33, 3, 1, 4, 4, TEST_LOCATION );
650 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 9, 3, 1, 4, 1, TEST_LOCATION );
654 // Test downscales to zero in one or both dimensions:
655 // Scaling should stop when one or both dimensions reach 1.
656 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
657 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 512, 0, 0, 1, 1, TEST_LOCATION );
658 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 256, 0, 0, 2, 1, TEST_LOCATION );
659 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 128, 0, 0, 4, 1, TEST_LOCATION );
660 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 16, 0, 0, 32, 1, TEST_LOCATION );
661 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 128, 512, 0, 0, 1, 4, TEST_LOCATION );
662 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 0, 0, 1, 16, TEST_LOCATION );
663 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 8, 512, 0, 0, 1, 64, TEST_LOCATION );
664 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 2, 512, 0, 0, 1, 256, TEST_LOCATION );
670 * @brief Test downscalings of RGBA8888 images in raw image arrays that should have no effect on the input.
672 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888Nops(void)
674 uint32_t image[608*608];
675 const uint32_t numPixels = sizeof(image) / sizeof(image[0]);
676 for( unsigned i = 0; i < numPixels; ++i )
678 image[i] = RandomPixelRGBA8888();
680 const uint32_t imageHash = HashPixels( image, numPixels );
681 unsigned char* const pixels = reinterpret_cast<unsigned char *> (image);
682 unsigned int resultingWidth = -1, resultingHeight = -1;
684 // Test downscales to the same size:
685 // The point is just to be sure the downscale is a NOP in this case:
687 DownscaleInPlacePow2RGBA8888( pixels, 600, 600, 600, 600, BoxDimensionTestBoth, resultingWidth, resultingHeight );
688 DALI_TEST_EQUALS( resultingWidth, 600u, TEST_LOCATION );
689 DALI_TEST_EQUALS( resultingHeight, 600u, TEST_LOCATION );
691 DownscaleInPlacePow2RGBA8888( pixels, 512, 128, 512, 128, BoxDimensionTestBoth, resultingWidth, resultingHeight );
692 DALI_TEST_EQUALS( resultingWidth, 512u, TEST_LOCATION );
693 DALI_TEST_EQUALS( resultingHeight, 128u, TEST_LOCATION );
695 DownscaleInPlacePow2RGBA8888( pixels, 17, 1001, 17, 1001, BoxDimensionTestBoth, resultingWidth, resultingHeight );
696 DALI_TEST_EQUALS( resultingWidth, 17u, TEST_LOCATION );
697 DALI_TEST_EQUALS( resultingHeight, 1001u, TEST_LOCATION );
699 // Test downscales that request a larger size (we never upscale so these are NOPs too):
700 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
701 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 300, 300, 600, 600, 300, 300, TEST_LOCATION );
702 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 3, 127, 99, 599, 3, 127, TEST_LOCATION );
703 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 600, 600, 999, 999, 600, 600, TEST_LOCATION ); //< checks no out of bounds mem access in this case
706 // Make sure that none of these NOP downscalings has affected the pixels of the image:
707 DALI_TEST_EQUALS( HashPixels( image, numPixels ), imageHash, TEST_LOCATION );
713 * @brief Do additional downscaling testing using RGB565 images in raw image
714 * arrays to shake out differences relating to the pixel format.
716 int UtcDaliImageOperationsDownscaleInPlacePow2RGB565(void)
718 // Test that calling with null and zero parameters doesn't blow up:
719 unsigned int outWidth, outHeight;
720 DownscaleInPlacePow2RGB565( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
722 uint16_t image[608*608];
723 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
728 // Do a straightforward test using an exact divisor target size:
729 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600, 600, 75, 75, 75, 75, TEST_LOCATION );
730 // Test that a slightly smaller than possible to achieve target results in the
731 // next-higher exact divisor output image dimensions:
732 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600, 600, 71, 69, 75, 75, TEST_LOCATION );
733 // Test that resizing from a starting size that is slightly larger than an exact
734 // multiple of the desired dimensions still results in the desired ones being
736 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
737 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600 + 1, 600 + 1, 75, 75, 75, 75, TEST_LOCATION );
738 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 1, 512 + 1, 2, 4, 2, 4, TEST_LOCATION );
739 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 1, 128 + 1, 16, 4, 16, 4, TEST_LOCATION );
740 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 1, 64 + 1, 16, 2, 16, 2, TEST_LOCATION );
741 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 3, 512 + 3, 16, 16, 16, 16, TEST_LOCATION );
742 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 3, 256 + 3, 16, 8, 16, 8, TEST_LOCATION );
743 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 3, 512 + 3, 4, 8, 4, 8, TEST_LOCATION );
744 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 7, 512 + 7, 4, 8, 4, 8, TEST_LOCATION );
745 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 7, 512 + 7, 2, 4, 2, 4, TEST_LOCATION );
746 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 7, 128 + 7, 16, 4, 16, 4, TEST_LOCATION );
747 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 7, 64 + 7, 16, 2, 16, 2, TEST_LOCATION );
754 * @brief Do additional downscaling testing using 2-byte-per-pixel images in
755 * raw image arrays to shake out differences relating to the pixel format.
757 int UtcDaliImageOperationsDownscaleInPlacePow2ComponentPair(void)
759 // Simple test that a null pointer does not get dereferenced in the function:
760 unsigned int outWidth, outHeight;
761 DownscaleInPlacePow2ComponentPair( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
763 // Simple tests of dimensions output:
765 uint8_t image[608*608*2];
766 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
771 TestDownscaleOutputsExpectedDimensions2ComponentPair( image,
772 600, 600, //< Input dimensions
773 37, 37, //< Requested dimensions
774 37, 37, //< Expected output dimensions
776 TestDownscaleOutputsExpectedDimensions2ComponentPair( image,
777 600, 600, //< Input dimensions
778 34, 35, //< Requested dimensions to scale-down to
779 37, 37, //< Expected output dimensions achieved
781 ///@note: No need to be as comprehensive as with RGB888 and RGBA8888 as the logic is shared.
787 * @brief Do additional downscaling testing using 1-byte-per-pixel images in
788 * raw image arrays to shake out differences relating to the pixel format.
790 int UtcDaliImageOperationsDownscaleInPlacePow2SingleBytePerPixel(void)
792 // Simple test that a null pointer does not get dereferenced in the function:
793 unsigned int outWidth, outHeight;
794 DownscaleInPlacePow2SingleBytePerPixel( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
796 // Tests of output dimensions from downscaling:
797 uint8_t image[608*608];
798 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
803 TestDownscaleOutputsExpectedDimensionsSingleComponent( image,
804 600, 300, //< Input dimensions
805 150, 75, //< Requested dimensions to scale-down to
806 150, 75, //< Expected output dimensions achieved
808 TestDownscaleOutputsExpectedDimensionsSingleComponent( image, 577, 411, 142, 99, 144, 102, TEST_LOCATION );
814 * @brief Test the function for averaging pairs of pixels on a scanline.
816 int UtcDaliImageOperationsHalveScanlineInPlaceRGB888(void)
818 // Red and cyan, averaging to grey:
819 unsigned char shortEven[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
820 unsigned char shortOdd[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xC, 0xC, 0xC };
822 Dali::Internal::Platform::HalveScanlineInPlaceRGB888( shortEven, 4u );
823 Dali::Internal::Platform::HalveScanlineInPlaceRGB888( shortOdd, 4u );
824 for( unsigned i = 0; i < sizeof(shortEven) >> 1u ; ++i )
826 DALI_TEST_EQUALS( unsigned(shortEven[i]), 0x7fu, TEST_LOCATION );
827 DALI_TEST_EQUALS( unsigned(shortOdd[i]), 0x7fu, TEST_LOCATION );
834 * @brief Test the function for averaging pairs of pixels on a scanline.
836 int UtcDaliImageOperationsHalveScanlineInPlaceRGBA8888(void)
838 const size_t scanlineLength = 4096u;
839 Dali::Vector<uint32_t> scanline;
840 Dali::Vector<uint32_t> reference;
841 SetupScanlineForHalvingTestsRGBA8888( scanlineLength, scanline, reference );
843 HalveScanlineInPlaceRGBA8888( (uint8_t *) &scanline[0], scanlineLength );
845 // Check that the halving matches the independently calculated reference:
846 size_t numMatches = 0;
847 for( int i = 0, length = reference.Size(); i < length; ++i )
849 DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
850 numMatches += scanline[i] == reference[i];
852 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
854 // Test for no beyond-bounds writes:
855 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
857 DALI_TEST_EQUALS( reference[i], (uint32_t)0xEEEEEEEE, TEST_LOCATION );
864 * @brief Test the function for averaging pairs of pixels on a scanline.
866 int UtcDaliImageOperationsHalveScanlineInPlaceRGB565(void)
868 const size_t scanlineLength = 4096u;
869 Dali::Vector<uint16_t> scanline;
870 Dali::Vector<uint16_t> reference;
871 SetupScanlineForHalvingTestsRGB565( scanlineLength, scanline, reference );
873 HalveScanlineInPlaceRGB565( (unsigned char *) (&scanline[0]), scanlineLength );
875 // Check output against reference:
876 size_t numMatches = 0;
877 for( int i = 0, length = reference.Size(); i < length; ++i )
879 DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
880 numMatches += scanline[i] == reference[i];
882 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
884 // Test for no beyond-bounds writes:
885 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
887 DALI_TEST_EQUALS( reference[i], (uint16_t)0xEEEE, TEST_LOCATION );
894 * @brief Test the function for averaging pairs of pixels on a scanline.
896 int UtcDaliImageOperationsHalveScanlineInPlace2Bytes(void)
898 const size_t scanlineLength = 4096u;
899 Dali::Vector<uint8_t> scanline;
900 Dali::Vector<uint8_t> reference;
901 SetupScanlineForHalvingTests2Bytes( scanlineLength, scanline, reference );
903 HalveScanlineInPlace2Bytes( &scanline[0], scanlineLength );
905 // Test the output against the reference (no differences):
906 size_t numMatches = 0;
907 for( int i = 0, length = reference.Size(); i < length; ++i )
909 DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
910 numMatches += scanline[i] == reference[i];
912 // The number of matching bytes should be double the number of pixels, which happens to be the original scanline length in pixels:
913 DALI_TEST_EQUALS( numMatches, scanlineLength, TEST_LOCATION );
919 * @brief Test the function for averaging pairs of pixels on a scanline.
921 int UtcDaliImageOperationsHalveScanlineInPlace1Byte(void)
923 const size_t scanlineLength = 4096u;
924 Dali::Vector<uint8_t> scanline;
925 Dali::Vector<uint8_t> reference;
926 SetupScanlineForHalvingTests1Byte( scanlineLength, scanline, reference );
928 HalveScanlineInPlace1Byte( &scanline[0], scanlineLength );
930 // Test the reference matches the output:
931 size_t numMatches = 0;
932 for( int i = 0, length = reference.Size(); i < length; ++i )
934 DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
935 numMatches += scanline[i] == reference[i];
937 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
943 * @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
945 int UtcDaliImageOperationsAverageScanlines1(void)
947 // Red and cyan, averaging to grey:
948 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
949 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
950 unsigned char outputBuffer[sizeof(shortEven1)];
952 AverageScanlines1( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) );
953 for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
955 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
958 // Longer test reusing RGBA setup/test logic:
959 const size_t scanlineLength = 4096u;
960 Dali::Vector<uint32_t> scanline1;
961 Dali::Vector<uint32_t> scanline2;
962 Dali::Vector<uint32_t> reference;
963 Dali::Vector<uint32_t> output;
964 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
966 AverageScanlines1( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 );
968 // Check the output matches the independently generated reference:
969 size_t numMatches = 0;
970 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
971 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
977 * @brief Test the function for averaging vertically-adjacent pairs of 2-byte-per-pixel pixels on a scanline.
979 int UtcDaliImageOperationsAverageScanlines2(void)
981 // Red and cyan, averaging to grey:
982 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
983 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
984 unsigned char outputBuffer[sizeof(shortEven1)];
986 AverageScanlines2( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 2 );
988 for( unsigned i = 0; i < sizeof(shortEven1); ++i )
990 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
993 // Longer test reusing RGBA setup/test logic:
994 const size_t scanlineLength = 4096u;
995 Dali::Vector<uint32_t> scanline1;
996 Dali::Vector<uint32_t> scanline2;
997 Dali::Vector<uint32_t> reference;
998 Dali::Vector<uint32_t> output;
999 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
1001 AverageScanlines2( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 2 );
1003 // Check the output matches the independently generated reference:
1004 size_t numMatches = 0;
1005 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
1006 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1012 * @brief Test the function for averaging vertically-adjacent pairs of RGB888 pixels on a scanline.
1014 int UtcDaliImageOperationsAverageScanlines3(void)
1016 // Red and cyan, averaging to grey:
1017 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
1018 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
1019 unsigned char outputBuffer[sizeof(shortEven1)];
1021 AverageScanlines3( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 3 );
1022 for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
1024 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
1027 // Longer test reusing RGBA setup/test logic:
1028 const size_t scanlineLength = 3 * 4 * 90u;
1029 Dali::Vector<uint32_t> scanline1;
1030 Dali::Vector<uint32_t> scanline2;
1031 Dali::Vector<uint32_t> reference;
1032 Dali::Vector<uint32_t> output;
1033 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
1035 AverageScanlines3( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 / 3 );
1037 // Check the output matches the independently generated reference:
1038 size_t numMatches = 0;
1039 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
1040 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1046 * @brief Test the function for averaging vertically-adjacent pairs of RGBA8888 pixels on a scanline.
1048 int UtcDaliImageOperationsAverageScanlinesRGBA8888(void)
1050 const size_t scanlineLength = 4096u;
1051 Dali::Vector<uint32_t> scanline1;
1052 Dali::Vector<uint32_t> scanline2;
1053 Dali::Vector<uint32_t> reference;
1054 Dali::Vector<uint32_t> output;
1055 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
1057 AverageScanlinesRGBA8888( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength );
1059 // Check the output matches the independently generated reference:
1060 size_t numMatches = 0;
1061 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
1062 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1068 * @brief Test the function for averaging vertically-adjacent pairs of RGB565 pixels on a scanline.
1070 int UtcDaliImageOperationsAverageScanlinesRGB565(void)
1072 // Red and cyan, averaging to grey:
1073 const uint16_t shortEven1[] = { 0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xBEEF, 0xBEEF };
1074 const uint16_t shortEven2[] = { 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0xBEEF, 0xBEEF };
1075 const size_t arrayLength = sizeof(shortEven1) / sizeof(shortEven1[0]) - 2;
1076 uint16_t outputBuffer[arrayLength + 2];
1077 outputBuffer[arrayLength] = 0xDEAD;
1078 outputBuffer[arrayLength+1] = 0xDEAD;
1080 Dali::Internal::Platform::AverageScanlinesRGB565( (const unsigned char*) shortEven1, (const unsigned char*) shortEven2, (unsigned char*) outputBuffer, arrayLength );
1081 for( unsigned i = 0; i < arrayLength ; ++i )
1083 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0xffff - (1u << 15) - (1u << 10) - (1u << 4), TEST_LOCATION );
1086 // Check for buffer overrun:
1087 DALI_TEST_EQUALS( outputBuffer[arrayLength], (uint16_t)0xDEAD, TEST_LOCATION );
1088 DALI_TEST_EQUALS( outputBuffer[arrayLength+1], (uint16_t)0xDEAD, TEST_LOCATION );
1096 void MakeSingleColorImageRGBA8888( unsigned int width, unsigned int height, uint32_t *inputImage )
1098 const uint32_t inPixel = PixelRGBA8888( 255, 192, 128, 64 );
1099 for( unsigned int i = 0; i < width * height; ++i )
1101 inputImage[i] = inPixel;
1106 * @brief Make an image with a checkerboard pattern.
1107 * @note This is an easy pattern to scan for correctness after a downscaling test.
1109 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > MakeCheckerboardImageRGBA8888( unsigned int width, unsigned int height, unsigned int checkerSize )
1111 const unsigned int imageWidth = width * checkerSize;
1112 const unsigned int imageHeight = height * checkerSize;
1113 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = new Dali::RefCountedVector<uint32_t>;
1114 image->GetVector().Resize( imageWidth * imageHeight );
1116 uint32_t rowColor = 0xffffffff;
1117 for( unsigned int cy = 0; cy < height; ++cy )
1119 rowColor = rowColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1120 uint32_t checkColor = rowColor;
1121 for( unsigned int cx = 0; cx < width; ++cx )
1123 checkColor = checkColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1124 uint32_t paintedColor = checkColor;
1125 // Draw 3 special case checks as r,g,b:
1126 if(cx == 0 && cy == 0)
1128 paintedColor = 0xff0000ff;// Red
1130 else if(cx == 7 && cy == 0)
1132 paintedColor = 0xff00ff00;// Green
1134 else if(cx == 7 && cy == 7)
1136 paintedColor = 0xffff0000;// blue
1138 uint32_t * check = &image->GetVector()[ (cy * checkerSize * imageWidth) + (cx * checkerSize)];
1139 for( unsigned int py = 0; py < checkerSize; ++py )
1141 uint32_t * checkLine = check + py * imageWidth;
1142 for( unsigned int px = 0; px < checkerSize; ++px )
1144 checkLine[px] = paintedColor;
1156 * @brief Test the right pixels are generated when downsampling a checkerboard into a small image.
1158 int UtcDaliImageOperationsPointSampleCheckerboardRGBA888(void)
1160 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = MakeCheckerboardImageRGBA8888( 8, 8, 32 );
1161 const unsigned int desiredWidth = 8;
1162 const unsigned int desiredHeight = 8;
1164 uint32_t outputImage[ desiredWidth * desiredHeight ];
1166 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) &image->GetVector()[0], 256, 256, (unsigned char*) outputImage, desiredWidth, desiredHeight );
1168 DALI_TEST_EQUALS( outputImage[0], (uint32_t)0xff0000ff, TEST_LOCATION ); // < Red corner pixel
1169 DALI_TEST_EQUALS( outputImage[7], (uint32_t)0xff00ff00, TEST_LOCATION ); // < Green corner pixel
1170 DALI_TEST_EQUALS( outputImage[8*8-1], (uint32_t)0xffff0000, TEST_LOCATION ); // < Blue corner pixel
1172 DALI_TEST_EQUALS( outputImage[1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1173 DALI_TEST_EQUALS( outputImage[2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1174 DALI_TEST_EQUALS( outputImage[3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1175 DALI_TEST_EQUALS( outputImage[4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1176 DALI_TEST_EQUALS( outputImage[5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1177 DALI_TEST_EQUALS( outputImage[6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1180 DALI_TEST_EQUALS( outputImage[8+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1181 DALI_TEST_EQUALS( outputImage[8+1], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1182 DALI_TEST_EQUALS( outputImage[8+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1183 DALI_TEST_EQUALS( outputImage[8+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1184 DALI_TEST_EQUALS( outputImage[8+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1185 DALI_TEST_EQUALS( outputImage[8+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1186 DALI_TEST_EQUALS( outputImage[8+6], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1187 DALI_TEST_EQUALS( outputImage[8+7], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1190 DALI_TEST_EQUALS( outputImage[16+0], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1191 DALI_TEST_EQUALS( outputImage[16+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1192 DALI_TEST_EQUALS( outputImage[16+2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1193 DALI_TEST_EQUALS( outputImage[16+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1194 DALI_TEST_EQUALS( outputImage[16+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1195 DALI_TEST_EQUALS( outputImage[16+5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1196 DALI_TEST_EQUALS( outputImage[16+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1197 DALI_TEST_EQUALS( outputImage[16+7], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1199 // ... could do more scanlines (there are 8)
1201 // Sample a few more pixels:
1204 DALI_TEST_EQUALS( outputImage[24+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1205 DALI_TEST_EQUALS( outputImage[32+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1206 DALI_TEST_EQUALS( outputImage[40+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1207 DALI_TEST_EQUALS( outputImage[48+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1208 DALI_TEST_EQUALS( outputImage[24+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1209 DALI_TEST_EQUALS( outputImage[32+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1210 DALI_TEST_EQUALS( outputImage[40+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1211 DALI_TEST_EQUALS( outputImage[48+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1212 DALI_TEST_EQUALS( outputImage[56+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1218 * @brief Test that a scaling preserves input color in destination image.
1220 int UtcDaliImageOperationsPointSampleRGBA888PixelsCorrectColor(void)
1222 const unsigned int inputWidth = 137;
1223 const unsigned int inputHeight = 571;
1224 const unsigned int desiredWidth = 59;
1225 const unsigned int desiredHeight = 257;
1227 uint32_t inputImage[ inputWidth * inputHeight ];
1228 MakeSingleColorImageRGBA8888( inputWidth, inputHeight, inputImage );
1230 const size_t outputBufferSize = desiredWidth * desiredHeight;
1231 std::vector< uint32_t > buffer;
1232 buffer.resize( outputBufferSize );
1233 uint32_t* outputImage = &buffer[0];
1235 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, inputWidth, inputHeight, (unsigned char*) outputImage, desiredWidth, desiredHeight );
1237 // Check that all the output pixels are the right color:
1238 const uint32_t reference = inputImage[ inputWidth * inputHeight / 2];
1239 unsigned int differentColorCount = 0;
1240 for( unsigned int i = 0; i < desiredWidth * desiredHeight; ++i )
1242 if( outputImage[i] != reference )
1244 ++differentColorCount;
1248 DALI_TEST_EQUALS( 0U, differentColorCount, TEST_LOCATION );
1254 * @brief Test that scaling down to a 1x1 image works.
1256 int UtcDaliImageOperationsPointSampleRGBA888ScaleToSinglePixel(void)
1258 const unsigned int desiredWidth = 1;
1259 const unsigned int desiredHeight = 1;
1261 uint32_t inputImage[ 1024 * 1024 ];
1262 MakeSingleColorImageRGBA8888( 1024, 1024, inputImage );
1263 uint32_t outputImage = 0;
1265 // Try several different starting image sizes:
1268 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1269 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1272 // Single-pixel wide tall stripe:
1273 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1024, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1274 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1277 // Single-pixel tall, wide strip:
1278 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1024, 1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1279 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1282 // Square mid-size image:
1283 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 103, 103, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1284 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1287 // Wide mid-size image:
1288 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 313, 79, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1289 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1292 // Tall mid-size image:
1293 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 53, 467, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1294 DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1297 // 0 x 0 input image (make sure output not written to):
1298 outputImage = 0xDEADBEEF;
1299 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 0, 0, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1300 DALI_TEST_EQUALS( outputImage, (uint32_t)0xDEADBEEF, TEST_LOCATION );
1307 * @brief Test that downsampling to 0 - area images is a NOP and does not modify the destination.
1310 int UtcDaliImageOperationsPointSampleRGBA888N(void)
1312 uint32_t inputImage[ 128 * 128 ];
1313 MakeSingleColorImageRGBA8888( 128, 128, inputImage );
1314 uint32_t outputImage[ 128 * 128 ];
1315 memset( outputImage, 0xaa, 128 * 128 * sizeof(uint32_t) );
1317 // Try several different starting image sizes:
1320 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1, (unsigned char*) outputImage, 0, 0 );
1321 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1323 // Single-pixel wide tall stripe:
1324 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 102, (unsigned char*) outputImage, 0, 33 );
1325 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1327 // Single-pixel tall, wide strip:
1328 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 102, 1, (unsigned char*) outputImage, 0, 67 );
1329 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1331 // Square mid-size image:
1332 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 103, 103, (unsigned char*) outputImage, 21, 0 );
1333 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1335 // Wide mid-size image to 0 height
1336 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 313, 79, (unsigned char*) outputImage, 99, 0 );
1337 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1339 // Tall mid-size image to 0 height, over width
1340 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 53, 46, (unsigned char*) outputImage, 9999, 0 );
1341 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1343 // 0 x 0 input image:
1344 Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 0, 0, (unsigned char*) outputImage, 200, 99 );
1345 DALI_TEST_EQUALS( 0xaaaaaaaa, outputImage[0], TEST_LOCATION );
1351 * @brief Test the small int (x,y) tuple.
1353 int UtcDaliImageOperationsUint16Pair(void)
1355 Uint16Pair vec1( 2, 3 );
1357 DALI_TEST_EQUALS( vec1.GetWidth(), (uint16_t)2, TEST_LOCATION );
1358 DALI_TEST_EQUALS( vec1.GetX(), (uint16_t)2, TEST_LOCATION );
1360 DALI_TEST_EQUALS( vec1.GetHeight(), (uint16_t)3, TEST_LOCATION );
1361 DALI_TEST_EQUALS( vec1.GetY(), (uint16_t)3, TEST_LOCATION );
1363 Uint16Pair vec1Copy = vec1;
1365 DALI_TEST_EQUALS( vec1Copy.GetWidth(), (uint16_t)2, TEST_LOCATION );
1366 DALI_TEST_EQUALS( vec1Copy.GetX(), (uint16_t)2, TEST_LOCATION );
1368 DALI_TEST_EQUALS( vec1Copy.GetHeight(), (uint16_t)3, TEST_LOCATION );
1369 DALI_TEST_EQUALS( vec1Copy.GetY(), (uint16_t)3, TEST_LOCATION );
1371 Uint16Pair vec2( 65535u, 65535u );
1373 DALI_TEST_EQUALS( vec2.GetX(), (uint16_t)65535u, TEST_LOCATION );
1374 DALI_TEST_EQUALS( vec2.GetY(), (uint16_t)65535u, TEST_LOCATION );
1380 * @brief Test the four-tap linear blending for single-byte modes.
1382 int UtcDaliImageOperationsBilinearFilter1BPP(void)
1384 // Zeros blend to zero:
1385 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 0 ), TEST_LOCATION );
1386 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 32768, 0 ), TEST_LOCATION );
1387 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 65535, 0 ), TEST_LOCATION );
1388 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 32768 ), TEST_LOCATION );
1389 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 65535 ), TEST_LOCATION );
1391 // Ones and zeros average to 0.5:
1392 DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 255, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
1393 DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 0, 255, 0, 255, 32768, 32768 ), TEST_LOCATION );
1395 // Quarters ones average to 0.25:
1396 DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 255, 0, 0, 0, 32768, 32768 ), TEST_LOCATION );
1397 DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 255, 0, 0, 32768, 32768 ), TEST_LOCATION );
1398 DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 255, 0, 32768, 32768 ), TEST_LOCATION );
1399 DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
1401 // Horizontal blends:
1402 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, 32768 ), TEST_LOCATION );
1403 for( unsigned y = 0; y < 65536u; y += 256 )
1405 // Vertical blends don't change result in this case as there is no vertical gradient in inputs:
1406 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, y ), TEST_LOCATION );
1408 DALI_TEST_EQUALS( 5u, BilinearFilter1Component( 0, 255, 0, 255, 1233, 32768 ), TEST_LOCATION );
1409 DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
1410 DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
1411 DALI_TEST_EQUALS( 67u, BilinearFilter1Component( 0, 255, 0, 255, 17291, 32768 ), TEST_LOCATION );
1412 DALI_TEST_EQUALS( 123u, BilinearFilter1Component( 0, 255, 0, 255, 31671, 32768 ), TEST_LOCATION );
1413 DALI_TEST_EQUALS( 184u, BilinearFilter1Component( 0, 255, 0, 255, 47231, 32768 ), TEST_LOCATION );
1414 DALI_TEST_EQUALS( 207u, BilinearFilter1Component( 0, 255, 0, 255, 53129, 32768 ), TEST_LOCATION );
1415 DALI_TEST_EQUALS( 239u, BilinearFilter1Component( 0, 255, 0, 255, 61392, 32768 ), TEST_LOCATION );
1416 DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 255, 0, 255, 65535, 32768 ), TEST_LOCATION );
1419 DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 0 ), TEST_LOCATION );
1420 DALI_TEST_EQUALS( 60u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 15379 ), TEST_LOCATION );
1421 DALI_TEST_EQUALS( 130u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 33451 ), TEST_LOCATION );
1422 DALI_TEST_EQUALS( 186u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 47836 ), TEST_LOCATION );
1423 DALI_TEST_EQUALS( 244u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 62731 ), TEST_LOCATION );
1424 DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 65535 ), TEST_LOCATION );