Dali 3D User Interface Engine
utc-Dali-ImageOperations.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 
18 #include <dali-test-suite-utils.h>
21 
22 #include <sys/mman.h>
23 #include <unistd.h>
24 
25 using namespace Dali::Internal::Platform;
26 
27 namespace
28 {
29 
33 uint32_t RandomInRange( uint32_t max )
34 {
35  const uint32_t randToMax = lrand48() % (max + 1);
36  return randToMax;
37 }
38 
42 inline uint32_t RandomComponent8()
43 {
44  return RandomInRange( 255u );
45 }
46 
50 inline uint32_t RandomComponent5()
51 {
52  return RandomInRange( 31u );
53 }
54 
58 inline uint32_t RandomComponent6()
59 {
60  return RandomInRange( 63u );
61 }
62 
66 inline uint32_t PixelRGBA8888( uint32_t r, uint32_t g, uint32_t b, uint32_t a )
67 {
68  return (r << 24) + (g << 16) + (b << 8) + a;
69 }
70 
74 inline uint16_t PixelRGB565( uint32_t r, uint32_t g, uint32_t b )
75 {
76  return (r << 11) + (g << 5) + b;
77 }
78 
82 inline uint32_t RandomPixelRGBA8888( )
83 {
84  const uint32_t randomPixel = PixelRGBA8888( RandomComponent8(), RandomComponent8(), RandomComponent8(), RandomComponent8() );
85  return randomPixel;
86 }
87 
94 inline uint32_t HashPixels( const uint32_t* const pixels, unsigned int numPixels )
95 {
96  uint32_t hash = 5381;
97 
98  for( unsigned int i = 0; i < numPixels; ++i )
99  {
100  hash = hash * 33 + pixels[i];
101  }
102 
103  return hash;
104 }
105 
109 void SetupScanlineForHalvingTestsRGBA8888( size_t scanlineLength, Dali::Vector<uint32_t>& scanline, Dali::Vector<uint32_t>& reference )
110 {
111  scanline.Resize( scanlineLength );
112  reference.Reserve( scanlineLength / 2 + 32 );
113 
114  // Prepare some random pixels:
115  srand( 19 * 23 * 47 * 53 );
116  for( size_t i = 0; i < scanlineLength / 2; ++i )
117  {
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();
127 
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 );
131 
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 ) );
134  }
135 
136  for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
137  {
138  reference[i] = 0xEEEEEEEE;
139  }
140 }
141 
145 void SetupScanlineForHalvingTestsRGB565( size_t scanlineLength, Dali::Vector<uint16_t>& scanline, Dali::Vector<uint16_t>& reference )
146 {
147  scanline.Resize( scanlineLength );
148  reference.Reserve( scanlineLength / 2 + 32 );
149 
150  // Prepare some random pixels:
151  srand48( 19 * 23 * 47 * 53 );
152  for( size_t i = 0; i < scanlineLength / 2; ++i )
153  {
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();
161 
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 );
165 
166  // Average the two pixels manually as a reference:
167  reference.PushBack( PixelRGB565( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u ) );
168  }
169 
170  for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
171  {
172  reference[i] = 0xEEEE;
173  }
174 }
175 
179 void SetupScanlineForHalvingTests2Bytes( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
180 {
181  scanline.Resize( scanlineLength * 2 );
182  reference.Reserve( scanlineLength + 32 );
183 
184  // Prepare some random pixels:
185  srand48( 19 * 23 * 47 * 53 * 59 );
186  for( size_t i = 0; i < scanlineLength / 2; ++i )
187  {
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();
193 
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;
199 
200  // Average the two pixels manually as a reference:
201  reference.PushBack( (c11 + c21) >> 1u );
202  reference.PushBack( (c12 + c22) >> 1u );
203  }
204 
205  for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
206  {
207  reference[i] = 0xEE;
208  }
209 }
210 
214 void SetupScanlineForHalvingTests1Byte( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
215 {
216  scanline.Resize( scanlineLength * 2 );
217  reference.Reserve( scanlineLength + 32 );
218 
219  // Prepare some random pixels:
220  srand48( 19 * 23 * 47 * 53 * 63 );
221  for( size_t i = 0; i < scanlineLength / 2; ++i )
222  {
223  // Generate random colors:
224  const uint32_t c1 = RandomComponent8();
225  const uint32_t c2 = RandomComponent8();
226 
227  // The average of these pixels should equal the reference:
228  scanline[i * 2] = c1;
229  scanline[i * 2 + 1] = c2;
230 
231  // Average the two pixels manually as a reference:
232  reference.PushBack( (c1 + c2) >> 1u );
233 
234  }
235 
236  for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
237  {
238  reference[i] = 0xEE;
239  }
240 }
241 
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 )
248 {
249  scanline1.Reserve( scanlineLength );
250  scanline2.Reserve( scanlineLength );
251  reference.Reserve( scanlineLength + 32 );
252  output.Reserve( scanlineLength + 32 );
253 
254  for( size_t i = scanlineLength; i < output.Capacity(); ++i )
255  {
256  output[i] = 0xDEADBEEF;
257  reference[i] = 0xDEADBEEF;
258  }
259 
260  // Prepare some random pixels:
261  srand48( 19 * 23 * 47 );
262  for( size_t i = 0; i < scanlineLength; ++i )
263  {
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();
273 
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 ) );
277 
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 ) );
280  }
281 }
282 
286 void MatchScanlinesRGBA8888( Dali::Vector<uint32_t>& reference, Dali::Vector<uint32_t>& output, size_t& numMatches, const char * const location )
287 {
288  numMatches = 0;
289  for( size_t i = 0, length = reference.Capacity(); i < length; ++i )
290  {
291  DALI_TEST_EQUALS( output[i], reference[i], location );
292  numMatches += output[i] == reference[i];
293  }
294 }
295 
296 } //< namespace unnamed
297 
302 {
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 );
314  END_TEST;
315 }
316 
321 {
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 );
327  END_TEST;
328 }
329 
334 {
342  DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0x7e0u ), 0x7800u + 0x3e0u, TEST_LOCATION );
344  END_TEST;
345 }
346 
351  Pixel::Format format,
352  uint32_t sourceDimension,
353  uint32_t targetDimension,
354  uint32_t expectedDimension,
355  const char * const location )
356 {
357  ImageDimensions desired( targetDimension, targetDimension );
359  SamplingMode::Type samplingMode( SamplingMode::BOX );
360 
362  sourceBitmap->GetPackedPixelsProfile()->ReserveBuffer( format, sourceDimension, sourceDimension, sourceDimension, sourceDimension );
363 
364  Integration::BitmapPtr downScaled = DownscaleBitmap( *sourceBitmap, desired, fittingMode, samplingMode );
365 
366  DALI_TEST_EQUALS( downScaled->GetImageWidth(), expectedDimension, location );
367  DALI_TEST_EQUALS( downScaled->GetImageHeight(), expectedDimension, location );
368  DALI_TEST_EQUALS( downScaled->GetPixelFormat(), format, location );
369 }
370 
378 {
379  // Do Scalings that are expected to work for all pixels modes and assert the resulting bitmap dimensions:
380 
386 
392 
393  // Do Scalings that are expected to produce a slightly larger than requested image:
399 
400  END_TEST;
401 }
402 
407 {
408  unsigned outWidth = -1, outHeight = -1;
409 
410  // Do downscaling to 1 x 1 so we can easily assert the value of the single pixel produced:
411 
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
418  };
419 
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 );
424 
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
431  };
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 );
436 
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
444  };
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 );
449 
450  // Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
451 
452  unsigned char magenta_600_x_600[608*608 * 3];
453  for( unsigned int i = 0; i < sizeof(magenta_600_x_600); i += 3 )
454  {
455  magenta_600_x_600[i] = 0xff;
456  magenta_600_x_600[i + 1] = 0;
457  magenta_600_x_600[i + 2] = 0xff;
458  }
459 
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 );
464 
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 );
469 
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 );
474 
475  // More dimension tests:
476 
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 );
480 
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 );
484 
485  Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 3, 3, BoxDimensionTestBoth, outWidth, outHeight );
486  DALI_TEST_CHECK( outWidth == 3u && outHeight == 3u );
487 
488  Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 320, 320, 5, 5, BoxDimensionTestBoth, outWidth, outHeight );
489  DALI_TEST_CHECK( outWidth == 5u && outHeight == 5u );
490 
491  Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 448, 448, 7, 7, BoxDimensionTestBoth, outWidth, outHeight );
492  DALI_TEST_CHECK( outWidth == 7u && outHeight == 7u );
493 
494  Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 11, 11, BoxDimensionTestBoth, outWidth, outHeight );
495  DALI_TEST_CHECK( outWidth == 11u && outHeight == 11u );
496 
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 )
500  {
501  numNonMagenta += magenta_600_x_600[i] == 0xff && magenta_600_x_600[i + 1] == 0x00 && magenta_600_x_600[i + 2] == 0xff ? 0 : 1;
502  }
503  DALI_TEST_EQUALS( numNonMagenta, 0u, TEST_LOCATION );
504 
505  END_TEST;
506 }
507 
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 )
512 {
513  unsigned int resultingWidth = -1, resultingHeight = -1;
515  reinterpret_cast<unsigned char *> (pixels),
516  inputWidth, inputHeight,
517  desiredWidth, desiredHeight, BoxDimensionTestBoth,
518  resultingWidth, resultingHeight );
519 
520  DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
521  DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
522 }
523 
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 )
528 {
529  unsigned int resultingWidth = -1, resultingHeight = -1;
531  reinterpret_cast<unsigned char *> (pixels),
532  inputWidth, inputHeight,
533  desiredWidth, desiredHeight, BoxDimensionTestBoth,
534  resultingWidth, resultingHeight );
535 
536  DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
537  DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
538 }
539 
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 )
544 {
545  unsigned int resultingWidth = -1, resultingHeight = -1;
547  pixels,
548  inputWidth, inputHeight,
549  desiredWidth, desiredHeight, BoxDimensionTestBoth,
550  resultingWidth, resultingHeight );
551 
552  DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
553  DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
554 }
555 
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 )
560 {
561  unsigned int resultingWidth = -1, resultingHeight = -1;
563  pixels,
564  inputWidth, inputHeight,
565  desiredWidth, desiredHeight, BoxDimensionTestBoth,
566  resultingWidth, resultingHeight );
567 
568  DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
569  DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
570 }
571 
576 {
577  uint32_t image[608*608];
578  for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
579  {
580  image[i] = 0xffffffff;
581  }
582  unsigned char* const pixels = reinterpret_cast<unsigned char *> (image);
583  unsigned int resultingWidth = -1, resultingHeight = -1;
584 
585  // Test downscaling where the input size is an exact multiple of the desired size:
586  // (We expect a perfect result here)
587 
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 );
591 
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 );
595 
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 );
599 
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 );
603 
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)
606 
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 );
610 
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 );
614 
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 );
618 
619  // Test downscales with source dimensions which are under a nice power of two by one:
620 
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 );
625 
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 );
630 
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 );
635 
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 );
648  TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 17*19, 17*19, 1, 1, 1, 1, TEST_LOCATION );
651 
652 
653 
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 );
665 
666  END_TEST;
667 }
668 
673 {
674  uint32_t image[608*608];
675  const uint32_t numPixels = sizeof(image) / sizeof(image[0]);
676  for( unsigned i = 0; i < numPixels; ++i )
677  {
678  image[i] = RandomPixelRGBA8888();
679  }
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;
683 
684  // Test downscales to the same size:
685  // The point is just to be sure the downscale is a NOP in this case:
686 
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 );
690 
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 );
694 
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 );
698 
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
704 
705 
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 );
708 
709  END_TEST;
710 }
711 
717 {
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 );
721 
722  uint16_t image[608*608];
723  for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
724  {
725  image[i] = 0xffff;
726  }
727 
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
735  // reached:
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 );
748 
749 
750  END_TEST;
751 }
752 
758 {
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 );
762 
763  // Simple tests of dimensions output:
764 
765  uint8_t image[608*608*2];
766  for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
767  {
768  image[i] = 0xff;
769  }
770 
772  600, 600, //< Input dimensions
773  37, 37, //< Requested dimensions
774  37, 37, //< Expected output dimensions
775  TEST_LOCATION );
777  600, 600, //< Input dimensions
778  34, 35, //< Requested dimensions to scale-down to
779  37, 37, //< Expected output dimensions achieved
780  TEST_LOCATION );
782 
783  END_TEST;
784 }
785 
791 {
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 );
795 
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 )
799  {
800  image[i] = 0xff;
801  }
802 
804  600, 300, //< Input dimensions
805  150, 75, //< Requested dimensions to scale-down to
806  150, 75, //< Expected output dimensions achieved
807  TEST_LOCATION );
808  TestDownscaleOutputsExpectedDimensionsSingleComponent( image, 577, 411, 142, 99, 144, 102, TEST_LOCATION );
809 
810  END_TEST;
811 }
812 
817 {
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 };
821 
824  for( unsigned i = 0; i < sizeof(shortEven) >> 1u ; ++i )
825  {
826  DALI_TEST_EQUALS( unsigned(shortEven[i]), 0x7fu, TEST_LOCATION );
827  DALI_TEST_EQUALS( unsigned(shortOdd[i]), 0x7fu, TEST_LOCATION );
828  }
829 
830  END_TEST;
831 }
832 
837 {
838  const size_t scanlineLength = 4096u;
839  Dali::Vector<uint32_t> scanline;
840  Dali::Vector<uint32_t> reference;
841  SetupScanlineForHalvingTestsRGBA8888( scanlineLength, scanline, reference );
842 
843  HalveScanlineInPlaceRGBA8888( (uint8_t *) &scanline[0], scanlineLength );
844 
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 )
848  {
849  DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
850  numMatches += scanline[i] == reference[i];
851  }
852  DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
853 
854  // Test for no beyond-bounds writes:
855  for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
856  {
857  DALI_TEST_EQUALS( reference[i], (uint32_t)0xEEEEEEEE, TEST_LOCATION );
858  }
859 
860  END_TEST;
861 }
862 
867 {
868  const size_t scanlineLength = 4096u;
869  Dali::Vector<uint16_t> scanline;
870  Dali::Vector<uint16_t> reference;
871  SetupScanlineForHalvingTestsRGB565( scanlineLength, scanline, reference );
872 
873  HalveScanlineInPlaceRGB565( (unsigned char *) (&scanline[0]), scanlineLength );
874 
875  // Check output against reference:
876  size_t numMatches = 0;
877  for( int i = 0, length = reference.Size(); i < length; ++i )
878  {
879  DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
880  numMatches += scanline[i] == reference[i];
881  }
882  DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
883 
884  // Test for no beyond-bounds writes:
885  for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
886  {
887  DALI_TEST_EQUALS( reference[i], (uint16_t)0xEEEE, TEST_LOCATION );
888  }
889 
890  END_TEST;
891 }
892 
897 {
898  const size_t scanlineLength = 4096u;
899  Dali::Vector<uint8_t> scanline;
900  Dali::Vector<uint8_t> reference;
901  SetupScanlineForHalvingTests2Bytes( scanlineLength, scanline, reference );
902 
903  HalveScanlineInPlace2Bytes( &scanline[0], scanlineLength );
904 
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 )
908  {
909  DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
910  numMatches += scanline[i] == reference[i];
911  }
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 );
914 
915  END_TEST;
916 }
917 
922 {
923  const size_t scanlineLength = 4096u;
924  Dali::Vector<uint8_t> scanline;
925  Dali::Vector<uint8_t> reference;
926  SetupScanlineForHalvingTests1Byte( scanlineLength, scanline, reference );
927 
928  HalveScanlineInPlace1Byte( &scanline[0], scanlineLength );
929 
930  // Test the reference matches the output:
931  size_t numMatches = 0;
932  for( int i = 0, length = reference.Size(); i < length; ++i )
933  {
934  DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
935  numMatches += scanline[i] == reference[i];
936  }
937  DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
938 
939  END_TEST;
940 }
941 
946 {
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)];
951 
952  AverageScanlines1( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) );
953  for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
954  {
955  DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
956  }
957 
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 );
965 
966  AverageScanlines1( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 );
967 
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 );
972 
973  END_TEST;
974 }
975 
980 {
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)];
985 
986  AverageScanlines2( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 2 );
987 
988  for( unsigned i = 0; i < sizeof(shortEven1); ++i )
989  {
990  DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
991  }
992 
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 );
1000 
1001  AverageScanlines2( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 2 );
1002 
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 );
1007 
1008  END_TEST;
1009 }
1010 
1015 {
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)];
1020 
1021  AverageScanlines3( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 3 );
1022  for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
1023  {
1024  DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
1025  }
1026 
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 );
1034 
1035  AverageScanlines3( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 / 3 );
1036 
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 );
1041 
1042  END_TEST;
1043 }
1044 
1049 {
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 );
1056 
1057  AverageScanlinesRGBA8888( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength );
1058 
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 );
1063 
1064  END_TEST;
1065 }
1066 
1071 {
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;
1079 
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 )
1082  {
1083  DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0xffff - (1u << 15) - (1u << 10) - (1u << 4), TEST_LOCATION );
1084  }
1085 
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 );
1089 
1090  END_TEST;
1091 }
1092 
1093 namespace
1094 {
1095 
1096 void MakeSingleColorImageRGBA8888( unsigned int width, unsigned int height, uint32_t *inputImage )
1097 {
1098  const uint32_t inPixel = PixelRGBA8888( 255, 192, 128, 64 );
1099  for( unsigned int i = 0; i < width * height; ++i )
1100  {
1101  inputImage[i] = inPixel;
1102  }
1103 }
1104 
1109 void MakeGuardedOutputImageRGBA8888( unsigned int desiredWidth, unsigned int desiredHeight, uint32_t *& outputBuffer, uint32_t *& outputImage )
1110 {
1111  const size_t outputBufferSize = getpagesize() + sizeof(uint32_t) * desiredWidth * desiredHeight + getpagesize();
1112  outputBuffer = (uint32_t *) valloc( outputBufferSize );
1113  mprotect( outputBuffer, getpagesize(), PROT_READ );
1114  mprotect( ((char*) outputBuffer) + outputBufferSize - getpagesize(), getpagesize(), PROT_READ );
1115  outputImage = outputBuffer + getpagesize() / sizeof(outputBuffer[0]);
1116 }
1117 
1121 uint32_t* AllocateReadOnlyPagesRGBA( unsigned int numPixels )
1122 {
1123  const unsigned int numWholePages = (numPixels * sizeof(uint32_t)) / getpagesize();
1124  bool needExtraPage = (numPixels * sizeof(uint32_t)) % getpagesize() != 0;
1125  const size_t outputBufferSize = (numWholePages + (needExtraPage ? 1 : 0)) * getpagesize();
1126  uint32_t * outputBuffer = (uint32_t *) valloc( outputBufferSize );
1127  mprotect( outputBuffer, outputBufferSize, PROT_READ );
1128 
1129  return outputBuffer;
1130 }
1131 
1135 void FreeReadOnlyPagesRGBA( uint32_t * pages, unsigned int numPixels )
1136 {
1137  const size_t bufferSize = numPixels * 4;
1138  mprotect( pages, bufferSize, PROT_READ | PROT_WRITE );
1139  free( pages );
1140 }
1141 
1142 /*
1143  * @brief Make an image with a checkerboard pattern.
1144  * @note This is an easy pattern to scan for correctness after a downscaling test.
1145  */
1147 {
1148  const unsigned int imageWidth = width * checkerSize;
1149  const unsigned int imageHeight = height * checkerSize;
1151  image->GetVector().Resize( imageWidth * imageHeight );
1152 
1153  uint32_t rowColor = 0xffffffff;
1154  for( unsigned int cy = 0; cy < height; ++cy )
1155  {
1156  rowColor = rowColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1157  uint32_t checkColor = rowColor;
1158  for( unsigned int cx = 0; cx < width; ++cx )
1159  {
1160  checkColor = checkColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1161  uint32_t paintedColor = checkColor;
1162  // Draw 3 special case checks as r,g,b:
1163  if(cx == 0 && cy == 0)
1164  {
1165  paintedColor = 0xff0000ff;// Red
1166  }
1167  else if(cx == 7 && cy == 0)
1168  {
1169  paintedColor = 0xff00ff00;// Green
1170  }
1171  else if(cx == 7 && cy == 7)
1172  {
1173  paintedColor = 0xffff0000;// blue
1174  }
1175  uint32_t * check = &image->GetVector()[ (cy * checkerSize * imageWidth) + (cx * checkerSize)];
1176  for( unsigned int py = 0; py < checkerSize; ++py )
1177  {
1178  uint32_t * checkLine = check + py * imageWidth;
1179  for( unsigned int px = 0; px < checkerSize; ++px )
1180  {
1181  checkLine[px] = paintedColor;
1182  }
1183  }
1184  }
1185  }
1186 
1187  return image;
1188 }
1189 
1190 }
1191 
1199 {
1200  const unsigned int inputWidth = 163;
1201  const unsigned int inputHeight = 691;
1202  const unsigned int destinationBufferSize = 4096 * 4;
1203  const unsigned int desiredWidth = 64;
1204  const unsigned int desiredHeight = destinationBufferSize / desiredWidth; // (256)
1205 
1206  uint32_t inputImage[ inputWidth * inputHeight ];
1207 
1208  // Allocate an output image buffer with read-only guard pages at either end:
1209  // The test will segfault if it strays into the guard pages.
1210  uint32_t *outputBuffer, *outputImage;
1211  MakeGuardedOutputImageRGBA8888( desiredWidth, desiredHeight, outputBuffer, outputImage );
1212 
1213  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, inputWidth, inputHeight, (unsigned char*) outputImage, desiredWidth, desiredHeight );
1214 
1215  FreeReadOnlyPagesRGBA( outputBuffer, desiredWidth * desiredHeight );
1216 
1218  DALI_TEST_EQUALS( true, true, TEST_LOCATION );
1219 
1220  END_TEST;
1221 }
1222 
1227 {
1229  const unsigned int desiredWidth = 8;
1230  const unsigned int desiredHeight = 8;
1231 
1232  uint32_t outputImage[ desiredWidth * desiredHeight ];
1233 
1234  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) &image->GetVector()[0], 256, 256, (unsigned char*) outputImage, desiredWidth, desiredHeight );
1235 
1236  DALI_TEST_EQUALS( outputImage[0], (uint32_t)0xff0000ff, TEST_LOCATION ); // < Red corner pixel
1237  DALI_TEST_EQUALS( outputImage[7], (uint32_t)0xff00ff00, TEST_LOCATION ); // < Green corner pixel
1238  DALI_TEST_EQUALS( outputImage[8*8-1], (uint32_t)0xffff0000, TEST_LOCATION ); // < Blue corner pixel
1239 
1240  DALI_TEST_EQUALS( outputImage[1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1241  DALI_TEST_EQUALS( outputImage[2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1242  DALI_TEST_EQUALS( outputImage[3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1243  DALI_TEST_EQUALS( outputImage[4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1244  DALI_TEST_EQUALS( outputImage[5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1245  DALI_TEST_EQUALS( outputImage[6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1246 
1247  // Second scanline:
1248  DALI_TEST_EQUALS( outputImage[8+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1249  DALI_TEST_EQUALS( outputImage[8+1], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1250  DALI_TEST_EQUALS( outputImage[8+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1251  DALI_TEST_EQUALS( outputImage[8+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1252  DALI_TEST_EQUALS( outputImage[8+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1253  DALI_TEST_EQUALS( outputImage[8+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1254  DALI_TEST_EQUALS( outputImage[8+6], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1255  DALI_TEST_EQUALS( outputImage[8+7], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1256 
1257  // Third scanline:
1258  DALI_TEST_EQUALS( outputImage[16+0], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1259  DALI_TEST_EQUALS( outputImage[16+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1260  DALI_TEST_EQUALS( outputImage[16+2], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1261  DALI_TEST_EQUALS( outputImage[16+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1262  DALI_TEST_EQUALS( outputImage[16+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1263  DALI_TEST_EQUALS( outputImage[16+5], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1264  DALI_TEST_EQUALS( outputImage[16+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1265  DALI_TEST_EQUALS( outputImage[16+7], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1266 
1267  // ... could do more scanlines (there are 8)
1268 
1269  // Sample a few more pixels:
1270 
1271  // Diagonals:
1272  DALI_TEST_EQUALS( outputImage[24+3], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1273  DALI_TEST_EQUALS( outputImage[32+4], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1274  DALI_TEST_EQUALS( outputImage[40+5], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1275  DALI_TEST_EQUALS( outputImage[48+6], (uint32_t)0xffffffff, TEST_LOCATION ); // < white pixel
1276  DALI_TEST_EQUALS( outputImage[24+4], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1277  DALI_TEST_EQUALS( outputImage[32+3], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1278  DALI_TEST_EQUALS( outputImage[40+2], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1279  DALI_TEST_EQUALS( outputImage[48+1], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1280  DALI_TEST_EQUALS( outputImage[56+0], (uint32_t)0xff000000, TEST_LOCATION ); // < black pixel
1281 
1282  END_TEST;
1283 }
1284 
1289 {
1290  const unsigned int inputWidth = 137;
1291  const unsigned int inputHeight = 571;
1292  const unsigned int desiredWidth = 59;
1293  const unsigned int desiredHeight = 257;
1294 
1295  uint32_t inputImage[ inputWidth * inputHeight ];
1296  MakeSingleColorImageRGBA8888( inputWidth, inputHeight, inputImage );
1297 
1298  uint32_t *outputBuffer, *outputImage;
1299  MakeGuardedOutputImageRGBA8888( desiredWidth, desiredHeight, outputBuffer, outputImage );
1300 
1301  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, inputWidth, inputHeight, (unsigned char*) outputImage, desiredWidth, desiredHeight );
1302 
1303  // Check that all the output pixels are the right color:
1304  const uint32_t reference = inputImage[ inputWidth * inputHeight / 2];
1305  unsigned int differentColorCount = 0;
1306  for( unsigned int i = 0; i < desiredWidth * desiredHeight; ++i )
1307  {
1308  if( outputImage[i] != reference )
1309  {
1310  ++differentColorCount;
1311  }
1312  }
1313 
1314  FreeReadOnlyPagesRGBA( outputBuffer, desiredWidth * desiredHeight );
1315 
1316  DALI_TEST_EQUALS( 0U, differentColorCount, TEST_LOCATION );
1317 
1318  END_TEST;
1319 }
1320 
1325 {
1326  const unsigned int desiredWidth = 1;
1327  const unsigned int desiredHeight = 1;
1328 
1329  uint32_t inputImage[ 1024 * 1024 ];
1330  MakeSingleColorImageRGBA8888( 1024, 1024, inputImage );
1331  uint32_t outputImage = 0;
1332 
1333  // Try several different starting image sizes:
1334 
1335  // 1x1 -> 1x1:
1336  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1337  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1338  outputImage = 0;
1339 
1340  // Single-pixel wide tall stripe:
1341  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1024, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1342  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1343  outputImage = 0;
1344 
1345  // Single-pixel tall, wide strip:
1346  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1024, 1, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1347  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1348  outputImage = 0;
1349 
1350  // Square mid-size image:
1351  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 103, 103, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1352  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1353  outputImage = 0;
1354 
1355  // Wide mid-size image:
1356  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 313, 79, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1357  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1358  outputImage = 0;
1359 
1360  // Tall mid-size image:
1361  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 53, 467, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1362  DALI_TEST_EQUALS( outputImage, inputImage[0], TEST_LOCATION );
1363  outputImage = 0;
1364 
1365  // 0 x 0 input image (make sure output not written to):
1366  outputImage = 0xDEADBEEF;
1367  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 0, 0, (unsigned char*) &outputImage, desiredWidth, desiredHeight );
1368  DALI_TEST_EQUALS( outputImage, (uint32_t)0xDEADBEEF, TEST_LOCATION );
1369  outputImage = 0;
1370 
1371  END_TEST;
1372 }
1373 
1379 {
1380  uint32_t inputImage[ 1024 * 1024 ];
1381  MakeSingleColorImageRGBA8888( 1024, 1024, inputImage );
1382  uint32_t* outputImage = AllocateReadOnlyPagesRGBA(1);
1383 
1384  // Try several different starting image sizes:
1385 
1386  // 1x1 -> 1x1:
1387  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1, (unsigned char*) outputImage, 0, 0 );
1388 
1389  // Single-pixel wide tall stripe:
1390  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1, 1024, (unsigned char*) outputImage, 0, 33 );
1391 
1392  // Single-pixel tall, wide strip:
1393  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 1024, 1, (unsigned char*) outputImage, 0, 67 );
1394 
1395  // Square mid-size image:
1396  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 103, 103, (unsigned char*) outputImage, 21, 0 );
1397 
1398  // Wide mid-size image:
1399  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 313, 79, (unsigned char*) outputImage, 99, 0 );
1400 
1401  // Tall mid-size image:
1402  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 53, 467, (unsigned char*) outputImage, 9999, 0 );
1403 
1404  // 0 x 0 input image:
1405  Dali::Internal::Platform::PointSample4BPP( (const unsigned char *) inputImage, 0, 0, (unsigned char*) outputImage, 200, 99 );
1406 
1407  FreeReadOnlyPagesRGBA( outputImage, getpagesize() / 4 );
1408 
1410  DALI_TEST_EQUALS( true, true, TEST_LOCATION );
1411 
1412  END_TEST;
1413 }
1414 
1422 {
1423  const unsigned int inputWidth = 163;
1424  const unsigned int inputHeight = 691;
1425  const unsigned int desiredWidth = 32;
1426  const unsigned int desiredHeight = 128;
1427  const unsigned int outputBuffersizeInWords = desiredWidth * (desiredHeight / 4) * 3;
1428 
1429  uint8_t inputImage[ inputWidth * inputHeight ][3];
1430 
1431  // Allocate an output image buffer with read-only guard pages at either end:
1432  // The test will segfault if it strays into the guard pages.
1433  uint32_t *outputBuffer, *outputImage;
1434 
1435  MakeGuardedOutputImageRGBA8888( desiredWidth * (desiredHeight / 4), 3, outputBuffer, outputImage );
1436 
1437  Dali::Internal::Platform::PointSample3BPP( &inputImage[0][0], inputWidth, inputHeight, (uint8_t*) outputImage, desiredWidth, desiredHeight );
1438 
1439  FreeReadOnlyPagesRGBA( outputBuffer, outputBuffersizeInWords );
1440 
1442  DALI_TEST_EQUALS( true, true, TEST_LOCATION );
1443 
1444  END_TEST;
1445 }
1446 
1451 {
1452  Uint16Pair vec1( 2, 3 );
1453 
1454  DALI_TEST_EQUALS( vec1.GetWidth(), (uint16_t)2, TEST_LOCATION );
1455  DALI_TEST_EQUALS( vec1.GetX(), (uint16_t)2, TEST_LOCATION );
1456 
1457  DALI_TEST_EQUALS( vec1.GetHeight(), (uint16_t)3, TEST_LOCATION );
1458  DALI_TEST_EQUALS( vec1.GetY(), (uint16_t)3, TEST_LOCATION );
1459 
1460  Uint16Pair vec1Copy = vec1;
1461 
1462  DALI_TEST_EQUALS( vec1Copy.GetWidth(), (uint16_t)2, TEST_LOCATION );
1463  DALI_TEST_EQUALS( vec1Copy.GetX(), (uint16_t)2, TEST_LOCATION );
1464 
1465  DALI_TEST_EQUALS( vec1Copy.GetHeight(), (uint16_t)3, TEST_LOCATION );
1466  DALI_TEST_EQUALS( vec1Copy.GetY(), (uint16_t)3, TEST_LOCATION );
1467 
1468  Uint16Pair vec2( 65535u, 65535u );
1469 
1470  DALI_TEST_EQUALS( vec2.GetX(), (uint16_t)65535u, TEST_LOCATION );
1471  DALI_TEST_EQUALS( vec2.GetY(), (uint16_t)65535u, TEST_LOCATION );
1472 
1473  END_TEST;
1474 }
1475 
1480 {
1481  // Zeros blend to zero:
1482  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 0 ), TEST_LOCATION );
1483  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 32768, 0 ), TEST_LOCATION );
1484  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 65535, 0 ), TEST_LOCATION );
1485  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 32768 ), TEST_LOCATION );
1486  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 0, 0, 0, 65535 ), TEST_LOCATION );
1487 
1488  // Ones and zeros average to 0.5:
1489  DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 255, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
1490  DALI_TEST_EQUALS( 127u, BilinearFilter1Component( 0, 255, 0, 255, 32768, 32768 ), TEST_LOCATION );
1491 
1492  // Quarters ones average to 0.25:
1493  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 255, 0, 0, 0, 32768, 32768 ), TEST_LOCATION );
1494  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 255, 0, 0, 32768, 32768 ), TEST_LOCATION );
1495  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 255, 0, 32768, 32768 ), TEST_LOCATION );
1496  DALI_TEST_EQUALS( 64u, BilinearFilter1Component( 0, 0, 0, 255, 32768, 32768 ), TEST_LOCATION );
1497 
1498  // Horizontal blends:
1499  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, 32768 ), TEST_LOCATION );
1500  for( unsigned y = 0; y < 65536u; y += 256 )
1501  {
1502  // Vertical blends don't change result in this case as there is no vertical gradient in inputs:
1503  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 255, 0, 255, 0, y ), TEST_LOCATION );
1504  }
1505  DALI_TEST_EQUALS( 5u, BilinearFilter1Component( 0, 255, 0, 255, 1233, 32768 ), TEST_LOCATION );
1506  DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
1507  DALI_TEST_EQUALS( 29u, BilinearFilter1Component( 0, 255, 0, 255, 7539, 32768 ), TEST_LOCATION );
1508  DALI_TEST_EQUALS( 67u, BilinearFilter1Component( 0, 255, 0, 255, 17291, 32768 ), TEST_LOCATION );
1509  DALI_TEST_EQUALS( 123u, BilinearFilter1Component( 0, 255, 0, 255, 31671, 32768 ), TEST_LOCATION );
1510  DALI_TEST_EQUALS( 184u, BilinearFilter1Component( 0, 255, 0, 255, 47231, 32768 ), TEST_LOCATION );
1511  DALI_TEST_EQUALS( 207u, BilinearFilter1Component( 0, 255, 0, 255, 53129, 32768 ), TEST_LOCATION );
1512  DALI_TEST_EQUALS( 239u, BilinearFilter1Component( 0, 255, 0, 255, 61392, 32768 ), TEST_LOCATION );
1513  DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 255, 0, 255, 65535, 32768 ), TEST_LOCATION );
1514 
1515  // Vertical Blends:
1516  DALI_TEST_EQUALS( 0u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 0 ), TEST_LOCATION );
1517  DALI_TEST_EQUALS( 60u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 15379 ), TEST_LOCATION );
1518  DALI_TEST_EQUALS( 130u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 33451 ), TEST_LOCATION );
1519  DALI_TEST_EQUALS( 186u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 47836 ), TEST_LOCATION );
1520  DALI_TEST_EQUALS( 244u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 62731 ), TEST_LOCATION );
1521  DALI_TEST_EQUALS( 255u, BilinearFilter1Component( 0, 0, 255, 255, 32768, 65535 ), TEST_LOCATION );
1522 
1523  END_TEST;
1524 }
Dali Docs Home
Read more about Dali