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>
20 #include "platform-abstractions/portable/image-operations.h"
22 using namespace Dali::Internal::Platform;
28 * @brief Generate a random integer between zero and the parameter passed in.
30 uint32_t RandomInRange( uint32_t max )
32 const uint32_t randToMax = lrand48() % (max + 1);
37 * @brief Random number representable in an 8 bit color component.
39 inline uint32_t RandomComponent8()
41 return RandomInRange( 255u );
45 * @brief Random number representable in a 5 bit color component.
47 inline uint32_t RandomComponent5()
49 return RandomInRange( 31u );
53 * @brief Random number representable in a 6 bit color component.
55 inline uint32_t RandomComponent6()
57 return RandomInRange( 63u );
61 * @brief RGBA8888 Pixels from separate color components.
63 inline uint32_t PixelRGBA8888( uint32_t r, uint32_t g, uint32_t b, uint32_t a )
65 return (r << 24) + (g << 16) + (b << 8) + a;
69 * @brief RGB565 Pixels from color components in the low bits of passed-in words.
71 inline uint16_t PixelRGB565( uint32_t r, uint32_t g, uint32_t b )
73 return (r << 11) + (g << 5) + b;
77 * @brief RGBA8888 Pixels with random color components.
79 inline uint32_t RandomPixelRGBA8888( )
81 const uint32_t randomPixel = PixelRGBA8888( RandomComponent8(), RandomComponent8(), RandomComponent8(), RandomComponent8() );
86 * @brief Return a hash over a set of pixels.
88 * Used to check a buffer of pixels is unmodified by an operation given inputs
89 * that should mean that it is not changed.
91 inline uint32_t HashPixels( const uint32_t* const pixels, unsigned int numPixels )
95 for( unsigned int i = 0; i < numPixels; ++i )
97 hash = hash * 33 + pixels[i];
104 * @brief Build some dummy scanlines to exercise scanline averaging code on.
106 void SetupScanlineForHalvingTestsRGBA8888( size_t scanlineLength, Dali::Vector<uint32_t>& scanline, Dali::Vector<uint32_t>& reference )
108 scanline.Resize( scanlineLength );
109 reference.Reserve( scanlineLength / 2 + 32 );
111 // Prepare some random pixels:
112 srand( 19 * 23 * 47 * 53 );
113 for( size_t i = 0; i < scanlineLength / 2; ++i )
115 // Generate random colors:
116 const uint32_t red1 = RandomComponent8();
117 const uint32_t red2 = RandomComponent8();
118 const uint32_t green1 = RandomComponent8();
119 const uint32_t green2 = RandomComponent8();
120 const uint32_t blue1 = RandomComponent8();
121 const uint32_t blue2 = RandomComponent8();
122 const uint32_t alpha1 = RandomComponent8();
123 const uint32_t alpha2 = RandomComponent8();
125 // The average of these pixels should equal the reference:
126 scanline[i * 2] = PixelRGBA8888( red1, green1, blue1, alpha1 );
127 scanline[i * 2 + 1] = PixelRGBA8888( red2, green2, blue2, alpha2 );
129 // Average the two pixels manually as a reference:
130 reference.PushBack( PixelRGBA8888( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u ) );
133 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
135 reference[i] = 0xEEEEEEEE;
140 * @brief Build some dummy scanlines to exercise scanline averaging code on.
142 void SetupScanlineForHalvingTestsRGB565( size_t scanlineLength, Dali::Vector<uint16_t>& scanline, Dali::Vector<uint16_t>& reference )
144 scanline.Resize( scanlineLength );
145 reference.Reserve( scanlineLength / 2 + 32 );
147 // Prepare some random pixels:
148 srand48( 19 * 23 * 47 * 53 );
149 for( size_t i = 0; i < scanlineLength / 2; ++i )
151 // Generate random colors:
152 const uint32_t red1 = RandomComponent5();
153 const uint32_t red2 = RandomComponent5();
154 const uint32_t green1 = RandomComponent6();
155 const uint32_t green2 = RandomComponent6();
156 const uint32_t blue1 = RandomComponent5();
157 const uint32_t blue2 = RandomComponent5();
159 // The average of these pixels should equal the reference:
160 scanline[i * 2] = PixelRGB565( red1, green1, blue1 );
161 scanline[i * 2 + 1] = PixelRGB565( red2, green2, blue2 );
163 // Average the two pixels manually as a reference:
164 reference.PushBack( PixelRGB565( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u ) );
167 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
169 reference[i] = 0xEEEE;
174 * @brief Build some dummy scanlines to exercise scanline averaging code on.
176 void SetupScanlineForHalvingTests2Bytes( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
178 scanline.Resize( scanlineLength * 2 );
179 reference.Reserve( scanlineLength + 32 );
181 // Prepare some random pixels:
182 srand48( 19 * 23 * 47 * 53 * 59 );
183 for( size_t i = 0; i < scanlineLength / 2; ++i )
185 // Generate random colors:
186 const uint32_t c11 = RandomComponent8();
187 const uint32_t c12 = RandomComponent8();
188 const uint32_t c21 = RandomComponent8();
189 const uint32_t c22 = RandomComponent8();
191 // The average of these pixels should equal the reference:
192 scanline[i * 4] = c11;
193 scanline[i * 4 + 1] = c12;
194 scanline[i * 4 + 2] = c21;
195 scanline[i * 4 + 3] = c22;
197 // Average the two pixels manually as a reference:
198 reference.PushBack( (c11 + c21) >> 1u );
199 reference.PushBack( (c12 + c22) >> 1u );
202 for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
209 * @brief Build some dummy 1 byte per pixel scanlines to exercise scanline averaging code on.
211 void SetupScanlineForHalvingTests1Byte( size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference )
213 scanline.Resize( scanlineLength * 2 );
214 reference.Reserve( scanlineLength + 32 );
216 // Prepare some random pixels:
217 srand48( 19 * 23 * 47 * 53 * 63 );
218 for( size_t i = 0; i < scanlineLength / 2; ++i )
220 // Generate random colors:
221 const uint32_t c1 = RandomComponent8();
222 const uint32_t c2 = RandomComponent8();
224 // The average of these pixels should equal the reference:
225 scanline[i * 2] = c1;
226 scanline[i * 2 + 1] = c2;
228 // Average the two pixels manually as a reference:
229 reference.PushBack( (c1 + c2) >> 1u );
233 for( size_t i = scanlineLength; i < reference.Capacity(); ++i )
240 * @brief Build some dummy scanlines to exercise vertical averaging code on.
242 * All tested formats bar RGB565 can share this setup.
244 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 )
246 scanline1.Reserve( scanlineLength );
247 scanline2.Reserve( scanlineLength );
248 reference.Reserve( scanlineLength + 32 );
249 output.Reserve( scanlineLength + 32 );
251 for( size_t i = scanlineLength; i < output.Capacity(); ++i )
253 output[i] = 0xDEADBEEF;
254 reference[i] = 0xDEADBEEF;
257 // Prepare some random pixels:
258 srand48( 19 * 23 * 47 );
259 for( size_t i = 0; i < scanlineLength; ++i )
261 // Generate random colors:
262 const uint32_t red1 = RandomComponent8();
263 const uint32_t red2 = RandomComponent8();
264 const uint32_t green1 = RandomComponent8();
265 const uint32_t green2 = RandomComponent8();
266 const uint32_t blue1 = RandomComponent8();
267 const uint32_t blue2 = RandomComponent8();
268 const uint32_t alpha1 = RandomComponent8();
269 const uint32_t alpha2 = RandomComponent8();
271 // The average of these pixels should equal the reference:
272 scanline1.PushBack( PixelRGBA8888( red1, green1, blue1, alpha1 ) );
273 scanline2.PushBack( PixelRGBA8888( red2, green2, blue2, alpha2 ) );
275 // Average the two pixels manually as a reference:
276 reference.PushBack( PixelRGBA8888( (red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u ) );
281 * @brief Compares a scanline of interest to a reference, testing each pixel is the same.
283 void MatchScanlinesRGBA8888( Dali::Vector<uint32_t>& reference, Dali::Vector<uint32_t>& output, size_t& numMatches, const char * const location )
286 for( size_t i = 0, length = reference.Capacity(); i < length; ++i )
288 DALI_TEST_EQUALS( output[i], reference[i], location );
289 numMatches += output[i] == reference[i];
293 } //< namespace unnamed
296 * @brief Test component averaging code.
298 int UtcDaliImageOperationsAverageComponent(void)
300 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0u, 0u ), 0u, TEST_LOCATION );
301 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 1u, 1u ), 1u, TEST_LOCATION );
302 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0xffffffffu >> 1u, 0xffffffffu >> 1u ), 0xffffffffu >> 1u, TEST_LOCATION );
303 const unsigned int avg3 = Dali::Internal::Platform::AverageComponent( 0xfffffffeu, 1u );
304 DALI_TEST_EQUALS( avg3, 0x7fffffffu, TEST_LOCATION );
305 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 255u, 255u ), 255u, TEST_LOCATION );
306 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 512u, 0u ), 256u, TEST_LOCATION );
307 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 511u, 0u ), 255u, TEST_LOCATION );
308 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 510u, 0u ), 255u, TEST_LOCATION );
309 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 509u, 0u ), 254u, TEST_LOCATION );
310 DALI_TEST_EQUALS( Dali::Internal::Platform::AverageComponent( 0u, 509u ), 254u, TEST_LOCATION );
315 * @brief Test Pixel averaging code.
317 int UtcDaliImageOperationsAveragePixelRGBA8888(void)
319 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0u, 0u ), 0u, TEST_LOCATION );
320 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0x01010101, 0x01010101 ), 0x01010101u, TEST_LOCATION );
321 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0x01010101, 0x03030303 ), 0x02020202u, TEST_LOCATION );
322 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0xffffffff, 0xffffffff ), 0xffffffffu, TEST_LOCATION );
323 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGBA8888( 0xffffffff, 0u ), 0x7f7f7f7fu, TEST_LOCATION );
328 * @brief Test RGBA565 pixel averaging function.
330 int UtcDaliImageOperationsAveragePixelRGB565(void)
332 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0u, 0u ), 0u, TEST_LOCATION );
333 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0xf800u ), 0xf800u, TEST_LOCATION );
334 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0x800u ), 1u << 15, TEST_LOCATION );
335 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x7e0u, 0x7e0u ), 0x7e0u, TEST_LOCATION );
336 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x7e0u, 0x20u ), 1u << 10, TEST_LOCATION );
337 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x1f, 0x1f ), 0x1fu, TEST_LOCATION );
338 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0x1f, 0x1 ), 1u << 4, TEST_LOCATION );
339 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xf800u, 0x7e0u ), 0x7800u + 0x3e0u, TEST_LOCATION );
340 DALI_TEST_EQUALS( Dali::Internal::Platform::AveragePixelRGB565( 0xffff, 0xffff ), 0xffffu, TEST_LOCATION );
345 * @brief Build a square bitmap, downscale it and assert the resulting bitmap has the right dimensions.
347 void TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::Format format, uint32_t sourceDimension, uint32_t targetDimension, uint32_t expectedDimension, const char * const location )
349 ImageAttributes attributes;
350 attributes.SetScalingMode( ImageAttributes::ShrinkToFit );
351 attributes.SetSize( targetDimension, targetDimension );
353 Integration::BitmapPtr sourceBitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
354 sourceBitmap->GetPackedPixelsProfile()->ReserveBuffer( format, sourceDimension, sourceDimension, sourceDimension, sourceDimension );
356 Integration::BitmapPtr downScaled = DownscaleBitmap( *sourceBitmap, attributes );
357 DALI_TEST_EQUALS( downScaled->GetImageWidth(), expectedDimension, location );
358 DALI_TEST_EQUALS( downScaled->GetImageHeight(), expectedDimension, location );
359 DALI_TEST_EQUALS( downScaled->GetPixelFormat(), format, location );
363 * @brief Test the top-level function for reducing the dimension of a bitmap,
364 * feeding it each of the five pixel formats that are output by image loaders.
365 * Simply assert that the resulting bitmaps have the expected dimensions and
368 int UtcDaliImageOperationsDownscaleBitmap(void)
370 // Do Scalings that are expected to work for all pixels modes and assert the resulting bitmap dimensions:
372 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 1024, 8, 8, TEST_LOCATION );
373 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 1024, 8, 8, TEST_LOCATION );
374 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 1024, 8, 8, TEST_LOCATION );
375 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 1024, 8, 8, TEST_LOCATION );
376 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 1024, 8, 8, TEST_LOCATION );
378 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 773, 1, 1, TEST_LOCATION );
379 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 787, 1, 1, TEST_LOCATION );
380 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 797, 1, 1, TEST_LOCATION );
381 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 809, 1, 1, TEST_LOCATION );
382 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 811, 1, 1, TEST_LOCATION );
384 // Do Scalings that are expected to produce a slightly larger than requested image:
385 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGBA8888, 47, 7, 11, TEST_LOCATION );
386 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB888, 73, 17, 18, TEST_LOCATION );
387 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::RGB565, 61, 8, 15, TEST_LOCATION );
388 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::LA88, 19, 5, 9, TEST_LOCATION );
389 TestDownscaledBitmapHasRightDimensionsAndFormat( Pixel::L8, 353, 23, 44, TEST_LOCATION );
395 * @brief Test downscaling of RGB888 images as raw pixel arrays.
397 int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
399 unsigned outWidth = -1, outHeight = -1;
401 // Do downscaling to 1 x 1 so we can easily assert the value of the single pixel produced:
403 // Scale down a black/white checkerboard to mid-grey:
404 unsigned char check_4x4 [16 * 3] = {
405 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
407 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
411 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
412 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
413 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
414 DALI_TEST_EQUALS( check_4x4[0], 0x7f, TEST_LOCATION );
416 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
417 unsigned char single_4x4 [16 * 3] = {
418 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
423 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
424 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
425 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
426 DALI_TEST_EQUALS( single_4x4[0], 0xf, TEST_LOCATION );
428 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
429 // (white pixel at bottom-right of image)
430 unsigned char single_4x4_2 [16 * 3] = {
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
436 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
437 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
438 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
439 DALI_TEST_EQUALS( single_4x4_2[0], 0xf, TEST_LOCATION );
441 // Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
443 unsigned char magenta_600_x_600[608*608 * 3];
444 for( unsigned int i = 0; i < sizeof(magenta_600_x_600); i += 3 )
446 magenta_600_x_600[i] = 0xff;
447 magenta_600_x_600[i + 1] = 0;
448 magenta_600_x_600[i + 2] = 0xff;
451 // Scaling to 0 x 0 should stop at 1 x 1:
452 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
453 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
454 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
456 // Scaling to 1 x 1 should hit 1 x 1:
457 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 608, 608, 1, 1, BoxDimensionTestBoth, outWidth, outHeight );
458 DALI_TEST_EQUALS( outWidth, 1u, TEST_LOCATION );
459 DALI_TEST_EQUALS( outHeight, 1u, TEST_LOCATION );
461 // Scaling to original dimensions should NOP:
462 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 384, 384, BoxDimensionTestBoth, outWidth, outHeight );
463 DALI_TEST_EQUALS( outWidth, 384u, TEST_LOCATION );
464 DALI_TEST_EQUALS( outHeight, 384u, TEST_LOCATION );
466 // More dimension tests:
468 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 44, 11, BoxDimensionTestBoth, outWidth, outHeight );
469 DALI_TEST_EQUALS( outWidth, 44u, TEST_LOCATION );
470 DALI_TEST_EQUALS( outHeight, 44u, TEST_LOCATION );
472 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 3, 48, BoxDimensionTestBoth, outWidth, outHeight );
473 DALI_TEST_EQUALS( outWidth, 48u, TEST_LOCATION );
474 DALI_TEST_EQUALS( outHeight, 48u, TEST_LOCATION );
476 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 384, 384, 3, 3, BoxDimensionTestBoth, outWidth, outHeight );
477 DALI_TEST_CHECK( outWidth == 3u && outHeight == 3u );
479 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 320, 320, 5, 5, BoxDimensionTestBoth, outWidth, outHeight );
480 DALI_TEST_CHECK( outWidth == 5u && outHeight == 5u );
482 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 448, 448, 7, 7, BoxDimensionTestBoth, outWidth, outHeight );
483 DALI_TEST_CHECK( outWidth == 7u && outHeight == 7u );
485 Dali::Internal::Platform::DownscaleInPlacePow2RGB888( magenta_600_x_600, 352, 352, 11, 11, BoxDimensionTestBoth, outWidth, outHeight );
486 DALI_TEST_CHECK( outWidth == 11u && outHeight == 11u );
488 // Check that no pixel values were modified by the repeated averaging of identical pixels in tests above:
489 unsigned int numNonMagenta = 0u;
490 for( unsigned i = 0; i < sizeof(magenta_600_x_600); i += 3 )
492 numNonMagenta += magenta_600_x_600[i] == 0xff && magenta_600_x_600[i + 1] == 0x00 && magenta_600_x_600[i + 2] == 0xff ? 0 : 1;
494 DALI_TEST_EQUALS( numNonMagenta, 0u, TEST_LOCATION );
500 * @brief Test that resizing RGBA8888 images as raw pixel arrays produces a result of the correct dimensions.
502 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 )
504 unsigned int resultingWidth = -1, resultingHeight = -1;
505 Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
506 reinterpret_cast<unsigned char *> (pixels),
507 inputWidth, inputHeight,
508 desiredWidth, desiredHeight, BoxDimensionTestBoth,
509 resultingWidth, resultingHeight );
511 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
512 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
516 * @brief Test that resizing RGB565 images as raw pixel arrays produces a result of the correct dimensions.
518 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 )
520 unsigned int resultingWidth = -1, resultingHeight = -1;
521 Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
522 reinterpret_cast<unsigned char *> (pixels),
523 inputWidth, inputHeight,
524 desiredWidth, desiredHeight, BoxDimensionTestBoth,
525 resultingWidth, resultingHeight );
527 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
528 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
532 * @brief Test that resizing 2-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
534 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 )
536 unsigned int resultingWidth = -1, resultingHeight = -1;
537 Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
539 inputWidth, inputHeight,
540 desiredWidth, desiredHeight, BoxDimensionTestBoth,
541 resultingWidth, resultingHeight );
543 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
544 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
548 * @brief Test that resizing single-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
550 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 )
552 unsigned int resultingWidth = -1, resultingHeight = -1;
553 Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
555 inputWidth, inputHeight,
556 desiredWidth, desiredHeight, BoxDimensionTestBoth,
557 resultingWidth, resultingHeight );
559 DALI_TEST_EQUALS( resultingWidth, expectedWidth, location );
560 DALI_TEST_EQUALS( resultingHeight, expectedHeight, location );
564 * @brief Test downscaling of RGBA8888 images in raw image arrays.
566 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888(void)
568 uint32_t image[608*608];
569 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
571 image[i] = 0xffffffff;
573 unsigned char* const pixels = reinterpret_cast<unsigned char *> (image);
574 unsigned int resultingWidth = -1, resultingHeight = -1;
576 // Test downscaling where the input size is an exact multiple of the desired size:
577 // (We expect a perfect result here)
579 DownscaleInPlacePow2RGBA8888( pixels, 600, 600, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight );
580 DALI_TEST_EQUALS( resultingWidth, 75u, TEST_LOCATION );
581 DALI_TEST_EQUALS( resultingHeight, 75u, TEST_LOCATION );
583 DownscaleInPlacePow2RGBA8888( pixels, 512, 512, 16, 16, BoxDimensionTestBoth, resultingWidth, resultingHeight );
584 DALI_TEST_EQUALS( resultingWidth, 16u, TEST_LOCATION );
585 DALI_TEST_EQUALS( resultingHeight, 16u, TEST_LOCATION );
587 DownscaleInPlacePow2RGBA8888( pixels, 512, 64, 16, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight );
588 DALI_TEST_EQUALS( resultingWidth, 16u, TEST_LOCATION );
589 DALI_TEST_EQUALS( resultingHeight, 2u, TEST_LOCATION );
591 DownscaleInPlacePow2RGBA8888( pixels, 64, 1024, 4, 64, BoxDimensionTestBoth, resultingWidth, resultingHeight );
592 DALI_TEST_EQUALS( resultingWidth, 4u, TEST_LOCATION );
593 DALI_TEST_EQUALS( resultingHeight, 64u, TEST_LOCATION );
595 // Test downscaling where the input size is slightly off being an exact multiple of the desired size:
596 // (We expect a perfect match at the end because of rounding-down to an even width and height at each step)
598 DownscaleInPlacePow2RGBA8888( pixels, 601, 603, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight );
599 DALI_TEST_EQUALS( resultingWidth, 75u, TEST_LOCATION );
600 DALI_TEST_EQUALS( resultingHeight, 75u, TEST_LOCATION );
602 DownscaleInPlacePow2RGBA8888( pixels, 736 + 1, 352 + 3, 23, 11, BoxDimensionTestBoth, resultingWidth, resultingHeight );
603 DALI_TEST_EQUALS( resultingWidth, 23u, TEST_LOCATION );
604 DALI_TEST_EQUALS( resultingHeight, 11u, TEST_LOCATION );
606 DownscaleInPlacePow2RGBA8888( pixels, 384 + 3, 896 + 1, 3, 7, BoxDimensionTestBoth, resultingWidth, resultingHeight );
607 DALI_TEST_EQUALS( resultingWidth, 3u, TEST_LOCATION );
608 DALI_TEST_EQUALS( resultingHeight, 7u, TEST_LOCATION );
610 // Test downscales with source dimensions which are under a nice power of two by one:
612 // The target is hit exactly due to losing spare columns or rows at each iteration:
613 DownscaleInPlacePow2RGBA8888( pixels, 63, 31, 7, 3, BoxDimensionTestBoth, resultingWidth, resultingHeight );
614 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
615 DALI_TEST_EQUALS( resultingHeight, 3u, TEST_LOCATION );
617 // 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.
618 DownscaleInPlacePow2RGBA8888( pixels, 63, 31, 4, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight );
619 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
620 DALI_TEST_EQUALS( resultingHeight, 3u, TEST_LOCATION );
622 // Should stop at almost twice the requested dimensions:
623 DownscaleInPlacePow2RGBA8888( pixels, 15, 127, 4, 32, BoxDimensionTestBoth, resultingWidth, resultingHeight );
624 DALI_TEST_EQUALS( resultingWidth, 7u, TEST_LOCATION );
625 DALI_TEST_EQUALS( resultingHeight, 63u, TEST_LOCATION );
627 // Test downscales to 1 in one or both dimensions:
628 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
629 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 512, 1, 1, 1, 1, TEST_LOCATION );
630 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 16, 1, 16, 1, TEST_LOCATION );
631 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 7, 1, 16, 1, TEST_LOCATION );
632 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 7, 1, 16, 1, TEST_LOCATION );
633 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 5, 1, 16, 1, TEST_LOCATION );
634 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 32, 3, 1, 16, 1, TEST_LOCATION );
635 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 1, 1, 16, TEST_LOCATION );
636 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 16, 1, 16, TEST_LOCATION );
637 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 1, 3, 1, 16, TEST_LOCATION );
638 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 33, 1, 1, 1, 1, TEST_LOCATION );
639 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 17*19, 17*19, 1, 1, 1, 1, TEST_LOCATION );
640 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 33, 3, 1, 4, 4, TEST_LOCATION );
641 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 33, 9, 3, 1, 4, 1, TEST_LOCATION );
645 // Test downscales to zero in one or both dimensions:
646 // Scaling should stop when one or both dimensions reach 1.
647 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
648 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 512, 0, 0, 1, 1, TEST_LOCATION );
649 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 256, 0, 0, 2, 1, TEST_LOCATION );
650 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 128, 0, 0, 4, 1, TEST_LOCATION );
651 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 512, 16, 0, 0, 32, 1, TEST_LOCATION );
652 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 128, 512, 0, 0, 1, 4, TEST_LOCATION );
653 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 32, 512, 0, 0, 1, 16, TEST_LOCATION );
654 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 8, 512, 0, 0, 1, 64, TEST_LOCATION );
655 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 2, 512, 0, 0, 1, 256, TEST_LOCATION );
661 * @brief Test downscalings of RGBA8888 images in raw image arrays that should have no effect on the input.
663 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888Nops(void)
665 uint32_t image[608*608];
666 const uint32_t numPixels = sizeof(image) / sizeof(image[0]);
667 for( unsigned i = 0; i < numPixels; ++i )
669 image[i] = RandomPixelRGBA8888();
671 const uint32_t imageHash = HashPixels( image, numPixels );
672 unsigned char* const pixels = reinterpret_cast<unsigned char *> (image);
673 unsigned int resultingWidth = -1, resultingHeight = -1;
675 // Test downscales to the same size:
676 // The point is just to be sure the downscale is a NOP in this case:
678 DownscaleInPlacePow2RGBA8888( pixels, 600, 600, 600, 600, BoxDimensionTestBoth, resultingWidth, resultingHeight );
679 DALI_TEST_EQUALS( resultingWidth, 600u, TEST_LOCATION );
680 DALI_TEST_EQUALS( resultingHeight, 600u, TEST_LOCATION );
682 DownscaleInPlacePow2RGBA8888( pixels, 512, 128, 512, 128, BoxDimensionTestBoth, resultingWidth, resultingHeight );
683 DALI_TEST_EQUALS( resultingWidth, 512u, TEST_LOCATION );
684 DALI_TEST_EQUALS( resultingHeight, 128u, TEST_LOCATION );
686 DownscaleInPlacePow2RGBA8888( pixels, 17, 1001, 17, 1001, BoxDimensionTestBoth, resultingWidth, resultingHeight );
687 DALI_TEST_EQUALS( resultingWidth, 17u, TEST_LOCATION );
688 DALI_TEST_EQUALS( resultingHeight, 1001u, TEST_LOCATION );
690 // Test downscales that request a larger size (we never upscale so these are NOPs too):
691 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
692 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 300, 300, 600, 600, 300, 300, TEST_LOCATION );
693 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 3, 127, 99, 599, 3, 127, TEST_LOCATION );
694 TestDownscaleOutputsExpectedDimensionsRGBA8888( image, 600, 600, 999, 999, 600, 600, TEST_LOCATION ); //< checks no out of bounds mem access in this case
697 // Make sure that none of these NOP downscalings has affected the pixels of the image:
698 DALI_TEST_EQUALS( HashPixels( image, numPixels ), imageHash, TEST_LOCATION );
704 * @brief Do additional downscaling testing using RGB565 images in raw image
705 * arrays to shake out differences relating to the pixel format.
707 int UtcDaliImageOperationsDownscaleInPlacePow2RGB565(void)
709 // Test that calling with null and zero parameters doesn't blow up:
710 unsigned int outWidth, outHeight;
711 DownscaleInPlacePow2RGB565( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
713 uint16_t image[608*608];
714 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
719 // Do a straightforward test using an exact divisor target size:
720 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600, 600, 75, 75, 75, 75, TEST_LOCATION );
721 // Test that a slightly smaller than possible to achieve target results in the
722 // next-higher exact divisor output image dimensions:
723 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600, 600, 71, 69, 75, 75, TEST_LOCATION );
724 // Test that resizing from a starting size that is slightly larger than an exact
725 // multiple of the desired dimensions still results in the desired ones being
727 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
728 TestDownscaleOutputsExpectedDimensionsRGB565( image, 600 + 1, 600 + 1, 75, 75, 75, 75, TEST_LOCATION );
729 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 1, 512 + 1, 2, 4, 2, 4, TEST_LOCATION );
730 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 1, 128 + 1, 16, 4, 16, 4, TEST_LOCATION );
731 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 1, 64 + 1, 16, 2, 16, 2, TEST_LOCATION );
732 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 3, 512 + 3, 16, 16, 16, 16, TEST_LOCATION );
733 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 3, 256 + 3, 16, 8, 16, 8, TEST_LOCATION );
734 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 3, 512 + 3, 4, 8, 4, 8, TEST_LOCATION );
735 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 7, 512 + 7, 4, 8, 4, 8, TEST_LOCATION );
736 TestDownscaleOutputsExpectedDimensionsRGB565( image, 256 + 7, 512 + 7, 2, 4, 2, 4, TEST_LOCATION );
737 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 7, 128 + 7, 16, 4, 16, 4, TEST_LOCATION );
738 TestDownscaleOutputsExpectedDimensionsRGB565( image, 512 + 7, 64 + 7, 16, 2, 16, 2, TEST_LOCATION );
745 * @brief Do additional downscaling testing using 2-byte-per-pixel images in
746 * raw image arrays to shake out differences relating to the pixel format.
748 int UtcDaliImageOperationsDownscaleInPlacePow2ComponentPair(void)
750 // Simple test that a null pointer does not get dereferenced in the function:
751 unsigned int outWidth, outHeight;
752 DownscaleInPlacePow2ComponentPair( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
754 // Simple tests of dimensions output:
756 uint8_t image[608*608*2];
757 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
762 TestDownscaleOutputsExpectedDimensions2ComponentPair( image,
763 600, 600, //< Input dimensions
764 37, 37, //< Requested dimensions
765 37, 37, //< Expected output dimensions
767 TestDownscaleOutputsExpectedDimensions2ComponentPair( image,
768 600, 600, //< Input dimensions
769 34, 35, //< Requested dimensions to scale-down to
770 37, 37, //< Expected output dimensions achieved
772 ///@note: No need to be as comprehensive as with RGB888 and RGBA8888 as the logic is shared.
778 * @brief Do additional downscaling testing using 1-byte-per-pixel images in
779 * raw image arrays to shake out differences relating to the pixel format.
781 int UtcDaliImageOperationsDownscaleInPlacePow2SingleBytePerPixel(void)
783 // Simple test that a null pointer does not get dereferenced in the function:
784 unsigned int outWidth, outHeight;
785 DownscaleInPlacePow2SingleBytePerPixel( 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight );
787 // Tests of output dimensions from downscaling:
788 uint8_t image[608*608];
789 for( unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i )
794 TestDownscaleOutputsExpectedDimensionsSingleComponent( image,
795 600, 300, //< Input dimensions
796 150, 75, //< Requested dimensions to scale-down to
797 150, 75, //< Expected output dimensions achieved
799 TestDownscaleOutputsExpectedDimensionsSingleComponent( image, 577, 411, 142, 99, 144, 102, TEST_LOCATION );
805 * @brief Test the function for averaging pairs of pixels on a scanline.
807 int UtcDaliImageOperationsHalveScanlineInPlaceRGB888(void)
809 // Red and cyan, averaging to grey:
810 unsigned char shortEven[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
811 unsigned char shortOdd[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xC, 0xC, 0xC };
813 Dali::Internal::Platform::HalveScanlineInPlaceRGB888( shortEven, 4u );
814 Dali::Internal::Platform::HalveScanlineInPlaceRGB888( shortOdd, 4u );
815 for( unsigned i = 0; i < sizeof(shortEven) >> 1u ; ++i )
817 DALI_TEST_EQUALS( unsigned(shortEven[i]), 0x7fu, TEST_LOCATION );
818 DALI_TEST_EQUALS( unsigned(shortOdd[i]), 0x7fu, TEST_LOCATION );
825 * @brief Test the function for averaging pairs of pixels on a scanline.
827 int UtcDaliImageOperationsHalveScanlineInPlaceRGBA8888(void)
829 const size_t scanlineLength = 4096u;
830 Dali::Vector<uint32_t> scanline;
831 Dali::Vector<uint32_t> reference;
832 SetupScanlineForHalvingTestsRGBA8888( scanlineLength, scanline, reference );
834 HalveScanlineInPlaceRGBA8888( (uint8_t *) &scanline[0], scanlineLength );
836 // Check that the halving matches the independently calculated reference:
837 size_t numMatches = 0;
838 for( int i = 0, length = reference.Size(); i < length; ++i )
840 DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
841 numMatches += scanline[i] == reference[i];
843 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
845 // Test for no beyond-bounds writes:
846 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
848 DALI_TEST_EQUALS( reference[i], 0xEEEEEEEE, TEST_LOCATION );
855 * @brief Test the function for averaging pairs of pixels on a scanline.
857 int UtcDaliImageOperationsHalveScanlineInPlaceRGB565(void)
859 const size_t scanlineLength = 4096u;
860 Dali::Vector<uint16_t> scanline;
861 Dali::Vector<uint16_t> reference;
862 SetupScanlineForHalvingTestsRGB565( scanlineLength, scanline, reference );
864 HalveScanlineInPlaceRGB565( (unsigned char *) (&scanline[0]), scanlineLength );
866 // Check output against reference:
867 size_t numMatches = 0;
868 for( int i = 0, length = reference.Size(); i < length; ++i )
870 DALI_TEST_EQUALS( scanline[i], reference[i], TEST_LOCATION );
871 numMatches += scanline[i] == reference[i];
873 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
875 // Test for no beyond-bounds writes:
876 for( size_t i = scanlineLength / 2; i < reference.Capacity(); ++i )
878 DALI_TEST_EQUALS( reference[i], 0xEEEE, TEST_LOCATION );
885 * @brief Test the function for averaging pairs of pixels on a scanline.
887 int UtcDaliImageOperationsHalveScanlineInPlace2Bytes(void)
889 const size_t scanlineLength = 4096u;
890 Dali::Vector<uint8_t> scanline;
891 Dali::Vector<uint8_t> reference;
892 SetupScanlineForHalvingTests2Bytes( scanlineLength, scanline, reference );
894 HalveScanlineInPlace2Bytes( &scanline[0], scanlineLength );
896 // Test the output against the reference (no differences):
897 size_t numMatches = 0;
898 for( int i = 0, length = reference.Size(); i < length; ++i )
900 DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
901 numMatches += scanline[i] == reference[i];
903 // The number of matching bytes should be double the number of pixels, which happens to be the original scanline length in pixels:
904 DALI_TEST_EQUALS( numMatches, scanlineLength, TEST_LOCATION );
910 * @brief Test the function for averaging pairs of pixels on a scanline.
912 int UtcDaliImageOperationsHalveScanlineInPlace1Byte(void)
914 const size_t scanlineLength = 4096u;
915 Dali::Vector<uint8_t> scanline;
916 Dali::Vector<uint8_t> reference;
917 SetupScanlineForHalvingTests1Byte( scanlineLength, scanline, reference );
919 HalveScanlineInPlace1Byte( &scanline[0], scanlineLength );
921 // Test the reference matches the output:
922 size_t numMatches = 0;
923 for( int i = 0, length = reference.Size(); i < length; ++i )
925 DALI_TEST_EQUALS( 1u * scanline[i], 1u * reference[i], TEST_LOCATION );
926 numMatches += scanline[i] == reference[i];
928 DALI_TEST_EQUALS( numMatches, scanlineLength / 2, TEST_LOCATION );
934 * @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
936 int UtcDaliImageOperationsAverageScanlines1(void)
938 // Red and cyan, averaging to grey:
939 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
940 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
941 unsigned char outputBuffer[sizeof(shortEven1)];
943 AverageScanlines1( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) );
944 for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
946 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
949 // Longer test reusing RGBA setup/test logic:
950 const size_t scanlineLength = 4096u;
951 Dali::Vector<uint32_t> scanline1;
952 Dali::Vector<uint32_t> scanline2;
953 Dali::Vector<uint32_t> reference;
954 Dali::Vector<uint32_t> output;
955 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
957 AverageScanlines1( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 );
959 // Check the output matches the independently generated reference:
960 size_t numMatches = 0;
961 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
962 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
968 * @brief Test the function for averaging vertically-adjacent pairs of 2-byte-per-pixel pixels on a scanline.
970 int UtcDaliImageOperationsAverageScanlines2(void)
972 // Red and cyan, averaging to grey:
973 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
974 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
975 unsigned char outputBuffer[sizeof(shortEven1)];
977 AverageScanlines2( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 2 );
979 for( unsigned i = 0; i < sizeof(shortEven1); ++i )
981 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
984 // Longer test reusing RGBA setup/test logic:
985 const size_t scanlineLength = 4096u;
986 Dali::Vector<uint32_t> scanline1;
987 Dali::Vector<uint32_t> scanline2;
988 Dali::Vector<uint32_t> reference;
989 Dali::Vector<uint32_t> output;
990 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
992 AverageScanlines2( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 2 );
994 // Check the output matches the independently generated reference:
995 size_t numMatches = 0;
996 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
997 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1003 * @brief Test the function for averaging vertically-adjacent pairs of RGB888 pixels on a scanline.
1005 int UtcDaliImageOperationsAverageScanlines3(void)
1007 // Red and cyan, averaging to grey:
1008 unsigned char shortEven1[] = { 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff };
1009 unsigned char shortEven2[] = { 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0 };
1010 unsigned char outputBuffer[sizeof(shortEven1)];
1012 AverageScanlines3( shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 3 );
1013 for( unsigned i = 0; i < sizeof(shortEven1) ; ++i )
1015 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION );
1018 // Longer test reusing RGBA setup/test logic:
1019 const size_t scanlineLength = 3 * 4 * 90u;
1020 Dali::Vector<uint32_t> scanline1;
1021 Dali::Vector<uint32_t> scanline2;
1022 Dali::Vector<uint32_t> reference;
1023 Dali::Vector<uint32_t> output;
1024 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
1026 AverageScanlines3( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength * 4 / 3 );
1028 // Check the output matches the independently generated reference:
1029 size_t numMatches = 0;
1030 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
1031 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1037 * @brief Test the function for averaging vertically-adjacent pairs of RGBA8888 pixels on a scanline.
1039 int UtcDaliImageOperationsAverageScanlinesRGBA8888(void)
1041 const size_t scanlineLength = 4096u;
1042 Dali::Vector<uint32_t> scanline1;
1043 Dali::Vector<uint32_t> scanline2;
1044 Dali::Vector<uint32_t> reference;
1045 Dali::Vector<uint32_t> output;
1046 SetupScanlinesRGBA8888( scanlineLength, scanline1, scanline2, reference, output );
1048 AverageScanlinesRGBA8888( (const unsigned char*) &scanline1[0], (const unsigned char*) &scanline2[0], (unsigned char*) &output[0], scanlineLength );
1050 // Check the output matches the independently generated reference:
1051 size_t numMatches = 0;
1052 MatchScanlinesRGBA8888( reference, output, numMatches, TEST_LOCATION );
1053 DALI_TEST_EQUALS( numMatches, reference.Capacity(), TEST_LOCATION );
1059 * @brief Test the function for averaging vertically-adjacent pairs of RGB565 pixels on a scanline.
1061 int UtcDaliImageOperationsAverageScanlinesRGB565(void)
1063 // Red and cyan, averaging to grey:
1064 const uint16_t shortEven1[] = { 0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xBEEF, 0xBEEF };
1065 const uint16_t shortEven2[] = { 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0xBEEF, 0xBEEF };
1066 const size_t arrayLength = sizeof(shortEven1) / sizeof(shortEven1[0]) - 2;
1067 uint16_t outputBuffer[arrayLength + 2];
1068 outputBuffer[arrayLength] = 0xDEAD;
1069 outputBuffer[arrayLength+1] = 0xDEAD;
1071 Dali::Internal::Platform::AverageScanlinesRGB565( (const unsigned char*) shortEven1, (const unsigned char*) shortEven2, (unsigned char*) outputBuffer, arrayLength );
1072 for( unsigned i = 0; i < arrayLength ; ++i )
1074 DALI_TEST_EQUALS( unsigned(outputBuffer[i]), 0xffff - (1u << 15) - (1u << 10) - (1u << 4), TEST_LOCATION );
1077 // Check for buffer overrun:
1078 DALI_TEST_EQUALS( outputBuffer[arrayLength], 0xDEAD, TEST_LOCATION );
1079 DALI_TEST_EQUALS( outputBuffer[arrayLength+1], 0xDEAD, TEST_LOCATION );