2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/common/ref-counted-dali-vector.h>
20 #include <dali/internal/imaging/common/image-operations.h>
25 using namespace Dali::Internal::Platform;
30 * @brief Generate a random integer between zero and the parameter passed in.
32 uint32_t RandomInRange(uint32_t max)
34 const uint32_t randToMax = lrand48() % (max + 1);
39 * @brief Random number representable in an 8 bit color component.
41 inline uint32_t RandomComponent8()
43 return RandomInRange(255u);
47 * @brief Random number representable in a 5 bit color component.
49 inline uint32_t RandomComponent5()
51 return RandomInRange(31u);
55 * @brief Random number representable in a 6 bit color component.
57 inline uint32_t RandomComponent6()
59 return RandomInRange(63u);
63 * @brief RGBA8888 Pixels from separate color components.
65 inline uint32_t PixelRGBA8888(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
67 return (r << 24) + (g << 16) + (b << 8) + a;
71 * @brief RGB565 Pixels from color components in the low bits of passed-in words.
73 inline uint16_t PixelRGB565(uint32_t r, uint32_t g, uint32_t b)
75 return (r << 11) + (g << 5) + b;
79 * @brief RGBA8888 Pixels with random color components.
81 inline uint32_t RandomPixelRGBA8888()
83 const uint32_t randomPixel = PixelRGBA8888(RandomComponent8(), RandomComponent8(), RandomComponent8(), RandomComponent8());
88 * @brief Return a hash over a set of pixels.
90 * Used to check a buffer of pixels is unmodified by an operation given inputs
91 * that should mean that it is not changed.
93 inline uint32_t HashPixels(const uint32_t* const pixels, unsigned int numPixels)
97 for(unsigned int i = 0; i < numPixels; ++i)
99 hash = hash * 33 + pixels[i];
106 * @brief Build some dummy scanlines to exercise scanline averaging code on.
108 void SetupScanlineForHalvingTestsRGBA8888(size_t scanlineLength, Dali::Vector<uint32_t>& scanline, Dali::Vector<uint32_t>& reference)
110 scanline.Resize(scanlineLength);
111 reference.Resize(scanlineLength / 2 + 32);
113 // Prepare some random pixels:
114 srand(19 * 23 * 47 * 53);
115 for(size_t i = 0; i < scanlineLength / 2; ++i)
117 // Generate random colors:
118 const uint32_t red1 = RandomComponent8();
119 const uint32_t red2 = RandomComponent8();
120 const uint32_t green1 = RandomComponent8();
121 const uint32_t green2 = RandomComponent8();
122 const uint32_t blue1 = RandomComponent8();
123 const uint32_t blue2 = RandomComponent8();
124 const uint32_t alpha1 = RandomComponent8();
125 const uint32_t alpha2 = RandomComponent8();
127 // The average of these pixels should equal the reference:
128 scanline[i * 2] = PixelRGBA8888(red1, green1, blue1, alpha1);
129 scanline[i * 2 + 1] = PixelRGBA8888(red2, green2, blue2, alpha2);
131 // Average the two pixels manually as a reference:
132 reference[i] = (PixelRGBA8888((red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u));
135 for(size_t i = scanlineLength / 2; i < reference.Count(); ++i)
137 reference[i] = 0xEEEEEEEE;
142 * @brief Build some dummy scanlines to exercise scanline averaging code on.
144 void SetupScanlineForHalvingTestsRGB565(size_t scanlineLength, Dali::Vector<uint16_t>& scanline, Dali::Vector<uint16_t>& reference)
146 scanline.Resize(scanlineLength);
147 reference.Resize(scanlineLength / 2 + 32);
149 // Prepare some random pixels:
150 srand48(19 * 23 * 47 * 53);
151 for(size_t i = 0; i < scanlineLength / 2; ++i)
153 // Generate random colors:
154 const uint32_t red1 = RandomComponent5();
155 const uint32_t red2 = RandomComponent5();
156 const uint32_t green1 = RandomComponent6();
157 const uint32_t green2 = RandomComponent6();
158 const uint32_t blue1 = RandomComponent5();
159 const uint32_t blue2 = RandomComponent5();
161 // The average of these pixels should equal the reference:
162 scanline[i * 2] = PixelRGB565(red1, green1, blue1);
163 scanline[i * 2 + 1] = PixelRGB565(red2, green2, blue2);
165 // Average the two pixels manually as a reference:
166 reference[i] = (PixelRGB565((red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u));
169 for(size_t i = scanlineLength / 2; i < reference.Count(); ++i)
171 reference[i] = 0xEEEE;
176 * @brief Build some dummy scanlines to exercise scanline averaging code on.
178 void SetupScanlineForHalvingTests2Bytes(size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference)
180 scanline.Resize(scanlineLength * 2);
181 reference.Resize(scanlineLength + 32);
183 // Prepare some random pixels:
184 srand48(19 * 23 * 47 * 53 * 59);
185 for(size_t i = 0; i < scanlineLength / 2; ++i)
187 // Generate random colors:
188 const uint32_t c11 = RandomComponent8();
189 const uint32_t c12 = RandomComponent8();
190 const uint32_t c21 = RandomComponent8();
191 const uint32_t c22 = RandomComponent8();
193 // The average of these pixels should equal the reference:
194 scanline[i * 4] = c11;
195 scanline[i * 4 + 1] = c12;
196 scanline[i * 4 + 2] = c21;
197 scanline[i * 4 + 3] = c22;
199 // Average the two pixels manually as a reference:
200 reference[i * 2] = ((c11 + c21) >> 1u);
201 reference[i * 2 + 1] = ((c12 + c22) >> 1u);
204 for(size_t i = scanlineLength; i < reference.Count(); ++i)
211 * @brief Build some dummy 1 byte per pixel scanlines to exercise scanline averaging code on.
213 void SetupScanlineForHalvingTests1Byte(size_t scanlineLength, Dali::Vector<uint8_t>& scanline, Dali::Vector<uint8_t>& reference)
215 scanline.Resize(scanlineLength);
216 reference.Resize(scanlineLength / 2 + 32);
218 // Prepare some random pixels:
219 srand48(19 * 23 * 47 * 53 * 63);
220 for(size_t i = 0; i < scanlineLength / 2; ++i)
222 // Generate random colors:
223 const uint32_t c1 = RandomComponent8();
224 const uint32_t c2 = RandomComponent8();
226 // The average of these pixels should equal the reference:
227 scanline[i * 2] = c1;
228 scanline[i * 2 + 1] = c2;
230 // Average the two pixels manually as a reference:
231 reference[i] = ((c1 + c2) >> 1u);
234 for(size_t i = scanlineLength / 2; i < reference.Count(); ++i)
241 * @brief Build some dummy scanlines to exercise vertical averaging code on.
243 * All tested formats bar RGB565 can share this setup.
245 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)
247 scanline1.Resize(scanlineLength);
248 scanline2.Resize(scanlineLength);
249 reference.Resize(scanlineLength + 32);
250 output.Resize(scanlineLength + 32);
252 for(size_t i = scanlineLength; i < output.Count(); ++i)
254 output[i] = 0xDEADBEEF;
255 reference[i] = 0xDEADBEEF;
258 // Prepare some random pixels:
259 srand48(19 * 23 * 47);
260 for(size_t i = 0; i < scanlineLength; ++i)
262 // Generate random colors:
263 const uint32_t red1 = RandomComponent8();
264 const uint32_t red2 = RandomComponent8();
265 const uint32_t green1 = RandomComponent8();
266 const uint32_t green2 = RandomComponent8();
267 const uint32_t blue1 = RandomComponent8();
268 const uint32_t blue2 = RandomComponent8();
269 const uint32_t alpha1 = RandomComponent8();
270 const uint32_t alpha2 = RandomComponent8();
272 // The average of these pixels should equal the reference:
273 scanline1[i] = (PixelRGBA8888(red1, green1, blue1, alpha1));
274 scanline2[i] = (PixelRGBA8888(red2, green2, blue2, alpha2));
276 // Average the two pixels manually as a reference:
277 reference[i] = (PixelRGBA8888((red1 + red2) >> 1u, (green1 + green2) >> 1u, (blue1 + blue2) >> 1u, (alpha1 + alpha2) >> 1u));
282 * @brief Compares a scanline of interest to a reference, testing each pixel is the same.
284 void MatchScanlinesRGBA8888(Dali::Vector<uint32_t>& reference, Dali::Vector<uint32_t>& output, size_t& numMatches, const char* const location)
287 for(size_t i = 0, length = reference.Count(); i < length; ++i)
289 DALI_TEST_EQUALS(output[i], reference[i], location);
290 numMatches += output[i] == reference[i];
297 * @brief Test component averaging code.
299 int UtcDaliImageOperationsAverageComponent(void)
301 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(0u, 0u), 0u, TEST_LOCATION);
302 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(1u, 1u), 1u, TEST_LOCATION);
303 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(0xffffffffu >> 1u, 0xffffffffu >> 1u), 0xffffffffu >> 1u, TEST_LOCATION);
304 const unsigned int avg3 = Dali::Internal::Platform::AverageComponent(0xfffffffeu, 1u);
305 DALI_TEST_EQUALS(avg3, 0x7fffffffu, TEST_LOCATION);
306 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(255u, 255u), 255u, TEST_LOCATION);
307 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(512u, 0u), 256u, TEST_LOCATION);
308 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(511u, 0u), 255u, TEST_LOCATION);
309 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(510u, 0u), 255u, TEST_LOCATION);
310 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(509u, 0u), 254u, TEST_LOCATION);
311 DALI_TEST_EQUALS(Dali::Internal::Platform::AverageComponent(0u, 509u), 254u, TEST_LOCATION);
316 * @brief Test Pixel averaging code.
318 int UtcDaliImageOperationsAveragePixelRGBA8888(void)
320 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGBA8888(0u, 0u), 0u, TEST_LOCATION);
321 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGBA8888(0x01010101, 0x01010101), 0x01010101u, TEST_LOCATION);
322 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGBA8888(0x01010101, 0x03030303), 0x02020202u, TEST_LOCATION);
323 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGBA8888(0xffffffff, 0xffffffff), 0xffffffffu, TEST_LOCATION);
324 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGBA8888(0xffffffff, 0u), 0x7f7f7f7fu, TEST_LOCATION);
329 * @brief Test RGBA565 pixel averaging function.
331 int UtcDaliImageOperationsAveragePixelRGB565(void)
333 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0u, 0u), 0u, TEST_LOCATION);
334 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0xf800u, 0xf800u), 0xf800u, TEST_LOCATION);
335 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0xf800u, 0x800u), 1u << 15, TEST_LOCATION);
336 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0x7e0u, 0x7e0u), 0x7e0u, TEST_LOCATION);
337 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0x7e0u, 0x20u), 1u << 10, TEST_LOCATION);
338 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0x1f, 0x1f), 0x1fu, TEST_LOCATION);
339 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0x1f, 0x1), 1u << 4, TEST_LOCATION);
340 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0xf800u, 0x7e0u), 0x7800u + 0x3e0u, TEST_LOCATION);
341 DALI_TEST_EQUALS(Dali::Internal::Platform::AveragePixelRGB565(0xffff, 0xffff), 0xffffu, TEST_LOCATION);
346 * @brief Build a square bitmap, downscale it and assert the resulting bitmap has the right dimensions.
348 void TestDownscaledBitmapHasRightDimensionsAndFormat(
349 Pixel::Format format,
350 uint32_t sourceDimension,
351 uint32_t targetDimension,
352 uint32_t expectedDimension,
353 const char* const location)
355 ImageDimensions desired(targetDimension, targetDimension);
356 FittingMode::Type fittingMode(FittingMode::SHRINK_TO_FIT);
357 SamplingMode::Type samplingMode(SamplingMode::BOX);
359 Dali::Devel::PixelBuffer sourceBitmap = Dali::Devel::PixelBuffer::New(sourceDimension, sourceDimension, format);
361 Dali::Devel::PixelBuffer downScaled = DownscaleBitmap(sourceBitmap, desired, fittingMode, samplingMode);
363 DALI_TEST_EQUALS(downScaled.GetWidth(), expectedDimension, location);
364 DALI_TEST_EQUALS(downScaled.GetHeight(), expectedDimension, location);
365 DALI_TEST_EQUALS(downScaled.GetPixelFormat(), format, location);
369 * @brief Test the top-level function for reducing the dimension of a bitmap,
370 * feeding it each of the five pixel formats that are output by image loaders.
371 * Simply assert that the resulting bitmaps have the expected dimensions and
374 int UtcDaliImageOperationsDownscaleBitmap(void)
376 // Do Scalings that are expected to work for all pixels modes and assert the resulting bitmap dimensions:
378 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGBA8888, 1024, 8, 8, TEST_LOCATION);
379 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB888, 1024, 8, 8, TEST_LOCATION);
380 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB565, 1024, 8, 8, TEST_LOCATION);
381 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::LA88, 1024, 8, 8, TEST_LOCATION);
382 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::L8, 1024, 8, 8, TEST_LOCATION);
384 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGBA8888, 773, 1, 1, TEST_LOCATION);
385 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB888, 787, 1, 1, TEST_LOCATION);
386 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB565, 797, 1, 1, TEST_LOCATION);
387 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::LA88, 809, 1, 1, TEST_LOCATION);
388 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::L8, 811, 1, 1, TEST_LOCATION);
390 // Do Scalings that are expected to produce a slightly larger than requested image:
391 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGBA8888, 47, 7, 11, TEST_LOCATION);
392 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB888, 73, 17, 18, TEST_LOCATION);
393 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::RGB565, 61, 8, 15, TEST_LOCATION);
394 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::LA88, 19, 5, 9, TEST_LOCATION);
395 TestDownscaledBitmapHasRightDimensionsAndFormat(Pixel::L8, 353, 23, 44, TEST_LOCATION);
401 * @brief Test downscaling of RGB888 images as raw pixel arrays.
403 int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
405 unsigned outWidth = -1, outHeight = -1;
407 // Do downscaling to 1 x 1 so we can easily assert the value of the single pixel produced:
409 // Scale down a black/white checkerboard to mid-grey:
410 unsigned char check_4x4[16 * 3] = {
411 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff};
413 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight);
414 DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
415 DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
416 DALI_TEST_EQUALS(check_4x4[0], (unsigned char)0x7f, TEST_LOCATION);
418 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
419 unsigned char single_4x4[16 * 3] = {
420 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
421 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight);
422 DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
423 DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
424 DALI_TEST_EQUALS(single_4x4[0], (unsigned char)0xf, TEST_LOCATION);
426 // Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
427 // (white pixel at bottom-right of image)
428 unsigned char single_4x4_2[16 * 3] = {
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff};
430 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight);
431 DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
432 DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
433 DALI_TEST_EQUALS(single_4x4_2[0], (unsigned char)0xf, TEST_LOCATION);
435 // Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
437 unsigned char magenta_600_x_600[608 * 608 * 3];
438 for(unsigned int i = 0; i < sizeof(magenta_600_x_600); i += 3)
440 magenta_600_x_600[i] = 0xff;
441 magenta_600_x_600[i + 1] = 0;
442 magenta_600_x_600[i + 2] = 0xff;
445 // Scaling to 0 x 0 should stop at 1 x 1:
446 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 0, 0, BoxDimensionTestBoth, outWidth, outHeight);
447 DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
448 DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
450 // Scaling to 1 x 1 should hit 1 x 1:
451 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 608, 608, 1, 1, BoxDimensionTestBoth, outWidth, outHeight);
452 DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
453 DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
455 // Scaling to original dimensions should NOP:
456 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384, 384, BoxDimensionTestBoth, outWidth, outHeight);
457 DALI_TEST_EQUALS(outWidth, 384u, TEST_LOCATION);
458 DALI_TEST_EQUALS(outHeight, 384u, TEST_LOCATION);
460 // More dimension tests:
462 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 44, 11, BoxDimensionTestBoth, outWidth, outHeight);
463 DALI_TEST_EQUALS(outWidth, 44u, TEST_LOCATION);
464 DALI_TEST_EQUALS(outHeight, 44u, TEST_LOCATION);
466 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 3, 48, BoxDimensionTestBoth, outWidth, outHeight);
467 DALI_TEST_EQUALS(outWidth, 48u, TEST_LOCATION);
468 DALI_TEST_EQUALS(outHeight, 48u, TEST_LOCATION);
470 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 3, 3, BoxDimensionTestBoth, outWidth, outHeight);
471 DALI_TEST_CHECK(outWidth == 3u && outHeight == 3u);
473 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 320, 320, 5, 5, BoxDimensionTestBoth, outWidth, outHeight);
474 DALI_TEST_CHECK(outWidth == 5u && outHeight == 5u);
476 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 448, 448, 7, 7, BoxDimensionTestBoth, outWidth, outHeight);
477 DALI_TEST_CHECK(outWidth == 7u && outHeight == 7u);
479 Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 11, 11, BoxDimensionTestBoth, outWidth, outHeight);
480 DALI_TEST_CHECK(outWidth == 11u && outHeight == 11u);
482 // Check that no pixel values were modified by the repeated averaging of identical pixels in tests above:
483 unsigned int numNonMagenta = 0u;
484 for(unsigned i = 0; i < sizeof(magenta_600_x_600); i += 3)
486 numNonMagenta += magenta_600_x_600[i] == 0xff && magenta_600_x_600[i + 1] == 0x00 && magenta_600_x_600[i + 2] == 0xff ? 0 : 1;
488 DALI_TEST_EQUALS(numNonMagenta, 0u, TEST_LOCATION);
494 * @brief Test that resizing RGBA8888 images as raw pixel arrays produces a result of the correct dimensions.
496 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)
498 unsigned int resultingWidth = -1, resultingHeight = -1;
499 Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
500 reinterpret_cast<unsigned char*>(pixels),
505 BoxDimensionTestBoth,
509 DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
510 DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
514 * @brief Test that resizing RGB565 images as raw pixel arrays produces a result of the correct dimensions.
516 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)
518 unsigned int resultingWidth = -1, resultingHeight = -1;
519 Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
520 reinterpret_cast<unsigned char*>(pixels),
525 BoxDimensionTestBoth,
529 DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
530 DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
534 * @brief Test that resizing 2-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
536 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)
538 unsigned int resultingWidth = -1, resultingHeight = -1;
539 Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
545 BoxDimensionTestBoth,
549 DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
550 DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
554 * @brief Test that resizing single-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
556 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)
558 unsigned int resultingWidth = -1, resultingHeight = -1;
559 Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
565 BoxDimensionTestBoth,
569 DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
570 DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
574 * @brief Test downscaling of RGBA8888 images in raw image arrays.
576 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888(void)
578 uint32_t image[608 * 608];
579 for(unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i)
581 image[i] = 0xffffffff;
583 unsigned char* const pixels = reinterpret_cast<unsigned char*>(image);
584 unsigned int resultingWidth = -1, resultingHeight = -1;
586 // Test downscaling where the input size is an exact multiple of the desired size:
587 // (We expect a perfect result here)
589 DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight);
590 DALI_TEST_EQUALS(resultingWidth, 75u, TEST_LOCATION);
591 DALI_TEST_EQUALS(resultingHeight, 75u, TEST_LOCATION);
593 DownscaleInPlacePow2RGBA8888(pixels, 512, 512, 16, 16, BoxDimensionTestBoth, resultingWidth, resultingHeight);
594 DALI_TEST_EQUALS(resultingWidth, 16u, TEST_LOCATION);
595 DALI_TEST_EQUALS(resultingHeight, 16u, TEST_LOCATION);
597 DownscaleInPlacePow2RGBA8888(pixels, 512, 64, 16, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight);
598 DALI_TEST_EQUALS(resultingWidth, 16u, TEST_LOCATION);
599 DALI_TEST_EQUALS(resultingHeight, 2u, TEST_LOCATION);
601 DownscaleInPlacePow2RGBA8888(pixels, 64, 1024, 4, 64, BoxDimensionTestBoth, resultingWidth, resultingHeight);
602 DALI_TEST_EQUALS(resultingWidth, 4u, TEST_LOCATION);
603 DALI_TEST_EQUALS(resultingHeight, 64u, TEST_LOCATION);
605 // Test downscaling where the input size is slightly off being an exact multiple of the desired size:
606 // (We expect a perfect match at the end because of rounding-down to an even width and height at each step)
608 DownscaleInPlacePow2RGBA8888(pixels, 601, 603, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight);
609 DALI_TEST_EQUALS(resultingWidth, 75u, TEST_LOCATION);
610 DALI_TEST_EQUALS(resultingHeight, 75u, TEST_LOCATION);
612 DownscaleInPlacePow2RGBA8888(pixels, 736 + 1, 352 + 3, 23, 11, BoxDimensionTestBoth, resultingWidth, resultingHeight);
613 DALI_TEST_EQUALS(resultingWidth, 23u, TEST_LOCATION);
614 DALI_TEST_EQUALS(resultingHeight, 11u, TEST_LOCATION);
616 DownscaleInPlacePow2RGBA8888(pixels, 384 + 3, 896 + 1, 3, 7, BoxDimensionTestBoth, resultingWidth, resultingHeight);
617 DALI_TEST_EQUALS(resultingWidth, 3u, TEST_LOCATION);
618 DALI_TEST_EQUALS(resultingHeight, 7u, TEST_LOCATION);
620 // Test downscales with source dimensions which are under a nice power of two by one:
622 // The target is hit exactly due to losing spare columns or rows at each iteration:
623 DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 7, 3, BoxDimensionTestBoth, resultingWidth, resultingHeight);
624 DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
625 DALI_TEST_EQUALS(resultingHeight, 3u, TEST_LOCATION);
627 // 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.
628 DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 4, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight);
629 DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
630 DALI_TEST_EQUALS(resultingHeight, 3u, TEST_LOCATION);
632 // Should stop at almost twice the requested dimensions:
633 DownscaleInPlacePow2RGBA8888(pixels, 15, 127, 4, 32, BoxDimensionTestBoth, resultingWidth, resultingHeight);
634 DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
635 DALI_TEST_EQUALS(resultingHeight, 63u, TEST_LOCATION);
637 // Test downscales to 1 in one or both dimensions:
638 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
639 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 512, 1, 1, 1, 1, TEST_LOCATION);
640 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 32, 16, 1, 16, 1, TEST_LOCATION);
641 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 32, 7, 1, 16, 1, TEST_LOCATION);
642 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 32, 7, 1, 16, 1, TEST_LOCATION);
643 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 32, 5, 1, 16, 1, TEST_LOCATION);
644 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 32, 3, 1, 16, 1, TEST_LOCATION);
645 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 32, 512, 1, 1, 1, 16, TEST_LOCATION);
646 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 32, 512, 1, 16, 1, 16, TEST_LOCATION);
647 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 32, 512, 1, 3, 1, 16, TEST_LOCATION);
648 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 33, 33, 1, 1, 1, 1, TEST_LOCATION);
649 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 17 * 19, 17 * 19, 1, 1, 1, 1, TEST_LOCATION);
650 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 33, 33, 3, 1, 4, 4, TEST_LOCATION);
651 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 33, 9, 3, 1, 4, 1, TEST_LOCATION);
653 // Test downscales to zero in one or both dimensions:
654 // Scaling should stop when one or both dimensions reach 1.
655 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
656 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 512, 0, 0, 1, 1, TEST_LOCATION);
657 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 256, 0, 0, 2, 1, TEST_LOCATION);
658 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 128, 0, 0, 4, 1, TEST_LOCATION);
659 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 512, 16, 0, 0, 32, 1, TEST_LOCATION);
660 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 128, 512, 0, 0, 1, 4, TEST_LOCATION);
661 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 32, 512, 0, 0, 1, 16, TEST_LOCATION);
662 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 8, 512, 0, 0, 1, 64, TEST_LOCATION);
663 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 2, 512, 0, 0, 1, 256, TEST_LOCATION);
669 * @brief Test downscalings of RGBA8888 images in raw image arrays that should have no effect on the input.
671 int UtcDaliImageOperationsDownscaleInPlacePow2RGBA8888Nops(void)
673 uint32_t image[608 * 608];
674 const uint32_t numPixels = sizeof(image) / sizeof(image[0]);
675 for(unsigned i = 0; i < numPixels; ++i)
677 image[i] = RandomPixelRGBA8888();
679 const uint32_t imageHash = HashPixels(image, numPixels);
680 unsigned char* const pixels = reinterpret_cast<unsigned char*>(image);
681 unsigned int resultingWidth = -1, resultingHeight = -1;
683 // Test downscales to the same size:
684 // The point is just to be sure the downscale is a NOP in this case:
686 DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 600, 600, BoxDimensionTestBoth, resultingWidth, resultingHeight);
687 DALI_TEST_EQUALS(resultingWidth, 600u, TEST_LOCATION);
688 DALI_TEST_EQUALS(resultingHeight, 600u, TEST_LOCATION);
690 DownscaleInPlacePow2RGBA8888(pixels, 512, 128, 512, 128, BoxDimensionTestBoth, resultingWidth, resultingHeight);
691 DALI_TEST_EQUALS(resultingWidth, 512u, TEST_LOCATION);
692 DALI_TEST_EQUALS(resultingHeight, 128u, TEST_LOCATION);
694 DownscaleInPlacePow2RGBA8888(pixels, 17, 1001, 17, 1001, BoxDimensionTestBoth, resultingWidth, resultingHeight);
695 DALI_TEST_EQUALS(resultingWidth, 17u, TEST_LOCATION);
696 DALI_TEST_EQUALS(resultingHeight, 1001u, TEST_LOCATION);
698 // Test downscales that request a larger size (we never upscale so these are NOPs too):
699 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
700 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 300, 300, 600, 600, 300, 300, TEST_LOCATION);
701 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 3, 127, 99, 599, 3, 127, TEST_LOCATION);
702 TestDownscaleOutputsExpectedDimensionsRGBA8888(image, 600, 600, 999, 999, 600, 600, TEST_LOCATION); //< checks no out of bounds mem access in this case
704 // Make sure that none of these NOP downscalings has affected the pixels of the image:
705 DALI_TEST_EQUALS(HashPixels(image, numPixels), imageHash, TEST_LOCATION);
711 * @brief Do additional downscaling testing using RGB565 images in raw image
712 * arrays to shake out differences relating to the pixel format.
714 int UtcDaliImageOperationsDownscaleInPlacePow2RGB565(void)
716 // Test that calling with null and zero parameters doesn't blow up:
717 unsigned int outWidth, outHeight;
718 DownscaleInPlacePow2RGB565(0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight);
720 uint16_t image[608 * 608];
721 for(unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i)
726 // Do a straightforward test using an exact divisor target size:
727 TestDownscaleOutputsExpectedDimensionsRGB565(image, 600, 600, 75, 75, 75, 75, TEST_LOCATION);
728 // Test that a slightly smaller than possible to achieve target results in the
729 // next-higher exact divisor output image dimensions:
730 TestDownscaleOutputsExpectedDimensionsRGB565(image, 600, 600, 71, 69, 75, 75, TEST_LOCATION);
731 // Test that resizing from a starting size that is slightly larger than an exact
732 // multiple of the desired dimensions still results in the desired ones being
734 // Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
735 TestDownscaleOutputsExpectedDimensionsRGB565(image, 600 + 1, 600 + 1, 75, 75, 75, 75, TEST_LOCATION);
736 TestDownscaleOutputsExpectedDimensionsRGB565(image, 256 + 1, 512 + 1, 2, 4, 2, 4, TEST_LOCATION);
737 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 1, 128 + 1, 16, 4, 16, 4, TEST_LOCATION);
738 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 1, 64 + 1, 16, 2, 16, 2, TEST_LOCATION);
739 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 3, 512 + 3, 16, 16, 16, 16, TEST_LOCATION);
740 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 3, 256 + 3, 16, 8, 16, 8, TEST_LOCATION);
741 TestDownscaleOutputsExpectedDimensionsRGB565(image, 256 + 3, 512 + 3, 4, 8, 4, 8, TEST_LOCATION);
742 TestDownscaleOutputsExpectedDimensionsRGB565(image, 256 + 7, 512 + 7, 4, 8, 4, 8, TEST_LOCATION);
743 TestDownscaleOutputsExpectedDimensionsRGB565(image, 256 + 7, 512 + 7, 2, 4, 2, 4, TEST_LOCATION);
744 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 7, 128 + 7, 16, 4, 16, 4, TEST_LOCATION);
745 TestDownscaleOutputsExpectedDimensionsRGB565(image, 512 + 7, 64 + 7, 16, 2, 16, 2, TEST_LOCATION);
751 * @brief Do additional downscaling testing using 2-byte-per-pixel images in
752 * raw image arrays to shake out differences relating to the pixel format.
754 int UtcDaliImageOperationsDownscaleInPlacePow2ComponentPair(void)
756 // Simple test that a null pointer does not get dereferenced in the function:
757 unsigned int outWidth, outHeight;
758 DownscaleInPlacePow2ComponentPair(0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight);
760 // Simple tests of dimensions output:
762 uint8_t image[608 * 608 * 2];
763 for(unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i)
768 TestDownscaleOutputsExpectedDimensions2ComponentPair(image,
770 600, //< Input dimensions
772 37, //< Requested dimensions
774 37, //< Expected output dimensions
776 TestDownscaleOutputsExpectedDimensions2ComponentPair(image,
778 600, //< Input dimensions
780 35, //< Requested dimensions to scale-down to
782 37, //< Expected output dimensions achieved
784 ///@note: No need to be as comprehensive as with RGB888 and RGBA8888 as the logic is shared.
790 * @brief Do additional downscaling testing using 1-byte-per-pixel images in
791 * raw image arrays to shake out differences relating to the pixel format.
793 int UtcDaliImageOperationsDownscaleInPlacePow2SingleBytePerPixel(void)
795 // Simple test that a null pointer does not get dereferenced in the function:
796 unsigned int outWidth, outHeight;
797 DownscaleInPlacePow2SingleBytePerPixel(0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight);
799 // Tests of output dimensions from downscaling:
800 uint8_t image[608 * 608];
801 for(unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i)
806 TestDownscaleOutputsExpectedDimensionsSingleComponent(image,
808 300, //< Input dimensions
810 75, //< Requested dimensions to scale-down to
812 75, //< Expected output dimensions achieved
814 TestDownscaleOutputsExpectedDimensionsSingleComponent(image, 577, 411, 142, 99, 144, 102, TEST_LOCATION);
820 * @brief Test the function for averaging pairs of pixels on a scanline.
822 int UtcDaliImageOperationsHalveScanlineInPlaceRGB888(void)
824 // Red and cyan, averaging to grey:
825 unsigned char shortEven[] = {0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff};
826 unsigned char shortOdd[] = {0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xC, 0xC, 0xC};
828 Dali::Internal::Platform::HalveScanlineInPlaceRGB888(shortEven, 4u);
829 Dali::Internal::Platform::HalveScanlineInPlaceRGB888(shortOdd, 4u);
831 for(unsigned i = 0; i < (sizeof(shortEven) >> 1u); ++i)
833 DALI_TEST_EQUALS(unsigned(shortEven[i]), 0x7fu, TEST_LOCATION);
834 DALI_TEST_EQUALS(unsigned(shortOdd[i]), 0x7fu, TEST_LOCATION);
841 * @brief Test the function for averaging pairs of pixels on a scanline.
843 int UtcDaliImageOperationsHalveScanlineInPlaceRGBA8888(void)
845 const size_t scanlineLength = 4096u;
846 Dali::Vector<uint32_t> scanline;
847 Dali::Vector<uint32_t> reference;
848 SetupScanlineForHalvingTestsRGBA8888(scanlineLength, scanline, reference);
850 HalveScanlineInPlaceRGBA8888((uint8_t*)&scanline[0], scanlineLength);
852 // Check that the halving matches the independently calculated reference:
853 size_t numMatches = 0;
854 for(int i = 0, length = scanlineLength / 2; i < length; ++i)
856 DALI_TEST_EQUALS(scanline[i], reference[i], TEST_LOCATION);
857 numMatches += scanline[i] == reference[i];
859 DALI_TEST_EQUALS(numMatches, scanlineLength / 2, TEST_LOCATION);
861 // Test for no beyond-bounds writes:
862 for(size_t i = scanlineLength / 2; i < reference.Count(); ++i)
864 DALI_TEST_EQUALS(reference[i], (uint32_t)0xEEEEEEEE, TEST_LOCATION);
871 * @brief Test the function for averaging pairs of pixels on a scanline.
873 int UtcDaliImageOperationsHalveScanlineInPlaceRGB565(void)
875 const size_t scanlineLength = 4096u;
876 Dali::Vector<uint16_t> scanline;
877 Dali::Vector<uint16_t> reference;
878 SetupScanlineForHalvingTestsRGB565(scanlineLength, scanline, reference);
880 HalveScanlineInPlaceRGB565((unsigned char*)(&scanline[0]), scanlineLength);
882 // Check output against reference:
883 size_t numMatches = 0;
884 for(int i = 0, length = scanlineLength / 2; i < length; ++i)
886 DALI_TEST_EQUALS(scanline[i], reference[i], TEST_LOCATION);
887 numMatches += scanline[i] == reference[i];
889 DALI_TEST_EQUALS(numMatches, scanlineLength / 2, TEST_LOCATION);
891 // Test for no beyond-bounds writes:
892 for(size_t i = scanlineLength / 2; i < reference.Count(); ++i)
894 DALI_TEST_EQUALS(reference[i], (uint16_t)0xEEEE, TEST_LOCATION);
901 * @brief Test the function for averaging pairs of pixels on a scanline.
903 int UtcDaliImageOperationsHalveScanlineInPlace2Bytes(void)
905 const size_t scanlineLength = 4096u;
906 Dali::Vector<uint8_t> scanline;
907 Dali::Vector<uint8_t> reference;
908 SetupScanlineForHalvingTests2Bytes(scanlineLength, scanline, reference);
910 HalveScanlineInPlace2Bytes(&scanline[0], scanlineLength);
912 // Test the output against the reference (no differences):
913 size_t numMatches = 0;
914 for(int i = 0, length = scanlineLength; i < length; ++i)
916 DALI_TEST_EQUALS(1u * scanline[i], 1u * reference[i], TEST_LOCATION);
917 numMatches += scanline[i] == reference[i];
919 // The number of matching bytes should be double the number of pixels, which happens to be the original scanline length in pixels:
920 DALI_TEST_EQUALS(numMatches, scanlineLength, TEST_LOCATION);
926 * @brief Test the function for averaging pairs of pixels on a scanline.
928 int UtcDaliImageOperationsHalveScanlineInPlace1Byte(void)
930 const size_t scanlineLength = 4096u;
931 Dali::Vector<uint8_t> scanline;
932 Dali::Vector<uint8_t> reference;
933 SetupScanlineForHalvingTests1Byte(scanlineLength, scanline, reference);
935 HalveScanlineInPlace1Byte(&scanline[0], scanlineLength);
937 // Test the reference matches the output:
938 size_t numMatches = 0;
939 for(int i = 0, length = scanlineLength / 2; i < length; ++i)
941 DALI_TEST_EQUALS(1u * scanline[i], 1u * reference[i], TEST_LOCATION);
942 numMatches += scanline[i] == reference[i];
944 // Only half will be matched
945 DALI_TEST_EQUALS(numMatches, scanlineLength / 2, TEST_LOCATION);
951 * @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
953 int UtcDaliImageOperationsAverageScanlines1ExceptTest(void)
955 // Edge cases for averagescanlines1:
956 unsigned char shortEven1[] = {0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x02, 0x03, 0x00, 0x01};
957 unsigned char shortEven2[] = {0x00, 0xff, 0x00, 0xff, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x03, 0x02};
958 unsigned char expectBuffer[] = {0x00, 0x7f, 0x7f, 0xff, 0x80, 0x7f, 0x80, 0x7f, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
959 unsigned char outputBuffer[sizeof(shortEven1)];
961 AverageScanlines1(shortEven1, shortEven2, outputBuffer, sizeof(shortEven1));
962 for(unsigned i = 0; i < sizeof(shortEven1); ++i)
964 DALI_TEST_EQUALS(unsigned(outputBuffer[i]), unsigned(expectBuffer[i]), TEST_LOCATION);
971 * @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
973 int UtcDaliImageOperationsAverageScanlines1(void)
975 // Red and cyan, averaging to grey:
976 unsigned char shortEven1[] = {0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff};
977 unsigned char shortEven2[] = {0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0};
978 unsigned char outputBuffer[sizeof(shortEven1)];
980 AverageScanlines1(shortEven1, shortEven2, outputBuffer, sizeof(shortEven1));
981 for(unsigned i = 0; i < sizeof(shortEven1); ++i)
983 DALI_TEST_EQUALS(unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION);
986 // Longer test reusing RGBA setup/test logic:
988 const size_t scanlineLength = 4096u;
989 Dali::Vector<uint32_t> scanline1;
990 Dali::Vector<uint32_t> scanline2;
991 Dali::Vector<uint32_t> reference;
992 Dali::Vector<uint32_t> output;
993 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
995 AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
997 // Check the output matches the independently generated reference:
998 size_t numMatches = 0;
999 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1000 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1003 // Longer test reusing RGBA setup/test logic with none-8-divisable length
1005 const size_t scanlineLength = 1003u;
1006 Dali::Vector<uint32_t> scanline1;
1007 Dali::Vector<uint32_t> scanline2;
1008 Dali::Vector<uint32_t> reference;
1009 Dali::Vector<uint32_t> output;
1010 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1012 AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
1014 // Check the output matches the independently generated reference:
1015 size_t numMatches = 0;
1016 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1017 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1020 // Very short test reusing RGBA setup/test logic with less-than-8 length
1022 const size_t scanlineLength = 1003u;
1023 Dali::Vector<uint32_t> scanline1;
1024 Dali::Vector<uint32_t> scanline2;
1025 Dali::Vector<uint32_t> reference;
1026 Dali::Vector<uint32_t> output;
1027 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1029 AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
1031 // Check the output matches the independently generated reference:
1032 size_t numMatches = 0;
1033 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1034 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1041 * @brief Test the function for averaging vertically-adjacent pairs of 2-byte-per-pixel pixels on a scanline.
1043 int UtcDaliImageOperationsAverageScanlines2(void)
1045 // Red and cyan, averaging to grey:
1046 unsigned char shortEven1[] = {0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff};
1047 unsigned char shortEven2[] = {0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0};
1048 unsigned char outputBuffer[sizeof(shortEven1)];
1050 AverageScanlines2(shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 2);
1052 for(unsigned i = 0; i < sizeof(shortEven1); ++i)
1054 DALI_TEST_EQUALS(unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION);
1057 // Longer test reusing RGBA setup/test logic:
1059 const size_t scanlineLength = 4096u;
1060 Dali::Vector<uint32_t> scanline1;
1061 Dali::Vector<uint32_t> scanline2;
1062 Dali::Vector<uint32_t> reference;
1063 Dali::Vector<uint32_t> output;
1064 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1066 AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
1068 // Check the output matches the independently generated reference:
1069 size_t numMatches = 0;
1070 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1071 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1074 // Longer test reusing RGBA setup/test logic with none-8-divisable length
1076 const size_t scanlineLength = 501u;
1077 Dali::Vector<uint32_t> scanline1;
1078 Dali::Vector<uint32_t> scanline2;
1079 Dali::Vector<uint32_t> reference;
1080 Dali::Vector<uint32_t> output;
1081 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1083 AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
1085 // Check the output matches the independently generated reference:
1086 size_t numMatches = 0;
1087 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1088 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1091 // Very short test reusing RGBA setup/test logic with less-than-8 length
1093 const size_t scanlineLength = 3u;
1094 Dali::Vector<uint32_t> scanline1;
1095 Dali::Vector<uint32_t> scanline2;
1096 Dali::Vector<uint32_t> reference;
1097 Dali::Vector<uint32_t> output;
1098 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1100 AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
1102 // Check the output matches the independently generated reference:
1103 size_t numMatches = 0;
1104 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1105 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1112 * @brief Test the function for averaging vertically-adjacent pairs of RGB888 pixels on a scanline.
1114 int UtcDaliImageOperationsAverageScanlines3(void)
1116 // Red and cyan, averaging to grey:
1117 unsigned char shortEven1[] = {0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff};
1118 unsigned char shortEven2[] = {0, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0};
1119 unsigned char outputBuffer[sizeof(shortEven1)];
1121 AverageScanlines3(shortEven1, shortEven2, outputBuffer, sizeof(shortEven1) / 3);
1122 for(unsigned i = 0; i < sizeof(shortEven1); ++i)
1124 DALI_TEST_EQUALS(unsigned(outputBuffer[i]), 0x7fu, TEST_LOCATION);
1127 // Longer test reusing RGBA setup/test logic:
1129 const size_t scanlineLength = 3 * 4 * 90u;
1130 Dali::Vector<uint32_t> scanline1;
1131 Dali::Vector<uint32_t> scanline2;
1132 Dali::Vector<uint32_t> reference;
1133 Dali::Vector<uint32_t> output;
1134 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1136 AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
1138 // Check the output matches the independently generated reference:
1139 size_t numMatches = 0;
1140 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1141 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1144 // Longer test reusing RGBA setup/test logic with none-8-divisable length
1146 const size_t scanlineLength = 3 * 501u;
1147 Dali::Vector<uint32_t> scanline1;
1148 Dali::Vector<uint32_t> scanline2;
1149 Dali::Vector<uint32_t> reference;
1150 Dali::Vector<uint32_t> output;
1151 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1153 AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
1155 // Check the output matches the independently generated reference:
1156 size_t numMatches = 0;
1157 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1158 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1161 // Very short test reusing RGBA setup/test logic with less-than-8 length
1163 const size_t scanlineLength = 3u;
1164 Dali::Vector<uint32_t> scanline1;
1165 Dali::Vector<uint32_t> scanline2;
1166 Dali::Vector<uint32_t> reference;
1167 Dali::Vector<uint32_t> output;
1168 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1170 AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
1172 // Check the output matches the independently generated reference:
1173 size_t numMatches = 0;
1174 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1175 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1182 * @brief Test the function for averaging vertically-adjacent pairs of RGBA8888 pixels on a scanline.
1184 int UtcDaliImageOperationsAverageScanlinesRGBA8888(void)
1186 const size_t scanlineLength = 4096u;
1187 Dali::Vector<uint32_t> scanline1;
1188 Dali::Vector<uint32_t> scanline2;
1189 Dali::Vector<uint32_t> reference;
1190 Dali::Vector<uint32_t> output;
1191 SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
1193 AverageScanlinesRGBA8888((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength);
1195 // Check the output matches the independently generated reference:
1196 size_t numMatches = 0;
1197 MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
1198 DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
1204 * @brief Test the function for averaging vertically-adjacent pairs of RGB565 pixels on a scanline.
1206 int UtcDaliImageOperationsAverageScanlinesRGB565(void)
1208 // Red and cyan, averaging to grey:
1209 const uint16_t shortEven1[] = {0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xf800, 0xBEEF, 0xBEEF};
1210 const uint16_t shortEven2[] = {0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0x7ff, 0xBEEF, 0xBEEF};
1211 const size_t arrayLength = sizeof(shortEven1) / sizeof(shortEven1[0]) - 2;
1212 uint16_t outputBuffer[arrayLength + 2];
1213 outputBuffer[arrayLength] = 0xDEAD;
1214 outputBuffer[arrayLength + 1] = 0xDEAD;
1216 Dali::Internal::Platform::AverageScanlinesRGB565((const unsigned char*)shortEven1, (const unsigned char*)shortEven2, (unsigned char*)outputBuffer, arrayLength);
1217 for(unsigned i = 0; i < arrayLength; ++i)
1219 DALI_TEST_EQUALS(unsigned(outputBuffer[i]), 0xffff - (1u << 15) - (1u << 10) - (1u << 4), TEST_LOCATION);
1222 // Check for buffer overrun:
1223 DALI_TEST_EQUALS(outputBuffer[arrayLength], (uint16_t)0xDEAD, TEST_LOCATION);
1224 DALI_TEST_EQUALS(outputBuffer[arrayLength + 1], (uint16_t)0xDEAD, TEST_LOCATION);
1231 void MakeSingleColorImageRGBA8888(unsigned int width, unsigned int height, uint32_t* inputImage)
1233 const uint32_t inPixel = PixelRGBA8888(255, 192, 128, 64);
1234 for(unsigned int i = 0; i < width * height; ++i)
1236 inputImage[i] = inPixel;
1241 * @brief Make an image with a checkerboard pattern.
1242 * @note This is an easy pattern to scan for correctness after a downscaling test.
1244 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > MakeCheckerboardImageRGBA8888(unsigned int width, unsigned int height, unsigned int checkerSize)
1246 const unsigned int imageWidth = width * checkerSize;
1247 const unsigned int imageHeight = height * checkerSize;
1248 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = new Dali::RefCountedVector<uint32_t>;
1249 image->GetVector().Resize(imageWidth * imageHeight);
1251 uint32_t rowColor = 0xffffffff;
1252 for(unsigned int cy = 0; cy < height; ++cy)
1254 rowColor = rowColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1255 uint32_t checkColor = rowColor;
1256 for(unsigned int cx = 0; cx < width; ++cx)
1258 checkColor = checkColor == 0xffffffff ? 0xff000000 : 0xffffffff;
1259 uint32_t paintedColor = checkColor;
1260 // Draw 3 special case checks as r,g,b:
1261 if(cx == 0 && cy == 0)
1263 paintedColor = 0xff0000ff; // Red
1265 else if(cx == 7 && cy == 0)
1267 paintedColor = 0xff00ff00; // Green
1269 else if(cx == 7 && cy == 7)
1271 paintedColor = 0xffff0000; // blue
1273 uint32_t* check = &image->GetVector()[(cy * checkerSize * imageWidth) + (cx * checkerSize)];
1274 for(unsigned int py = 0; py < checkerSize; ++py)
1276 uint32_t* checkLine = check + py * imageWidth;
1277 for(unsigned int px = 0; px < checkerSize; ++px)
1279 checkLine[px] = paintedColor;
1291 * @brief Test the right pixels are generated when downsampling a checkerboard into a small image.
1293 int UtcDaliImageOperationsPointSampleCheckerboardRGBA888(void)
1295 Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = MakeCheckerboardImageRGBA8888(8, 8, 32);
1296 const unsigned int desiredWidth = 8;
1297 const unsigned int desiredHeight = 8;
1299 uint32_t outputImage[desiredWidth * desiredHeight];
1301 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)&image->GetVector()[0], 256, 256, (unsigned char*)outputImage, desiredWidth, desiredHeight);
1303 DALI_TEST_EQUALS(outputImage[0], (uint32_t)0xff0000ff, TEST_LOCATION); // < Red corner pixel
1304 DALI_TEST_EQUALS(outputImage[7], (uint32_t)0xff00ff00, TEST_LOCATION); // < Green corner pixel
1305 DALI_TEST_EQUALS(outputImage[8 * 8 - 1], (uint32_t)0xffff0000, TEST_LOCATION); // < Blue corner pixel
1307 DALI_TEST_EQUALS(outputImage[1], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1308 DALI_TEST_EQUALS(outputImage[2], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1309 DALI_TEST_EQUALS(outputImage[3], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1310 DALI_TEST_EQUALS(outputImage[4], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1311 DALI_TEST_EQUALS(outputImage[5], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1312 DALI_TEST_EQUALS(outputImage[6], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1315 DALI_TEST_EQUALS(outputImage[8 + 0], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1316 DALI_TEST_EQUALS(outputImage[8 + 1], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1317 DALI_TEST_EQUALS(outputImage[8 + 2], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1318 DALI_TEST_EQUALS(outputImage[8 + 3], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1319 DALI_TEST_EQUALS(outputImage[8 + 4], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1320 DALI_TEST_EQUALS(outputImage[8 + 5], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1321 DALI_TEST_EQUALS(outputImage[8 + 6], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1322 DALI_TEST_EQUALS(outputImage[8 + 7], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1325 DALI_TEST_EQUALS(outputImage[16 + 0], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1326 DALI_TEST_EQUALS(outputImage[16 + 1], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1327 DALI_TEST_EQUALS(outputImage[16 + 2], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1328 DALI_TEST_EQUALS(outputImage[16 + 3], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1329 DALI_TEST_EQUALS(outputImage[16 + 4], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1330 DALI_TEST_EQUALS(outputImage[16 + 5], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1331 DALI_TEST_EQUALS(outputImage[16 + 6], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1332 DALI_TEST_EQUALS(outputImage[16 + 7], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1334 // ... could do more scanlines (there are 8)
1336 // Sample a few more pixels:
1339 DALI_TEST_EQUALS(outputImage[24 + 3], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1340 DALI_TEST_EQUALS(outputImage[32 + 4], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1341 DALI_TEST_EQUALS(outputImage[40 + 5], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1342 DALI_TEST_EQUALS(outputImage[48 + 6], (uint32_t)0xffffffff, TEST_LOCATION); // < white pixel
1343 DALI_TEST_EQUALS(outputImage[24 + 4], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1344 DALI_TEST_EQUALS(outputImage[32 + 3], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1345 DALI_TEST_EQUALS(outputImage[40 + 2], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1346 DALI_TEST_EQUALS(outputImage[48 + 1], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1347 DALI_TEST_EQUALS(outputImage[56 + 0], (uint32_t)0xff000000, TEST_LOCATION); // < black pixel
1353 * @brief Test that a scaling preserves input color in destination image.
1355 int UtcDaliImageOperationsPointSampleRGBA888PixelsCorrectColor(void)
1357 const unsigned int inputWidth = 137;
1358 const unsigned int inputHeight = 571;
1359 const unsigned int desiredWidth = 59;
1360 const unsigned int desiredHeight = 257;
1362 uint32_t inputImage[inputWidth * inputHeight];
1363 MakeSingleColorImageRGBA8888(inputWidth, inputHeight, inputImage);
1365 const size_t outputBufferSize = desiredWidth * desiredHeight;
1366 std::vector<uint32_t> buffer;
1367 buffer.resize(outputBufferSize);
1368 uint32_t* outputImage = &buffer[0];
1370 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, inputWidth, inputHeight, (unsigned char*)outputImage, desiredWidth, desiredHeight);
1372 // Check that all the output pixels are the right color:
1373 const uint32_t reference = inputImage[inputWidth * inputHeight / 2];
1374 unsigned int differentColorCount = 0;
1375 for(unsigned int i = 0; i < desiredWidth * desiredHeight; ++i)
1377 if(outputImage[i] != reference)
1379 ++differentColorCount;
1383 DALI_TEST_EQUALS(0U, differentColorCount, TEST_LOCATION);
1389 * @brief Test that scaling down to a 1x1 image works.
1391 int UtcDaliImageOperationsPointSampleRGBA888ScaleToSinglePixel(void)
1393 const unsigned int desiredWidth = 1;
1394 const unsigned int desiredHeight = 1;
1396 uint32_t inputImage[1024 * 1024];
1397 MakeSingleColorImageRGBA8888(1024, 1024, inputImage);
1398 uint32_t outputImage = 0;
1400 // Try several different starting image sizes:
1403 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1404 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1407 // Single-pixel wide tall stripe:
1408 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1024, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1409 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1412 // Single-pixel tall, wide strip:
1413 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1024, 1, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1414 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1417 // Square mid-size image:
1418 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1419 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1422 // Wide mid-size image:
1423 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1424 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1427 // Tall mid-size image:
1428 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 467, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1429 DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
1432 // 0 x 0 input image (make sure output not written to):
1433 outputImage = 0xDEADBEEF;
1434 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
1435 DALI_TEST_EQUALS(outputImage, (uint32_t)0xDEADBEEF, TEST_LOCATION);
1442 * @brief Test that downsampling to 0 - area images is a NOP and does not modify the destination.
1445 int UtcDaliImageOperationsPointSampleRGBA888N(void)
1447 uint32_t inputImage[128 * 128];
1448 MakeSingleColorImageRGBA8888(128, 128, inputImage);
1449 uint32_t outputImage[128 * 128];
1450 memset(outputImage, 0xaa, 128 * 128 * sizeof(uint32_t));
1452 // Try several different starting image sizes:
1455 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, (unsigned char*)outputImage, 0, 0);
1456 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1458 // Single-pixel wide tall stripe:
1459 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 102, (unsigned char*)outputImage, 0, 33);
1460 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1462 // Single-pixel tall, wide strip:
1463 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 102, 1, (unsigned char*)outputImage, 0, 67);
1464 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1466 // Square mid-size image:
1467 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, (unsigned char*)outputImage, 21, 0);
1468 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1470 // Wide mid-size image to 0 height
1471 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, (unsigned char*)outputImage, 99, 0);
1472 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1474 // Tall mid-size image to 0 height, over width
1475 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 46, (unsigned char*)outputImage, 9999, 0);
1476 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1478 // 0 x 0 input image:
1479 Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, (unsigned char*)outputImage, 200, 99);
1480 DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
1486 * @brief Test the small int (x,y) tuple.
1488 int UtcDaliImageOperationsUint16Pair(void)
1490 Uint16Pair vec1(2, 3);
1492 DALI_TEST_EQUALS(vec1.GetWidth(), (uint16_t)2, TEST_LOCATION);
1493 DALI_TEST_EQUALS(vec1.GetX(), (uint16_t)2, TEST_LOCATION);
1495 DALI_TEST_EQUALS(vec1.GetHeight(), (uint16_t)3, TEST_LOCATION);
1496 DALI_TEST_EQUALS(vec1.GetY(), (uint16_t)3, TEST_LOCATION);
1498 Uint16Pair vec1Copy = vec1;
1500 DALI_TEST_EQUALS(vec1Copy.GetWidth(), (uint16_t)2, TEST_LOCATION);
1501 DALI_TEST_EQUALS(vec1Copy.GetX(), (uint16_t)2, TEST_LOCATION);
1503 DALI_TEST_EQUALS(vec1Copy.GetHeight(), (uint16_t)3, TEST_LOCATION);
1504 DALI_TEST_EQUALS(vec1Copy.GetY(), (uint16_t)3, TEST_LOCATION);
1506 Uint16Pair vec2(65535u, 65535u);
1508 DALI_TEST_EQUALS(vec2.GetX(), (uint16_t)65535u, TEST_LOCATION);
1509 DALI_TEST_EQUALS(vec2.GetY(), (uint16_t)65535u, TEST_LOCATION);
1515 * @brief Test the four-tap linear blending for single-byte modes.
1517 int UtcDaliImageOperationsBilinearFilter1BPP(void)
1519 // Zeros blend to zero:
1520 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 0, 0, 0, 0), TEST_LOCATION);
1521 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 0, 0, 32768, 0), TEST_LOCATION);
1522 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 0, 0, 65535, 0), TEST_LOCATION);
1523 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 0, 0, 0, 32768), TEST_LOCATION);
1524 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 0, 0, 0, 65535), TEST_LOCATION);
1526 // Ones and zeros average to 0.5:
1527 DALI_TEST_EQUALS(127u, BilinearFilter1Component(255, 0, 0, 255, 32768, 32768), TEST_LOCATION);
1528 DALI_TEST_EQUALS(127u, BilinearFilter1Component(0, 255, 0, 255, 32768, 32768), TEST_LOCATION);
1530 // Quarters ones average to 0.25:
1531 DALI_TEST_EQUALS(64u, BilinearFilter1Component(255, 0, 0, 0, 32768, 32768), TEST_LOCATION);
1532 DALI_TEST_EQUALS(64u, BilinearFilter1Component(0, 255, 0, 0, 32768, 32768), TEST_LOCATION);
1533 DALI_TEST_EQUALS(64u, BilinearFilter1Component(0, 0, 255, 0, 32768, 32768), TEST_LOCATION);
1534 DALI_TEST_EQUALS(64u, BilinearFilter1Component(0, 0, 0, 255, 32768, 32768), TEST_LOCATION);
1536 // Horizontal blends:
1537 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 255, 0, 255, 0, 32768), TEST_LOCATION);
1538 for(unsigned y = 0; y < 65536u; y += 256)
1540 // Vertical blends don't change result in this case as there is no vertical gradient in inputs:
1541 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 255, 0, 255, 0, y), TEST_LOCATION);
1543 DALI_TEST_EQUALS(5u, BilinearFilter1Component(0, 255, 0, 255, 1233, 32768), TEST_LOCATION);
1544 DALI_TEST_EQUALS(29u, BilinearFilter1Component(0, 255, 0, 255, 7539, 32768), TEST_LOCATION);
1545 DALI_TEST_EQUALS(29u, BilinearFilter1Component(0, 255, 0, 255, 7539, 32768), TEST_LOCATION);
1546 DALI_TEST_EQUALS(67u, BilinearFilter1Component(0, 255, 0, 255, 17291, 32768), TEST_LOCATION);
1547 DALI_TEST_EQUALS(123u, BilinearFilter1Component(0, 255, 0, 255, 31671, 32768), TEST_LOCATION);
1548 DALI_TEST_EQUALS(184u, BilinearFilter1Component(0, 255, 0, 255, 47231, 32768), TEST_LOCATION);
1549 DALI_TEST_EQUALS(207u, BilinearFilter1Component(0, 255, 0, 255, 53129, 32768), TEST_LOCATION);
1550 DALI_TEST_EQUALS(239u, BilinearFilter1Component(0, 255, 0, 255, 61392, 32768), TEST_LOCATION);
1551 DALI_TEST_EQUALS(255u, BilinearFilter1Component(0, 255, 0, 255, 65535, 32768), TEST_LOCATION);
1554 DALI_TEST_EQUALS(0u, BilinearFilter1Component(0, 0, 255, 255, 32768, 0), TEST_LOCATION);
1555 DALI_TEST_EQUALS(60u, BilinearFilter1Component(0, 0, 255, 255, 32768, 15379), TEST_LOCATION);
1556 DALI_TEST_EQUALS(130u, BilinearFilter1Component(0, 0, 255, 255, 32768, 33451), TEST_LOCATION);
1557 DALI_TEST_EQUALS(186u, BilinearFilter1Component(0, 0, 255, 255, 32768, 47836), TEST_LOCATION);
1558 DALI_TEST_EQUALS(244u, BilinearFilter1Component(0, 0, 255, 255, 32768, 62731), TEST_LOCATION);
1559 DALI_TEST_EQUALS(255u, BilinearFilter1Component(0, 0, 255, 255, 32768, 65535), TEST_LOCATION);