Some cases doesn't have stride byte as multiply of BytesPerPixel().
But until now, PixelBuffer and PixelData only support Stride as pixels count
(It looks since GL_UNPACK_ROW_LENGTH is pixel scale, not a bytes.)
For example, If we have 2 width image with RGB888 format, stride byte
should be 8 byte, which is not a multiply of 3 byte.
To support those cases, let we set stride value as bytes scale.
TODO : For now, we convert from RGB to RGBA at graphics-texture side.
Couldn't we support RGB format at GL standard?
Change-Id: Ide30895239b64a9e1fdfae6c607dec512994c8b3
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
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)
{
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+
+ const uint32_t bytesPerPixel = 4u;
+
Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
reinterpret_cast<unsigned char*>(pixels),
inputWidth,
inputHeight,
- inputWidth,
+ inputWidth * bytesPerPixel,
desiredWidth,
desiredHeight,
BoxDimensionTestBoth,
DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
- DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+ DALI_TEST_EQUALS(resultingStride, expectedWidth * bytesPerPixel, location);
}
/**
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)
{
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+
+ const uint32_t bytesPerPixel = 2u;
+
Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
reinterpret_cast<unsigned char*>(pixels),
inputWidth,
inputHeight,
- inputWidth,
+ inputWidth * bytesPerPixel,
desiredWidth,
desiredHeight,
BoxDimensionTestBoth,
DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
- DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+ DALI_TEST_EQUALS(resultingStride, expectedWidth * bytesPerPixel, location);
}
/**
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)
{
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+
+ const uint32_t bytesPerPixel = 2u;
+
Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
pixels,
inputWidth,
inputHeight,
- inputWidth,
+ inputWidth * bytesPerPixel,
desiredWidth,
desiredHeight,
BoxDimensionTestBoth,
DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
- DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+ DALI_TEST_EQUALS(resultingStride, expectedWidth * bytesPerPixel, location);
}
/**
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)
{
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+
+ const uint32_t bytesPerPixel = 1u;
+
Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
pixels,
inputWidth,
inputHeight,
- inputWidth,
+ inputWidth * bytesPerPixel,
desiredWidth,
desiredHeight,
BoxDimensionTestBoth,
DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
- DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+ DALI_TEST_EQUALS(resultingStride, expectedWidth * bytesPerPixel, location);
}
} // namespace
{
unsigned outWidth = -1, outHeight = -1, outStride = -1;
+ const uint32_t bytesPerPixel = 3u;
+
// Do downscaling to 1 x 1 so we can easily assert the value of the single pixel produced:
// Scale down a black/white checkerboard to mid-grey:
- unsigned char check_4x4[16 * 3] = {
+ unsigned char check_4x4[16 * bytesPerPixel] = {
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};
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 4 * bytesPerPixel, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
- DALI_TEST_EQUALS(outStride, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outStride, 1u * bytesPerPixel, TEST_LOCATION);
DALI_TEST_EQUALS(check_4x4[0], (unsigned char)0x7f, TEST_LOCATION);
// Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
- unsigned char single_4x4[16 * 3] = {
+ unsigned char single_4x4[16 * bytesPerPixel] = {
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};
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4, 4, 4, 4 * bytesPerPixel, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
- DALI_TEST_EQUALS(outStride, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outStride, 1u * bytesPerPixel, TEST_LOCATION);
DALI_TEST_EQUALS(single_4x4[0], (unsigned char)0xf, TEST_LOCATION);
// Scale down a 16 pixel black image with a single white pixel to a 1/16th grey single pixel:
// (white pixel at bottom-right of image)
- unsigned char single_4x4_2[16 * 3] = {
+ unsigned char single_4x4_2[16 * bytesPerPixel] = {
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};
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 4, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(single_4x4_2, 4, 4, 4 * bytesPerPixel, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
- DALI_TEST_EQUALS(outStride, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outStride, 1u * bytesPerPixel, TEST_LOCATION);
DALI_TEST_EQUALS(single_4x4_2[0], (unsigned char)0xf, TEST_LOCATION);
+ // Scale down a black/white checkerboard to mid-grey:
+ unsigned char check_2x4_with_padding[4 * 8] = {
+ 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00};
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_2x4_with_padding, 2, 4, 8, 1, 2, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outHeight, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outStride, 1u * bytesPerPixel, TEST_LOCATION);
+ for(uint32_t i = 0; i < 2 * bytesPerPixel; ++i)
+ {
+ DALI_TEST_EQUALS(check_2x4_with_padding[i], (unsigned char)0x7f, TEST_LOCATION);
+ }
+
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(check_4x4, 4, 4, 4 * bytesPerPixel, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(outStride, 1u * bytesPerPixel, TEST_LOCATION);
+ DALI_TEST_EQUALS(check_4x4[0], (unsigned char)0x7f, TEST_LOCATION);
+
// Build a larger ~600 x ~600 uniform magenta image for tests which only test output dimensions:
- unsigned char magenta_600_x_600[608 * 608 * 3];
- for(unsigned int i = 0; i < sizeof(magenta_600_x_600); i += 3)
+ unsigned char magenta_600_x_600[608 * 608 * bytesPerPixel];
+ for(unsigned int i = 0; i < sizeof(magenta_600_x_600); i += bytesPerPixel)
{
magenta_600_x_600[i] = 0xff;
magenta_600_x_600[i + 1] = 0;
}
// Scaling to 0 x 0 should stop at 1 x 1:
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352 * bytesPerPixel, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
// Scaling to 1 x 1 should hit 1 x 1:
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 608, 608, 608, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 608, 608, 608 * bytesPerPixel, 1, 1, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 1u, TEST_LOCATION);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
// Scaling to original dimensions should NOP:
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384, 384, 384, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384 * bytesPerPixel, 384, 384, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 384u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 384u, TEST_LOCATION);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
// More dimension tests:
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352, 44, 11, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352 * bytesPerPixel, 44, 11, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 44u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 44u, TEST_LOCATION);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384, 3, 48, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384 * bytesPerPixel, 3, 48, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_EQUALS(outWidth, 48u, TEST_LOCATION);
DALI_TEST_EQUALS(outHeight, 48u, TEST_LOCATION);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384, 3, 3, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 384, 384, 384 * bytesPerPixel, 3, 3, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_CHECK(outWidth == 3u && outHeight == 3u);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 320, 320, 320, 5, 5, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 320, 320, 320 * bytesPerPixel, 5, 5, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_CHECK(outWidth == 5u && outHeight == 5u);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 448, 448, 448, 7, 7, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 448, 448, 448 * bytesPerPixel, 7, 7, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_CHECK(outWidth == 7u && outHeight == 7u);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
- Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352, 11, 11, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB888(magenta_600_x_600, 352, 352, 352 * bytesPerPixel, 11, 11, BoxDimensionTestBoth, outWidth, outHeight, outStride);
DALI_TEST_CHECK(outWidth == 11u && outHeight == 11u);
- DALI_TEST_CHECK(outStride == outWidth);
+ DALI_TEST_CHECK(outStride == outWidth * bytesPerPixel);
// Check that no pixel values were modified by the repeated averaging of identical pixels in tests above:
unsigned int numNonMagenta = 0u;
- for(unsigned i = 0; i < sizeof(magenta_600_x_600); i += 3)
+ for(unsigned i = 0; i < sizeof(magenta_600_x_600); i += bytesPerPixel)
{
numNonMagenta += magenta_600_x_600[i] == 0xff && magenta_600_x_600[i + 1] == 0x00 && magenta_600_x_600[i + 2] == 0xff ? 0 : 1;
}
unsigned char* const pixels = reinterpret_cast<unsigned char*>(image);
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+ const uint32_t bytesPerPixel = 4u;
+
// Test downscaling where the input size is an exact multiple of the desired size:
// (We expect a perfect result here)
- DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 600, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 600 * bytesPerPixel, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 75u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 75u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 512, 512, 512, 16, 16, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 512, 512, 512 * bytesPerPixel, 16, 16, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 16u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 16u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 512, 64, 512, 16, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 512, 64, 512 * bytesPerPixel, 16, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 16u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 2u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 64, 1024, 64, 4, 64, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 64, 1024, 64 * bytesPerPixel, 4, 64, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 4u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 64u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// Test downscaling where the input size is slightly off being an exact multiple of the desired size:
// (We expect a perfect match at the end because of rounding-down to an even width and height at each step)
- DownscaleInPlacePow2RGBA8888(pixels, 601, 603, 601, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 601, 603, 601 * bytesPerPixel, 75, 75, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 75u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 75u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 736 + 1, 352 + 3, 736 + 1, 23, 11, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 736 + 1, 352 + 3, (736 + 1) * bytesPerPixel, 23, 11, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 23u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 11u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 384 + 3, 896 + 1, 384 + 3, 3, 7, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 384 + 3, 896 + 1, (384 + 3) * bytesPerPixel, 3, 7, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 3u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 7u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// Test downscales with source dimensions which are under a nice power of two by one:
// The target is hit exactly due to losing spare columns or rows at each iteration:
- DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 63, 7, 3, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 63 * bytesPerPixel, 7, 3, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 3u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// 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.
- DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 63, 4, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 63, 31, 63 * bytesPerPixel, 4, 2, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 3u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// Should stop at almost twice the requested dimensions:
- DownscaleInPlacePow2RGBA8888(pixels, 15, 127, 15, 4, 32, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 15, 127, 15 * bytesPerPixel, 4, 32, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 7u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 63u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// Test downscales to 1 in one or both dimensions:
// Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
unsigned char* const pixels = reinterpret_cast<unsigned char*>(image);
unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+ const uint32_t bytesPerPixel = 4u;
+
// Test downscales to the same size:
// The point is just to be sure the downscale is a NOP in this case:
- DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 600, 600, 600, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 600, 600, 600 * bytesPerPixel, 600, 600, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 600u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 600u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 512, 128, 512, 512, 128, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 512, 128, 512 * bytesPerPixel, 512, 128, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 512u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 128u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
- DownscaleInPlacePow2RGBA8888(pixels, 17, 1001, 17, 17, 1001, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, 17, 1001, 17 * bytesPerPixel, 17, 1001, BoxDimensionTestBoth, resultingWidth, resultingHeight, resultingStride);
DALI_TEST_EQUALS(resultingWidth, 17u, TEST_LOCATION);
DALI_TEST_EQUALS(resultingHeight, 1001u, TEST_LOCATION);
- DALI_TEST_EQUALS(resultingStride, resultingWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(resultingStride, resultingWidth * bytesPerPixel, TEST_LOCATION);
// Test downscales that request a larger size (we never upscale so these are NOPs too):
// Parameters: input-x input-y, desired-x, desired-y, expected-x, expected-y
{
// Test that calling with null and zero parameters doesn't blow up:
unsigned int outWidth, outHeight, outStride;
- DownscaleInPlacePow2RGB565(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2RGB565(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
uint16_t image[608 * 608];
for(unsigned i = 0; i < sizeof(image) / sizeof(image[0]); ++i)
{
// Simple test that a null pointer does not get dereferenced in the function:
unsigned int outWidth, outHeight, outStride;
- DownscaleInPlacePow2ComponentPair(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
// Simple tests of dimensions output:
{
// Simple test that a null pointer does not get dereferenced in the function:
unsigned int outWidth, outHeight, outStride;
- DownscaleInPlacePow2SingleBytePerPixel(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
+ Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(0, 0, 0, 0, 0, 0, BoxDimensionTestBoth, outWidth, outHeight, outStride);
// Tests of output dimensions from downscaling:
uint8_t image[608 * 608];
*/
int UtcDaliImageOperationsPointSampleCheckerboardRGBA888(void)
{
- Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = MakeCheckerboardImageRGBA8888(8, 8, 32);
- const unsigned int desiredWidth = 8;
- const unsigned int desiredHeight = 8;
+ Dali::IntrusivePtr<Dali::RefCountedVector<uint32_t> > image = MakeCheckerboardImageRGBA8888(8, 8, 32);
+
+ const uint32_t desiredWidth = 8;
+ const uint32_t desiredHeight = 8;
+
+ const uint32_t bytesPerPixel = 4u;
uint32_t outputImage[desiredWidth * desiredHeight];
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)&image->GetVector()[0], 256, 256, 256, (unsigned char*)outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)&image->GetVector()[0], 256, 256, 256 * bytesPerPixel, (unsigned char*)outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage[0], (uint32_t)0xff0000ff, TEST_LOCATION); // < Red corner pixel
DALI_TEST_EQUALS(outputImage[7], (uint32_t)0xff00ff00, TEST_LOCATION); // < Green corner pixel
*/
int UtcDaliImageOperationsPointSampleRGBA888PixelsCorrectColor(void)
{
- const unsigned int inputWidth = 137;
- const unsigned int inputHeight = 571;
- const unsigned int desiredWidth = 59;
- const unsigned int desiredHeight = 257;
+ const uint32_t inputWidth = 137;
+ const uint32_t inputHeight = 571;
+ const uint32_t desiredWidth = 59;
+ const uint32_t desiredHeight = 257;
+
+ const uint32_t bytesPerPixel = 4u;
uint32_t inputImage[inputWidth * inputHeight];
MakeSingleColorImageRGBA8888(inputWidth, inputHeight, inputImage);
buffer.resize(outputBufferSize);
uint32_t* outputImage = &buffer[0];
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, inputWidth, inputHeight, inputWidth, (unsigned char*)outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, inputWidth, inputHeight, inputWidth * bytesPerPixel, (unsigned char*)outputImage, desiredWidth, desiredHeight);
// Check that all the output pixels are the right color:
const uint32_t reference = inputImage[inputWidth * inputHeight / 2];
- unsigned int differentColorCount = 0;
- for(unsigned int i = 0; i < desiredWidth * desiredHeight; ++i)
+ uint32_t differentColorCount = 0;
+ for(uint32_t i = 0u; i < desiredWidth * desiredHeight; ++i)
{
if(outputImage[i] != reference)
{
*/
int UtcDaliImageOperationsPointSampleRGBA888ScaleToSinglePixel(void)
{
- const unsigned int desiredWidth = 1;
- const unsigned int desiredHeight = 1;
+ const uint32_t desiredWidth = 1;
+ const uint32_t desiredHeight = 1;
+
+ const uint32_t bytesPerPixel = 4u;
uint32_t inputImage[1024 * 1024];
MakeSingleColorImageRGBA8888(1024, 1024, inputImage);
// Try several different starting image sizes:
// 1x1 -> 1x1:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, 1, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, 1 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// Single-pixel wide tall stripe:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1024, 1, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1024, 1 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// Single-pixel tall, wide strip:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1024, 1, 1024, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1024, 1, 1024 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// Square mid-size image:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, 103, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, 103 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// Wide mid-size image:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, 313, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, 313 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// Tall mid-size image:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 467, 53, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 467, 53 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, inputImage[0], TEST_LOCATION);
outputImage = 0;
// 0 x 0 input image (make sure output not written to):
outputImage = 0xDEADBEEF;
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, 0, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, 0 * bytesPerPixel, (unsigned char*)&outputImage, desiredWidth, desiredHeight);
DALI_TEST_EQUALS(outputImage, (uint32_t)0xDEADBEEF, TEST_LOCATION);
outputImage = 0;
uint32_t outputImage[128 * 128];
memset(outputImage, 0xaa, 128 * 128 * sizeof(uint32_t));
+ const uint32_t bytesPerPixel = 4u;
+
// Try several different starting image sizes:
// 1x1 -> 1x1:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, 1, (unsigned char*)outputImage, 0, 0);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 1, 1 * bytesPerPixel, (unsigned char*)outputImage, 0, 0);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// Single-pixel wide tall stripe:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 102, 1, (unsigned char*)outputImage, 0, 33);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 1, 102, 1 * bytesPerPixel, (unsigned char*)outputImage, 0, 33);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// Single-pixel tall, wide strip:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 102, 1, 102, (unsigned char*)outputImage, 0, 67);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 102, 1, 102 * bytesPerPixel, (unsigned char*)outputImage, 0, 67);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// Square mid-size image:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, 103, (unsigned char*)outputImage, 21, 0);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 103, 103, 103 * bytesPerPixel, (unsigned char*)outputImage, 21, 0);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// Wide mid-size image to 0 height
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, 313, (unsigned char*)outputImage, 99, 0);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 313, 79, 313 * bytesPerPixel, (unsigned char*)outputImage, 99, 0);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// Tall mid-size image to 0 height, over width
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 46, 53, (unsigned char*)outputImage, 9999, 0);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 53, 46, 53 * bytesPerPixel, (unsigned char*)outputImage, 9999, 0);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
// 0 x 0 input image:
- Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, 0, (unsigned char*)outputImage, 200, 99);
+ Dali::Internal::Platform::PointSample4BPP((const unsigned char*)inputImage, 0, 0, 0 * bytesPerPixel, (unsigned char*)outputImage, 200, 99);
DALI_TEST_EQUALS(0xaaaaaaaa, outputImage[0], TEST_LOCATION);
END_TEST;
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
DALI_TEST_CHECK(pixelData);
DALI_TEST_EQUALS(pixelData.GetWidth(), 10, TEST_LOCATION);
DALI_TEST_EQUALS(pixelData.GetHeight(), 10, TEST_LOCATION);
- DALI_TEST_EQUALS(pixelData.GetStride(), 10, TEST_LOCATION);
+ DALI_TEST_EQUALS(pixelData.GetStrideBytes(), 20, TEST_LOCATION);
DALI_TEST_EQUALS(pixelData.GetPixelFormat(), Pixel::RGB565, TEST_LOCATION);
// Try drawing it
DALI_TEST_CHECK(pixelData);
DALI_TEST_EQUALS(pixelData.GetWidth(), 10, TEST_LOCATION);
DALI_TEST_EQUALS(pixelData.GetHeight(), 10, TEST_LOCATION);
- DALI_TEST_EQUALS(pixelData.GetStride(), 10, TEST_LOCATION);
+ DALI_TEST_EQUALS(pixelData.GetStrideBytes(), 20, TEST_LOCATION);
DALI_TEST_EQUALS(pixelData.GetPixelFormat(), Pixel::RGB565, TEST_LOCATION);
// Try drawing it
FillCheckerboard(pixbuf);
DALI_TEST_EQUALS(pixbuf.GetWidth(), 10, TEST_LOCATION);
- DALI_TEST_EQUALS(pixbuf.GetStride(), 10, TEST_LOCATION);
+ DALI_TEST_EQUALS(pixbuf.GetStrideBytes(), 20, TEST_LOCATION);
END_TEST;
}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return GetImplementation(*this).GetStride();
}
+uint32_t PixelBuffer::GetStrideBytes() const
+{
+ return GetImplementation(*this).GetStrideBytes();
+}
+
Pixel::Format PixelBuffer::GetPixelFormat() const
{
return GetImplementation(*this).GetPixelFormat();
#define DALI_PIXEL_BUFFER_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @brief Gets the stride of the buffer in pixels.
*
* @SINCE_2_1.17
+ * @DEPRECATED_2_4.8 Use GetStrideBytes() instead.
* @return The stride of the buffer in pixels. 0 means the buffer is tightly packed.
*/
uint32_t GetStride() const;
+ /**
+ * @brief Gets the stride of the buffer in bytes.
+ *
+ * @SINCE_2_4.8
+ * @return The stride of the buffer in bytes. 0 means the buffer is tightly packed.
+ */
+ uint32_t GetStrideBytes() const;
+
/**
* @brief Gets the pixel format.
*
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
unsigned char* destBuffer = buffer.GetBuffer();
unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel(buffer.GetPixelFormat());
- unsigned int srcStrideBytes = mask.GetStride() * srcBytesPerPixel;
- unsigned int destStrideBytes = buffer.GetStride() * destBytesPerPixel;
+ unsigned int srcStrideBytes = mask.GetStrideBytes();
+ unsigned int destStrideBytes = buffer.GetStrideBytes();
// if image is premultiplied, the other channels of the image need to multiply by alpha.
if(buffer.IsAlphaPreMultiplied())
unsigned char* srcBuffer = mask.GetBuffer();
unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel(srcPixelFormat);
- unsigned int srcStrideBytes = mask.GetStride() * srcBytesPerPixel;
+ unsigned int srcStrideBytes = mask.GetStrideBytes();
// Set up source color offsets
Dali::Pixel::Format srcColorPixelFormat = buffer.GetPixelFormat();
unsigned int srcColorBytesPerPixel = Dali::Pixel::GetBytesPerPixel(srcColorPixelFormat);
- unsigned int srcColorStrideBytes = buffer.GetStride() * srcColorBytesPerPixel;
+ unsigned int srcColorStrideBytes = buffer.GetStrideBytes();
// Setup destination offsets
Dali::Pixel::Format destPixelFormat = Dali::Pixel::RGBA8888;
PixelBufferPtr newPixelBuffer = PixelBuffer::New(buffer.GetWidth(), buffer.GetHeight(), destPixelFormat);
unsigned char* destBuffer = newPixelBuffer->GetBuffer();
unsigned char* oldBuffer = buffer.GetBuffer();
- unsigned int destStrideBytes = newPixelBuffer->GetStride() * destBytesPerPixel;
+ unsigned int destStrideBytes = newPixelBuffer->GetStrideBytes();
bool hasAlpha = Dali::Pixel::HasAlpha(buffer.GetPixelFormat());
unsigned char* outBuffer,
const unsigned int bufferWidth,
const unsigned int bufferHeight,
- const unsigned int inBufferStride,
- const unsigned int outBufferStride,
+ const unsigned int inBufferStrideBytes,
+ const unsigned int outBufferStrideBytes,
const float blurRadius)
{
+ // Note that we always assume that input and output are RGBA8888 format.
+ // TODO : Can't we support other pixel format?
+ constexpr uint32_t inBytesPerPixel = 4u;
+ constexpr uint32_t outBytesPerPixel = 4u;
+
// Calculate the weights for gaussian blur
int radius = static_cast<int>(std::ceil(blurRadius));
int rows = radius * 2 + 1;
int columns2 = columns / 2;
for(unsigned int y = 0; y < bufferHeight; y++)
{
- unsigned int targetPixelIndex = y;
- unsigned int ioffset = y * inBufferStride;
+ unsigned int targetPixelByte = y * outBytesPerPixel;
+ unsigned int ioffset = y * inBufferStrideBytes;
for(unsigned int x = 0; x < bufferWidth; x++)
{
float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
float weight = weightMatrix[weightColumnOffset + column];
if(fabsf(weight) > Math::MACHINE_EPSILON_1)
{
- int ix = x + column;
- ix = std::max(0, std::min(ix, static_cast<int>(bufferWidth - 1)));
- unsigned int sourcePixelIndex = ioffset + ix;
- r += weight * inBuffer[sourcePixelIndex * 4];
- g += weight * inBuffer[sourcePixelIndex * 4 + 1];
- b += weight * inBuffer[sourcePixelIndex * 4 + 2];
- a += weight * inBuffer[sourcePixelIndex * 4 + 3];
+ int ix = x + column;
+ ix = std::max(0, std::min(ix, static_cast<int>(bufferWidth - 1)));
+ unsigned int sourcePixelByte = ioffset + (ix * inBytesPerPixel);
+ r += weight * inBuffer[sourcePixelByte];
+ g += weight * inBuffer[sourcePixelByte + 1];
+ b += weight * inBuffer[sourcePixelByte + 2];
+ a += weight * inBuffer[sourcePixelByte + 3];
}
}
- outBuffer[targetPixelIndex * 4] = std::max(0, std::min(static_cast<int>(r + 0.5f), 255));
- outBuffer[targetPixelIndex * 4 + 1] = std::max(0, std::min(static_cast<int>(g + 0.5f), 255));
- outBuffer[targetPixelIndex * 4 + 2] = std::max(0, std::min(static_cast<int>(b + 0.5f), 255));
- outBuffer[targetPixelIndex * 4 + 3] = std::max(0, std::min(static_cast<int>(a + 0.5f), 255));
+ outBuffer[targetPixelByte] = std::max(0, std::min(static_cast<int>(r + 0.5f), 255));
+ outBuffer[targetPixelByte + 1] = std::max(0, std::min(static_cast<int>(g + 0.5f), 255));
+ outBuffer[targetPixelByte + 2] = std::max(0, std::min(static_cast<int>(b + 0.5f), 255));
+ outBuffer[targetPixelByte + 3] = std::max(0, std::min(static_cast<int>(a + 0.5f), 255));
- targetPixelIndex += outBufferStride;
+ targetPixelByte += outBufferStrideBytes;
}
}
void PerformGaussianBlurRGBA(PixelBuffer& buffer, const float blurRadius)
{
- unsigned int bufferWidth = buffer.GetWidth();
- unsigned int bufferHeight = buffer.GetHeight();
- unsigned int bufferStride = buffer.GetStride();
+ unsigned int bufferWidth = buffer.GetWidth();
+ unsigned int bufferHeight = buffer.GetHeight();
+ unsigned int bufferStrideBytes = buffer.GetStrideBytes();
- if(bufferWidth == 0 || bufferHeight == 0 || bufferStride == 0 || buffer.GetPixelFormat() != Pixel::RGBA8888)
+ if(bufferWidth == 0 || bufferHeight == 0 || bufferStrideBytes == 0 || buffer.GetPixelFormat() != Pixel::RGBA8888)
{
DALI_LOG_ERROR("Invalid buffer!\n");
return;
}
// Create a temporary buffer for the two-pass blur
- PixelBufferPtr softShadowImageBuffer = PixelBuffer::New(bufferWidth, bufferHeight, Pixel::RGBA8888);
+ PixelBufferPtr softShadowImageBuffer = PixelBuffer::New(bufferHeight, bufferWidth, Pixel::RGBA8888);
// We perform the blur first but write its output image buffer transposed, so that we
// can just do it in two passes. The first pass blurs horizontally and transposes, the
// second pass does the same, but as the image is now transposed, it's really doing a
// vertical blur. The second transposition makes the image the right way up again. This
// is much faster than doing a 2D convolution.
- ConvoluteAndTranspose(buffer.GetBuffer(), softShadowImageBuffer->GetBuffer(), bufferWidth, bufferHeight, bufferStride, bufferHeight, blurRadius);
- ConvoluteAndTranspose(softShadowImageBuffer->GetBuffer(), buffer.GetBuffer(), bufferHeight, bufferWidth, bufferHeight, bufferStride, blurRadius);
+ ConvoluteAndTranspose(buffer.GetBuffer(), softShadowImageBuffer->GetBuffer(), bufferWidth, bufferHeight, bufferStrideBytes, bufferHeight * 4u, blurRadius);
+ ConvoluteAndTranspose(softShadowImageBuffer->GetBuffer(), buffer.GetBuffer(), bufferHeight, bufferWidth, bufferHeight * 4u, bufferStrideBytes, blurRadius);
// On leaving scope, softShadowImageBuffer will get destroyed.
}
* @param[in] pixelsIn The input buffer.
* @param[in] widthIn The width of the input buffer.
* @param[in] heightIn The height of the input buffer.
- * @param[in] strideIn The stride of the input buffer.
+ * @param[in] strideBytesIn The stride bytes of the input buffer.
* @param[in] pixelSize The size of the pixel.
* @param[out] pixelsOut The rotated output buffer.
* @param[out] widthOut The width of the output buffer.
bool Rotate90(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
uint8_t*& pixelsOut,
uint32_t& widthOut,
// Rotate the buffer.
for(uint32_t y = 0u; y < heightIn; ++y)
{
- const uint32_t srcLineIndex = y * strideIn;
+ const uint32_t srcLineBytes = y * strideBytesIn;
const uint32_t dstX = y;
for(uint32_t x = 0u; x < widthIn; ++x)
{
const uint32_t dstY = heightOut - x - 1u;
const uint32_t dstIndex = pixelSize * (dstY * widthOut + dstX);
- const uint32_t srcIndex = pixelSize * (srcLineIndex + x);
+ const uint32_t srcIndex = srcLineBytes + (pixelSize * x);
for(uint32_t channel = 0u; channel < pixelSize; ++channel)
{
* @param[in] pixelsIn The input buffer.
* @param[in] widthIn The width of the input buffer.
* @param[in] heightIn The height of the input buffer.
- * @param[in] strideIn The stride of the input buffer.
+ * @param[in] strideBytesIn The stride bytes of the input buffer.
* @param[in] pixelSize The size of the pixel.
* @param[out] pixelsOut The rotated output buffer.
*
bool Rotate180(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
uint8_t*& pixelsOut)
{
// Rotate the buffer.
for(uint32_t y = 0u; y < heightIn; ++y)
{
- const uint32_t srcLineIndex = y * strideIn;
+ const uint32_t srcLineBytes = y * strideBytesIn;
const uint32_t dstY = heightIn - y - 1u;
for(uint32_t x = 0u; x < widthIn; ++x)
{
const uint32_t dstX = widthIn - x - 1u;
const uint32_t dstIndex = pixelSize * (dstY * widthIn + dstX);
- const uint32_t srcIndex = pixelSize * (srcLineIndex + x);
+ const uint32_t srcIndex = srcLineBytes + (pixelSize * x);
for(uint32_t channel = 0u; channel < pixelSize; ++channel)
{
* @param[in] pixelsIn The input buffer.
* @param[in] widthIn The width of the input buffer.
* @param[in] heightIn The height of the input buffer.
- * @param[in] strideIn The stride of the input buffer.
+ * @param[in] strideBytesIn The stride bytes of the input buffer.
* @param[in] pixelSize The size of the pixel.
* @param[out] pixelsOut The rotated output buffer.
* @param[out] widthOut The width of the output buffer.
bool Rotate270(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
uint8_t*& pixelsOut,
uint32_t& widthOut,
// Rotate the buffer.
for(uint32_t y = 0u; y < heightIn; ++y)
{
- const uint32_t srcLineIndex = y * strideIn;
+ const uint32_t srcLineBytes = y * strideBytesIn;
const uint32_t dstX = widthOut - y - 1u;
for(uint32_t x = 0u; x < widthIn; ++x)
{
const uint32_t dstY = x;
const uint32_t dstIndex = pixelSize * (dstY * widthOut + dstX);
- const uint32_t srcIndex = pixelSize * (srcLineIndex + x);
+ const uint32_t srcIndex = srcLineBytes + (pixelSize * x);
for(uint32_t channel = 0u; channel < pixelSize; ++channel)
{
*
* @param[in] srcBufferPtr Pointer to the input pixel buffer.
* @param[in] srcWidth The width of the input pixel buffer.
- * @param[in] srcStride The stride of the input pixel buffer.
+ * @param[in] srcStrideBytes The stride bytes of the input pixel buffer.
* @param[in] pixelSize The size of the pixel.
* @param[in,out] dstPixelBuffer Pointer to the output pixel buffer.
* @param[in] dstWidth The width of the output pixel buffer.
*/
void HorizontalSkew(const uint8_t* const srcBufferPtr,
uint32_t srcWidth,
- uint32_t srcStride,
+ uint32_t srcStrideBytes,
uint32_t pixelSize,
uint8_t*& dstBufferPtr,
uint32_t dstWidth,
for(uint32_t i = 0u; i < srcWidth; ++i)
{
// Loop through row pixels
- const uint32_t srcIndex = pixelSize * (row * srcStride + i);
+ const uint32_t srcIndex = row * srcStrideBytes + (pixelSize * i);
uint8_t src[4u] = {0u, 0u, 0u, 0u};
for(uint32_t channel = 0u; channel < pixelSize; ++channel)
* @param[in] srcBufferPtr Pointer to the input pixel buffer.
* @param[in] srcWidth The width of the input pixel buffer.
* @param[in] srcHeight The height of the input pixel buffer.
- * @param[in] srcStride The stride of the input pixel buffer.
+ * @param[in] srcStrideBytes The stride bytes of the input pixel buffer.
* @param[in] pixelSize The size of the pixel.
* @param[in,out] dstPixelBuffer Pointer to the output pixel buffer.
* @param[in] dstWidth The width of the output pixel buffer.
void VerticalSkew(const uint8_t* const srcBufferPtr,
uint32_t srcWidth,
uint32_t srcHeight,
- uint32_t srcStride,
+ uint32_t srcStrideBytes,
uint32_t pixelSize,
uint8_t*& dstBufferPtr,
uint32_t dstWidth,
for(uint32_t i = 0u; i < srcHeight; ++i)
{
// Loop through column pixels
- const uint32_t srcIndex = pixelSize * (i * srcStride + column);
+ const uint32_t srcIndex = i * srcStrideBytes + (pixelSize * column);
uint8_t src[4u] = {0u, 0u, 0u, 0u};
for(uint32_t channel = 0u; channel < pixelSize; ++channel)
Dali::Devel::PixelBuffer CropAndPadForFittingMode(Dali::Devel::PixelBuffer& bitmap, ImageDimensions desiredDimensions, FittingMode::Type fittingMode)
{
- const uint32_t inputWidth = bitmap.GetWidth();
- const uint32_t inputHeight = bitmap.GetHeight();
- const uint32_t inputStride = bitmap.GetStride();
+ const uint32_t inputWidth = bitmap.GetWidth();
+ const uint32_t inputHeight = bitmap.GetHeight();
+ const uint32_t inputStrideBytes = bitmap.GetStrideBytes();
if(desiredDimensions.GetWidth() < 1u || desiredDimensions.GetHeight() < 1u)
{
// Add some pre-calculated offsets to the bitmap pointers so this is not done within a loop.
// The cropping is added to the source pointer, and the padding is added to the destination.
const auto bytesPerPixel = Pixel::GetBytesPerPixel(pixelFormat);
- const PixelBuffer* const sourcePixels = bitmap.GetBuffer() + ((((scanlinesToCrop / 2) * inputStride) + (columnsToCrop / 2)) * bytesPerPixel);
+ const PixelBuffer* const sourcePixels = bitmap.GetBuffer() + ((((scanlinesToCrop / 2) * inputStrideBytes) + (columnsToCrop / 2) * bytesPerPixel));
PixelBuffer* const targetPixels = croppedBitmap.GetBuffer();
PixelBuffer* const targetPixelsActive = targetPixels + ((((scanlinesToPad / 2) * desiredWidth) + (columnsToPad / 2)) * bytesPerPixel);
DALI_ASSERT_DEBUG(sourcePixels && targetPixels);
// Copy the image data to the new bitmap.
// Optimize to a single memcpy if the left and right edges don't need a crop or a pad.
uint32_t outputSpan(desiredWidth * bytesPerPixel);
- if(columnsToCrop == 0 && columnsToPad == 0 && inputStride == inputWidth)
+ if(columnsToCrop == 0 && columnsToPad == 0 && inputStrideBytes == inputWidth * bytesPerPixel)
{
memcpy(targetPixelsActive, sourcePixels, (desiredHeight - scanlinesToPad) * outputSpan);
}
{
// The width needs to change (due to either a crop or a pad), so we copy a scanline at a time.
// Precalculate any constants to optimize the inner loop.
- const uint32_t inputSpan(inputStride * bytesPerPixel);
+ const uint32_t inputSpan(inputStrideBytes);
const uint32_t copySpan((desiredWidth - columnsToPad) * bytesPerPixel);
const uint32_t scanlinesToCopy(desiredHeight - scanlinesToPad);
SamplingMode::Type samplingMode)
{
// Source dimensions as loaded from resources (e.g. filesystem):
- auto bitmapWidth = bitmap.GetWidth();
- auto bitmapHeight = bitmap.GetHeight();
- auto bitmapStride = bitmap.GetStride();
+ auto bitmapWidth = bitmap.GetWidth();
+ auto bitmapHeight = bitmap.GetHeight();
+ auto bitmapStrideBytes = bitmap.GetStrideBytes();
// Desired dimensions (the rectangle to fit the source image to):
auto desiredWidth = desired.GetWidth();
auto desiredHeight = desired.GetHeight();
auto pixelFormat = bitmap.GetPixelFormat();
// Do the fast power of 2 iterated box filter to get to roughly the right side if the filter mode requests that:
- uint32_t shrunkWidth = -1, shrunkHeight = -1, outStride = -1;
- DownscaleInPlacePow2(bitmap.GetBuffer(), pixelFormat, bitmapWidth, bitmapHeight, bitmapStride, desiredWidth, desiredHeight, fittingMode, samplingMode, shrunkWidth, shrunkHeight, outStride);
+ uint32_t shrunkWidth = -1, shrunkHeight = -1, outStrideBytes = -1;
+ DownscaleInPlacePow2(bitmap.GetBuffer(), pixelFormat, bitmapWidth, bitmapHeight, bitmapStrideBytes, desiredWidth, desiredHeight, fittingMode, samplingMode, shrunkWidth, shrunkHeight, outStrideBytes);
// Work out the dimensions of the downscaled bitmap, given the scaling mode and desired dimensions:
const ImageDimensions filteredDimensions = FitToScalingMode(ImageDimensions(desiredWidth, desiredHeight), ImageDimensions(shrunkWidth, shrunkHeight), fittingMode);
{
if(samplingMode == SamplingMode::LINEAR || samplingMode == SamplingMode::BOX_THEN_LINEAR)
{
- LinearSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStride, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
+ LinearSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStrideBytes, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
}
else if(samplingMode == SamplingMode::LANCZOS || samplingMode == SamplingMode::BOX_THEN_LANCZOS)
{
- LanczosSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStride, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
+ LanczosSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStrideBytes, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
}
else
{
- PointSample(bitmap.GetBuffer(), shrunkWidth, shrunkHeight, outStride, pixelFormat, outputBitmap.GetBuffer(), filteredWidth, filteredHeight);
+ PointSample(bitmap.GetBuffer(), shrunkWidth, shrunkHeight, outStrideBytes, pixelFormat, outputBitmap.GetBuffer(), filteredWidth, filteredHeight);
}
filtered = true;
}
void DownscaleInPlacePow2Generic(uint8_t* const pixels,
const uint32_t inputWidth,
const uint32_t inputHeight,
- const uint32_t inputStride,
+ const uint32_t inputStrideBytes,
const uint32_t desiredWidth,
const uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
if(pixels == 0)
{
// Scale the image until it would be smaller than desired, stopping if the
// resulting height or width would be less than 1:
- uint32_t scaledWidth = inputWidth, scaledHeight = inputHeight, stride = inputStride;
+ uint32_t scaledWidth = inputWidth, scaledHeight = inputHeight, strideBytes = inputStrideBytes;
while(ContinueScaling(dimensionTest, scaledWidth, scaledHeight, desiredWidth, desiredHeight))
{
- const uint32_t lastWidth = scaledWidth;
- const uint32_t lastStride = stride;
+ const uint32_t lastWidth = scaledWidth;
+ const uint32_t lastStrideBytes = strideBytes;
scaledWidth >>= 1u;
scaledHeight >>= 1u;
- stride = scaledWidth;
+ strideBytes = scaledWidth * BYTES_PER_PIXEL;
DALI_LOG_INFO(gImageOpsLogFilter, Dali::Integration::Log::Verbose, "Scaling to %u\t%u.\n", scaledWidth, scaledHeight);
for(uint32_t y = 0; y <= lastScanlinePair; ++y)
{
// Scale two scanlines horizontally:
- HalveScanlineInPlace(&pixels[y * 2 * lastStride * BYTES_PER_PIXEL], lastWidth);
- HalveScanlineInPlace(&pixels[(y * 2 + 1) * lastStride * BYTES_PER_PIXEL], lastWidth);
+ HalveScanlineInPlace(&pixels[y * 2 * lastStrideBytes], lastWidth);
+ HalveScanlineInPlace(&pixels[(y * 2 + 1) * lastStrideBytes], lastWidth);
// Scale vertical pairs of pixels while the last two scanlines are still warm in
// the CPU cache(s):
// images but even a 4k wide RGB888 image will use just 24kB of cache (4k pixels
// * 3 Bpp * 2 scanlines) for two scanlines on the first iteration.
AverageScanlines(
- &pixels[y * 2 * lastStride * BYTES_PER_PIXEL],
- &pixels[(y * 2 + 1) * lastStride * BYTES_PER_PIXEL],
- &pixels[y * scaledWidth * BYTES_PER_PIXEL],
+ &pixels[y * 2 * lastStrideBytes],
+ &pixels[(y * 2 + 1) * lastStrideBytes],
+ &pixels[y * strideBytes],
scaledWidth);
}
}
///@note: we could finish off with one of two mutually exclusive passes, one squashing horizontally as far as possible, and the other vertically, if we knew a following cpu point or bilinear filter would restore the desired aspect ratio.
- outWidth = scaledWidth;
- outHeight = scaledHeight;
- outStride = stride;
+ outWidth = scaledWidth;
+ outHeight = scaledHeight;
+ outStrideBytes = strideBytes;
}
} // namespace
Pixel::Format pixelFormat,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
FittingMode::Type fittingMode,
SamplingMode::Type samplingMode,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
- outWidth = inputWidth;
- outHeight = inputHeight;
- outStride = inputStride;
+ outWidth = inputWidth;
+ outHeight = inputHeight;
+ outStrideBytes = inputStrideBytes;
// Perform power of 2 iterated 4:1 box filtering if the requested filter mode requires it:
if(samplingMode == SamplingMode::BOX || samplingMode == SamplingMode::BOX_THEN_NEAREST || samplingMode == SamplingMode::BOX_THEN_LINEAR || samplingMode == SamplingMode::BOX_THEN_LANCZOS)
{
{
case Pixel::RGBA8888:
{
- Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
break;
}
case Pixel::RGB888:
{
- Internal::Platform::DownscaleInPlacePow2RGB888(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ Internal::Platform::DownscaleInPlacePow2RGB888(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
break;
}
case Pixel::RGB565:
{
- Internal::Platform::DownscaleInPlacePow2RGB565(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ Internal::Platform::DownscaleInPlacePow2RGB565(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
break;
}
case Pixel::LA88:
{
- Internal::Platform::DownscaleInPlacePow2ComponentPair(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ Internal::Platform::DownscaleInPlacePow2ComponentPair(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
break;
}
case Pixel::L8:
case Pixel::CHROMINANCE_U:
case Pixel::CHROMINANCE_V:
{
- Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
break;
}
default:
void DownscaleInPlacePow2RGB888(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
- DownscaleInPlacePow2Generic<3, HalveScanlineInPlaceRGB888, AverageScanlines3>(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ DownscaleInPlacePow2Generic<3, HalveScanlineInPlaceRGB888, AverageScanlines3>(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
}
void DownscaleInPlacePow2RGBA8888(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
DALI_ASSERT_DEBUG(((reinterpret_cast<ptrdiff_t>(pixels) & 3u) == 0u) && "Pointer should be 4-byte aligned for performance on some platforms.");
- DownscaleInPlacePow2Generic<4, HalveScanlineInPlaceRGBA8888, AverageScanlinesRGBA8888>(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ DownscaleInPlacePow2Generic<4, HalveScanlineInPlaceRGBA8888, AverageScanlinesRGBA8888>(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
}
void DownscaleInPlacePow2RGB565(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
- DownscaleInPlacePow2Generic<2, HalveScanlineInPlaceRGB565, AverageScanlinesRGB565>(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ DownscaleInPlacePow2Generic<2, HalveScanlineInPlaceRGB565, AverageScanlinesRGB565>(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
}
/**
void DownscaleInPlacePow2ComponentPair(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
- DownscaleInPlacePow2Generic<2, HalveScanlineInPlace2Bytes, AverageScanlines2>(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ DownscaleInPlacePow2Generic<2, HalveScanlineInPlace2Bytes, AverageScanlines2>(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
}
void DownscaleInPlacePow2SingleBytePerPixel(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride)
+ uint32_t& outStrideBytes)
{
- DownscaleInPlacePow2Generic<1, HalveScanlineInPlace1Byte, AverageScanlines1>(pixels, inputWidth, inputHeight, inputStride, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStride);
+ DownscaleInPlacePow2Generic<1, HalveScanlineInPlace1Byte, AverageScanlines1>(pixels, inputWidth, inputHeight, inputStrideBytes, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight, outStrideBytes);
}
// Point sampling group below
inline void PointSampleAddressablePixels(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight)
{
DALI_ASSERT_DEBUG(((desiredWidth <= inputWidth && desiredHeight <= inputHeight) ||
- outPixels >= inPixels + inputStride * inputHeight * sizeof(PIXEL) || outPixels <= inPixels - desiredWidth * desiredHeight * sizeof(PIXEL)) &&
+ outPixels >= inPixels + inputStrideBytes * inputHeight || outPixels <= inPixels - desiredWidth * desiredHeight * sizeof(PIXEL)) &&
"The input and output buffers must not overlap for an upscaling.");
DALI_ASSERT_DEBUG(reinterpret_cast<uint64_t>(inPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...).");
DALI_ASSERT_DEBUG(reinterpret_cast<uint64_t>(outPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...).");
{
return;
}
- const PIXEL* const inAligned = reinterpret_cast<const PIXEL*>(inPixels);
- PIXEL* const outAligned = reinterpret_cast<PIXEL*>(outPixels);
- const uint32_t deltaX = (inputWidth << 16u) / desiredWidth;
- const uint32_t deltaY = (inputHeight << 16u) / desiredHeight;
+ PIXEL* const outAligned = reinterpret_cast<PIXEL*>(outPixels);
+ const uint32_t deltaX = (inputWidth << 16u) / desiredWidth;
+ const uint32_t deltaY = (inputHeight << 16u) / desiredHeight;
uint32_t inY = 0;
for(uint32_t outY = 0; outY < desiredHeight; ++outY)
{
// Round fixed point y coordinate to nearest integer:
const uint32_t integerY = (inY + (1u << 15u)) >> 16u;
- const PIXEL* const inScanline = &inAligned[inputStride * integerY];
+ const PIXEL* const inAligned = reinterpret_cast<const PIXEL*>(inPixels + inputStrideBytes * integerY);
+ const PIXEL* const inScanline = &inAligned[0];
PIXEL* const outScanline = &outAligned[desiredWidth * outY];
DALI_ASSERT_DEBUG(integerY < inputHeight);
- DALI_ASSERT_DEBUG(reinterpret_cast<const uint8_t*>(inScanline) < (inPixels + inputStride * inputHeight * sizeof(PIXEL)));
+ DALI_ASSERT_DEBUG(reinterpret_cast<const uint8_t*>(inScanline) < (inPixels + inputStrideBytes * inputHeight));
DALI_ASSERT_DEBUG(reinterpret_cast<uint8_t*>(outScanline) < (outPixels + desiredWidth * desiredHeight * sizeof(PIXEL)));
uint32_t inX = 0;
void PointSample4BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight)
{
- PointSampleAddressablePixels<uint32_t>(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSampleAddressablePixels<uint32_t>(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
}
// RGB565, LA88
void PointSample2BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight)
{
- PointSampleAddressablePixels<uint16_t>(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSampleAddressablePixels<uint16_t>(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
}
// L8, A8
void PointSample1BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight)
{
- PointSampleAddressablePixels<uint8_t>(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSampleAddressablePixels<uint8_t>(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
}
/* RGB888
void PointSample3BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight)
for(uint32_t outY = 0; outY < desiredHeight; ++outY)
{
const uint32_t integerY = (inY + (1u << 15u)) >> 16u;
- const uint8_t* const inScanline = &inPixels[inputStride * integerY * BYTES_PER_PIXEL];
+ const uint8_t* const inScanline = &inPixels[inputStrideBytes * integerY];
uint8_t* const outScanline = &outPixels[desiredWidth * outY * BYTES_PER_PIXEL];
uint32_t inX = 0; //< 16.16 fixed-point input image x-coord.
void PointSample(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
Pixel::Format pixelFormat,
uint8_t* outPixels,
uint32_t desiredWidth,
{
case Pixel::RGB888:
{
- PointSample3BPP(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSample3BPP(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
break;
}
case Pixel::RGBA8888:
{
- PointSample4BPP(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSample4BPP(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
break;
}
case Pixel::RGB565:
case Pixel::LA88:
{
- PointSample2BPP(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSample2BPP(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
break;
}
case Pixel::L8:
case Pixel::CHROMINANCE_U:
case Pixel::CHROMINANCE_V:
{
- PointSample1BPP(inPixels, inputWidth, inputHeight, inputStride, outPixels, desiredWidth, desiredHeight);
+ PointSample1BPP(inPixels, inputWidth, inputHeight, inputStrideBytes, outPixels, desiredWidth, desiredHeight);
break;
}
default:
bool DEBUG_ASSERT_ALIGNMENT>
inline void LinearSampleGeneric(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
const uint32_t desiredWidth = desiredDimensions.GetWidth();
const uint32_t desiredHeight = desiredDimensions.GetHeight();
- DALI_ASSERT_DEBUG(((outPixels >= inPixels + inputStride * inputHeight * sizeof(PIXEL)) ||
+ DALI_ASSERT_DEBUG(((outPixels >= inPixels + inputStrideBytes * inputHeight) ||
(inPixels >= outPixels + desiredWidth * desiredHeight * sizeof(PIXEL))) &&
"Input and output buffers cannot overlap.");
if(DEBUG_ASSERT_ALIGNMENT)
{
return;
}
- const PIXEL* const inAligned = reinterpret_cast<const PIXEL*>(inPixels);
- PIXEL* const outAligned = reinterpret_cast<PIXEL*>(outPixels);
- const uint32_t deltaX = (inputWidth << 16u) / desiredWidth;
- const uint32_t deltaY = (inputHeight << 16u) / desiredHeight;
+ PIXEL* const outAligned = reinterpret_cast<PIXEL*>(outPixels);
+ const uint32_t deltaX = (inputWidth << 16u) / desiredWidth;
+ const uint32_t deltaY = (inputHeight << 16u) / desiredHeight;
uint32_t inY = 0;
for(uint32_t outY = 0; outY < desiredHeight; ++outY)
DALI_ASSERT_DEBUG(integerY1 < inputHeight);
DALI_ASSERT_DEBUG(integerY2 < inputHeight);
- const PIXEL* const inScanline1 = &inAligned[inputStride * integerY1];
- const PIXEL* const inScanline2 = &inAligned[inputStride * integerY2];
+ const PIXEL* const inScanline1 = reinterpret_cast<const PIXEL*>(inPixels + inputStrideBytes * integerY1);
+ const PIXEL* const inScanline2 = reinterpret_cast<const PIXEL*>(inPixels + inputStrideBytes * integerY2);
uint32_t inX = 0;
for(uint32_t outX = 0; outX < desiredWidth; ++outX)
void LinearSample1BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- LinearSampleGeneric<uint8_t, BilinearFilter1BPPByte, false>(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions);
+ LinearSampleGeneric<uint8_t, BilinearFilter1BPPByte, false>(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions);
}
void LinearSample2BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- LinearSampleGeneric<Pixel2Bytes, BilinearFilter2Bytes, true>(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions);
+ LinearSampleGeneric<Pixel2Bytes, BilinearFilter2Bytes, true>(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions);
}
void LinearSampleRGB565(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- LinearSampleGeneric<PixelRGB565, BilinearFilterRGB565, true>(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions);
+ LinearSampleGeneric<PixelRGB565, BilinearFilterRGB565, true>(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions);
}
void LinearSample3BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- LinearSampleGeneric<Pixel3Bytes, BilinearFilterRGB888, false>(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions);
+ LinearSampleGeneric<Pixel3Bytes, BilinearFilterRGB888, false>(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions);
}
void LinearSample4BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- LinearSampleGeneric<Pixel4Bytes, BilinearFilter4Bytes, true>(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions);
+ LinearSampleGeneric<Pixel4Bytes, BilinearFilter4Bytes, true>(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions);
}
// Dispatch to a format-appropriate linear sampling function:
void LinearSample(const uint8_t* __restrict__ inPixels,
ImageDimensions inDimensions,
- uint32_t inStride,
+ uint32_t inputStrideBytes,
Pixel::Format pixelFormat,
uint8_t* __restrict__ outPixels,
ImageDimensions outDimensions)
{
case Pixel::RGB888:
{
- LinearSample3BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LinearSample3BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::RGBA8888:
{
- LinearSample4BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LinearSample4BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::L8:
case Pixel::CHROMINANCE_U:
case Pixel::CHROMINANCE_V:
{
- LinearSample1BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LinearSample1BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::LA88:
{
- LinearSample2BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LinearSample2BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::RGB565:
{
- LinearSampleRGB565(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LinearSampleRGB565(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
default:
void Resample(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions,
Resampler::Filter filterType,
samples[i].ResizeUninitialized(srcWidth);
}
- const int srcPitch = inputStride * numChannels;
+ const int srcPitch = inputStrideBytes;
const int dstPitch = dstWidth * numChannels;
int dstY = 0;
void LanczosSample4BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- Resample(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions, Resampler::LANCZOS4, 4, true);
+ Resample(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions, Resampler::LANCZOS4, 4, true);
}
void LanczosSample3BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
- Resample(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions, Resampler::LANCZOS4, 3, false);
+ Resample(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions, Resampler::LANCZOS4, 3, false);
}
void LanczosSample1BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions)
{
// For L8 images
- Resample(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions, Resampler::LANCZOS4, 1, false);
+ Resample(inPixels, inputDimensions, inputStrideBytes, outPixels, desiredDimensions, Resampler::LANCZOS4, 1, false);
}
// Dispatch to a format-appropriate third-party resampling function:
void LanczosSample(const uint8_t* __restrict__ inPixels,
ImageDimensions inDimensions,
- uint32_t inStride,
+ uint32_t inputStrideBytes,
Pixel::Format pixelFormat,
uint8_t* __restrict__ outPixels,
ImageDimensions outDimensions)
{
case Pixel::RGB888:
{
- LanczosSample3BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LanczosSample3BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::RGBA8888:
case Pixel::BGRA8888:
{
- LanczosSample4BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LanczosSample4BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
case Pixel::L8:
case Pixel::A8:
{
- LanczosSample1BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+ LanczosSample1BPP(inPixels, inDimensions, inputStrideBytes, outPixels, outDimensions);
break;
}
default:
}
else
{
- LinearSample(inPixels, inDimensions, inStride, pixelFormat, outPixels, outDimensions);
+ LinearSample(inPixels, inDimensions, inputStrideBytes, pixelFormat, outPixels, outDimensions);
DALI_LOG_INFO(gImageOpsLogFilter, Dali::Integration::Log::Verbose, "Bitmap was not lanczos sampled: unsupported pixel format: %u.\n", static_cast<uint32_t>(pixelFormat));
}
}
void RotateByShear(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
float radians,
uint8_t*& pixelsOut,
fastRotationPerformed = Rotate90(pixelsIn,
widthIn,
heightIn,
- strideIn,
+ strideBytesIn,
pixelSize,
pixelsOut,
widthOut,
fastRotationPerformed = Rotate180(pixelsIn,
widthIn,
heightIn,
- strideIn,
+ strideBytesIn,
pixelSize,
pixelsOut);
fastRotationPerformed = Rotate270(pixelsIn,
widthIn,
heightIn,
- strideIn,
+ strideBytesIn,
pixelSize,
pixelsOut,
widthOut,
const uint8_t* const firstHorizontalSkewPixelsIn = fastRotationPerformed ? pixelsOut : pixelsIn;
std::unique_ptr<uint8_t, void (*)(void*)> tmpPixelsInPtr((fastRotationPerformed ? pixelsOut : nullptr), free);
- uint32_t stride = fastRotationPerformed ? widthOut : strideIn;
+ uint32_t strideBytes = fastRotationPerformed ? widthOut * pixelSize : strideBytesIn;
// Reset the input/output
widthIn = widthOut;
const float shear = angleTangent * ((angleTangent >= 0.f) ? (0.5f + static_cast<float>(y)) : (0.5f + static_cast<float>(y) - static_cast<float>(heightOut)));
const int intShear = static_cast<int>(floor(shear));
- HorizontalSkew(firstHorizontalSkewPixelsIn, widthIn, stride, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast<float>(intShear));
+ HorizontalSkew(firstHorizontalSkewPixelsIn, widthIn, strideBytes, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast<float>(intShear));
}
// Reset the 'pixel in' pointer with the output of the 'First Horizontal Skew' and free the memory allocated by the 'Fast Rotations'.
for(column = 0u; column < widthOut; ++column, offset -= angleSinus)
{
const int32_t shear = static_cast<int32_t>(floor(offset));
- VerticalSkew(tmpPixelsInPtr.get(), tmpWidthIn, tmpHeightIn, tmpWidthIn, pixelSize, pixelsOut, widthOut, heightOut, column, shear, offset - static_cast<float>(shear));
+ VerticalSkew(tmpPixelsInPtr.get(), tmpWidthIn, tmpHeightIn, tmpWidthIn * pixelSize, pixelSize, pixelsOut, widthOut, heightOut, column, shear, offset - static_cast<float>(shear));
}
// Reset the 'pixel in' pointer with the output of the 'Vertical Skew' and free the memory allocated by the 'First Horizontal Skew'.
// Reset the input/output
for(uint32_t y = 0u; y < heightOut; ++y, offset += angleTangent)
{
const int32_t shear = static_cast<int32_t>(floor(offset));
- HorizontalSkew(tmpPixelsInPtr.get(), tmpWidthIn, tmpWidthIn, pixelSize, pixelsOut, widthOut, y, shear, offset - static_cast<float>(shear));
+ HorizontalSkew(tmpPixelsInPtr.get(), tmpWidthIn, tmpWidthIn * pixelSize, pixelSize, pixelsOut, widthOut, y, shear, offset - static_cast<float>(shear));
}
// The deleter of the tmpPixelsInPtr unique pointer is called freeing the memory allocated by the 'Vertical Skew'.
void HorizontalShear(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
float radians,
uint8_t*& pixelsOut,
const float shear = radians * ((radians >= 0.f) ? (0.5f + static_cast<float>(y)) : (0.5f + static_cast<float>(y) - static_cast<float>(heightOut)));
const int32_t intShear = static_cast<int32_t>(floor(shear));
- HorizontalSkew(pixelsIn, widthIn, strideIn, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast<float>(intShear));
+ HorizontalSkew(pixelsIn, widthIn, strideBytesIn, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast<float>(intShear));
}
}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @param[in,out] pixels The buffer both to read from and write the result to.
* @param[in] inputWidth The width of the input image.
* @param[in] inputHeight The height of the input image.
- * @param[in] inputStride The stride of the input image.
+ * @param[in] inputStrideBytes The stride bytes of the input image.
* @param[in] desiredWidth The width the client is requesting.
* @param[in] desiredHeight The height the client is requesting.
* @param[out] outWidth The resulting width after downscaling.
* @param[out] outHeight The resulting height after downscaling.
- * @param[out] outStride The resulting stride after downscaling.
+ * @param[out] outStrideBytes The resulting stride bytes after downscaling.
*/
void DownscaleInPlacePow2RGB888(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride);
+ uint32_t& outStrideBytes);
/**
* @copydoc DownscaleInPlacePow2RGB888
void DownscaleInPlacePow2RGBA8888(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride);
+ uint32_t& outStrideBytes);
/**
* @copydoc DownscaleInPlacePow2RGB888
void DownscaleInPlacePow2RGB565(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride);
+ uint32_t& outStrideBytes);
/**
* @copydoc DownscaleInPlacePow2RGB888
void DownscaleInPlacePow2ComponentPair(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride);
+ uint32_t& outStrideBytes);
/**
* @copydoc DownscaleInPlacePow2RGB888
void DownscaleInPlacePow2SingleBytePerPixel(uint8_t* pixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint32_t desiredWidth,
uint32_t desiredHeight,
BoxDimensionTest dimensionTest,
uint32_t& outWidth,
uint32_t& outHeight,
- uint32_t& outStride);
+ uint32_t& outStrideBytes);
/**
* @brief Rescales an input image into the exact output dimensions passed-in.
void PointSample(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
Pixel::Format pixelFormat,
uint8_t* outPixels,
uint32_t desiredWidth,
void PointSample4BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight);
void PointSample3BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight);
void PointSample2BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight);
void PointSample1BPP(const uint8_t* inPixels,
uint32_t inputWidth,
uint32_t inputHeight,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* outPixels,
uint32_t desiredWidth,
uint32_t desiredHeight);
*/
void LinearSample(const uint8_t* __restrict__ inPixels,
ImageDimensions inDimensions,
- uint32_t inStride,
+ uint32_t inStrideBytes,
Pixel::Format pixelFormat,
uint8_t* __restrict__ outPixels,
ImageDimensions outDimensions);
*/
void LinearSample1BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*/
void LinearSample2BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*/
void LinearSampleRGB565(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*/
void LinearSample3BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*/
void LinearSample4BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*
* @param[in] inPixels Pointer to the input image buffer.
* @param[in] inputDimensions The input dimensions of the image.
- * @param[in] inputStride The input stride of the image.
+ * @param[in] inputStrideBytes The input stride bytes of the image.
* @param[in] pixelFormat The format of the image pointed at by pixels.
* @param[out] outPixels Pointer to the output image buffer.
* @param[in] desiredDimensions The output dimensions of the image.
*/
void LanczosSample(const uint8_t* __restrict__ inPixels,
ImageDimensions inDimensions,
- uint32_t inStride,
+ uint32_t inStrideBytes,
Pixel::Format pixelFormat,
uint8_t* __restrict__ outPixels,
ImageDimensions outDimensions);
*
* @param[in] inPixels Pointer to the input image buffer.
* @param[in] inputDimensions The input dimensions of the image.
- * @param[in] inputStride The input stride of the image.
+ * @param[in] inputStrideBytes The input stride bytes of the image.
* @param[out] outPixels Pointer to the output image buffer.
* @param[in] desiredDimensions The output dimensions of the image.
*/
void LanczosSample4BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*
* @param[in] inPixels Pointer to the input image buffer.
* @param[in] inputDimensions The input dimensions of the image.
- * @param[in] inputStride The input stride of the image.
+ * @param[in] inputStrideBytes The input stride bytes of the image.
* @param[out] outPixels Pointer to the output image buffer.
* @param[in] desiredDimensions The output dimensions of the image.
*/
void LanczosSample1BPP(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions);
*
* @param[in] inPixels Pointer to the input image buffer.
* @param[in] inputDimensions The input dimensions of the image.
- * @param[in] inputStride The input stride of the image.
+ * @param[in] inputStrideBytes The input stride bytes of the image.
* @param[out] outPixels Pointer to the output image buffer.
* @param[in] desiredDimensions The output dimensions of the image.
*/
void Resample(const uint8_t* __restrict__ inPixels,
ImageDimensions inputDimensions,
- uint32_t inputStride,
+ uint32_t inputStrideBytes,
uint8_t* __restrict__ outPixels,
ImageDimensions desiredDimensions,
Resampler::Filter filterType,
* @param[in] pixelsIn The input buffer.
* @param[in] widthIn The width of the input buffer.
* @param[in] heightIn The height of the input buffer.
- * @param[in] strideIn The stride of the input buffer.
+ * @param[in] strideBytesIn The stride bytes of the input buffer.
* @param[in] pixelSize The size of the pixel.
* @param[in] radians The rotation angle in radians.
* @param[out] pixelsOut The rotated output buffer.
void RotateByShear(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
float radians,
uint8_t*& pixelsOut,
* @param[in] pixelsIn The input buffer.
* @param[in] widthIn The width of the input buffer.
* @param[in] heightIn The height of the input buffer.
- * @param[in] strideIn The stride of the input buffer.
+ * @param[in] strideBytesIn The stride bytes of the input buffer.
* @param[in] pixelSize The size of the pixel.
* @param[in] radians The shear angle in radians.
* @param[out] pixelsOut The rotated output buffer.
void HorizontalShear(const uint8_t* const pixelsIn,
uint32_t widthIn,
uint32_t heightIn,
- uint32_t strideIn,
+ uint32_t strideBytesIn,
uint32_t pixelSize,
float radians,
uint8_t*& pixelsOut,
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
/// @brief Pointer to Pointer cast operator
- operator T**()
+ operator T* *()
{
return &mRawPointer;
}
pixelFormat = (i == 1 ? Pixel::CHROMINANCE_U : Pixel::CHROMINANCE_V);
}
- Internal::Adaptor::PixelBufferPtr internal = Internal::Adaptor::PixelBuffer::New(buffer, planeSize, width, height, planeWidth, pixelFormat);
+ Internal::Adaptor::PixelBufferPtr internal = Internal::Adaptor::PixelBuffer::New(buffer, planeSize, width, height, planeWidth * Pixel::GetBytesPerPixel(pixelFormat), pixelFormat);
Dali::Devel::PixelBuffer bitmap = Devel::PixelBuffer(internal.Get());
planes[i] = buffer;
pixelBuffers.push_back(bitmap);
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
uint32_t bufferSize,
uint32_t width,
uint32_t height,
- uint32_t stride,
+ uint32_t strideBytes,
Dali::Pixel::Format pixelFormat)
: mMetadata(),
mBuffer(buffer),
mBufferSize(bufferSize),
mWidth(width),
mHeight(height),
- mStride(stride ? stride : width),
+ mStrideBytes(strideBytes ? strideBytes : (width * Dali::Pixel::GetBytesPerPixel(pixelFormat))),
mPixelFormat(pixelFormat),
mPreMultiplied(false)
{
uint32_t height,
Dali::Pixel::Format pixelFormat)
{
- uint32_t bufferSize = width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat);
+ const uint32_t bufferBytesPerPixel = Dali::Pixel::GetBytesPerPixel(pixelFormat);
+
+ uint32_t bufferSize = width * height * bufferBytesPerPixel;
uint8_t* buffer = NULL;
if(bufferSize > 0)
{
}
DALI_LOG_INFO(gPixelBufferFilter, Debug::Concise, "Allocated PixelBuffer of size %u\n", bufferSize);
- return new PixelBuffer(buffer, bufferSize, width, height, width, pixelFormat);
+ return new PixelBuffer(buffer, bufferSize, width, height, width * bufferBytesPerPixel, pixelFormat);
}
PixelBufferPtr PixelBuffer::New(uint8_t* buffer,
uint32_t bufferSize,
uint32_t width,
uint32_t height,
- uint32_t stride,
+ uint32_t strideBytes,
Dali::Pixel::Format pixelFormat)
{
- return new PixelBuffer(buffer, bufferSize, width, height, stride, pixelFormat);
+ return new PixelBuffer(buffer, bufferSize, width, height, strideBytes, pixelFormat);
}
Dali::PixelData PixelBuffer::Convert(PixelBuffer& pixelBuffer, bool releaseAfterUpload)
pixelBuffer.mBufferSize,
pixelBuffer.mWidth,
pixelBuffer.mHeight,
- pixelBuffer.mStride,
+ pixelBuffer.mStrideBytes,
pixelBuffer.mPixelFormat,
Dali::PixelData::FREE);
}
pixelBuffer.mBufferSize,
pixelBuffer.mWidth,
pixelBuffer.mHeight,
- pixelBuffer.mStride,
+ pixelBuffer.mStrideBytes,
pixelBuffer.mPixelFormat,
Dali::PixelData::FREE);
}
- pixelBuffer.mBuffer = NULL;
- pixelBuffer.mWidth = 0;
- pixelBuffer.mHeight = 0;
- pixelBuffer.mBufferSize = 0;
- pixelBuffer.mStride = 0;
+ pixelBuffer.mBuffer = NULL;
+ pixelBuffer.mWidth = 0;
+ pixelBuffer.mHeight = 0;
+ pixelBuffer.mBufferSize = 0;
+ pixelBuffer.mStrideBytes = 0;
return pixelData;
}
uint32_t PixelBuffer::GetStride() const
{
- return mStride;
+ DALI_LOG_ERROR("GetStride() API deprecated! Use GetStrideBytes() instead\n");
+ const uint32_t bytesPerPixel = Dali::Pixel::GetBytesPerPixel(mPixelFormat);
+ if(DALI_UNLIKELY(bytesPerPixel == 0u))
+ {
+ return 0u;
+ }
+ return mStrideBytes / bytesPerPixel;
+}
+
+uint32_t PixelBuffer::GetStrideBytes() const
+{
+ return mStrideBytes;
}
Dali::Pixel::Format PixelBuffer::GetPixelFormat() const
memcpy(destBuffer, mBuffer, mBufferSize);
}
- Dali::PixelData pixelData = Dali::PixelData::New(destBuffer, mBufferSize, mWidth, mHeight, mStride, mPixelFormat, Dali::PixelData::FREE);
+ Dali::PixelData pixelData = Dali::PixelData::New(destBuffer, mBufferSize, mWidth, mHeight, mStrideBytes, mPixelFormat, Dali::PixelData::FREE);
return pixelData;
}
mBufferSize = pixelBuffer.mBufferSize;
mWidth = pixelBuffer.mWidth;
mHeight = pixelBuffer.mHeight;
- mStride = pixelBuffer.mStride;
+ mStrideBytes = pixelBuffer.mStrideBytes;
mPixelFormat = pixelBuffer.mPixelFormat;
mPreMultiplied = pixelBuffer.mPreMultiplied;
return true;
}
- const unsigned int pixelSize = Pixel::GetBytesPerPixel(mPixelFormat);
+ const uint32_t pixelSize = Pixel::GetBytesPerPixel(mPixelFormat);
uint8_t* pixelsOut = nullptr;
Platform::RotateByShear(mBuffer,
mWidth,
mHeight,
- mStride,
+ mStrideBytes,
pixelSize,
radians,
pixelsOut,
ReleaseBuffer();
// Set the new pixel buffer.
- mBuffer = pixelsOut;
- pixelsOut = nullptr;
- mBufferSize = mWidth * mHeight * pixelSize;
- mStride = mWidth; // The buffer is tightly packed.
+ mBuffer = pixelsOut;
+ pixelsOut = nullptr;
+ mBufferSize = mWidth * mHeight * pixelSize;
+ mStrideBytes = mWidth * pixelSize; // The buffer is tightly packed.
#if defined(DEBUG_ENABLED)
gPixelBufferAllocationTotal += mBufferSize;
PixelBufferPtr PixelBuffer::NewCrop(const PixelBuffer& inBuffer, uint16_t x, uint16_t y, ImageDimensions cropDimensions)
{
- PixelBufferPtr outBuffer = PixelBuffer::New(cropDimensions.GetWidth(), cropDimensions.GetHeight(), inBuffer.GetPixelFormat());
- int bytesPerPixel = Pixel::GetBytesPerPixel(inBuffer.mPixelFormat);
- int srcStride = inBuffer.mStride * bytesPerPixel;
- int destStride = cropDimensions.GetWidth() * bytesPerPixel; // The destination buffer is tightly packed
+ PixelBufferPtr outBuffer = PixelBuffer::New(cropDimensions.GetWidth(), cropDimensions.GetHeight(), inBuffer.GetPixelFormat());
+ int bytesPerPixel = Pixel::GetBytesPerPixel(inBuffer.mPixelFormat);
+ int srcStrideBytes = inBuffer.mStrideBytes;
+ int destStrideBytes = cropDimensions.GetWidth() * bytesPerPixel; // The destination buffer is tightly packed
// Clamp crop to right edge
if(x + cropDimensions.GetWidth() > inBuffer.mWidth)
{
- destStride = (inBuffer.mWidth - x) * bytesPerPixel;
+ destStrideBytes = (inBuffer.mWidth - x) * bytesPerPixel;
}
- int srcOffset = x * bytesPerPixel + y * srcStride;
+ int srcOffset = x * bytesPerPixel + y * srcStrideBytes;
int destOffset = 0;
uint8_t* destBuffer = outBuffer->mBuffer;
}
for(uint16_t row = y; row < endRow; ++row)
{
- memcpy(destBuffer + destOffset, inBuffer.mBuffer + srcOffset, destStride);
- srcOffset += srcStride;
- destOffset += destStride;
+ memcpy(destBuffer + destOffset, inBuffer.mBuffer + srcOffset, destStrideBytes);
+ srcOffset += srcStrideBytes;
+ destOffset += destStrideBytes;
}
return outBuffer;
}
inBuffer.mPixelFormat == Pixel::RGBA8888 ||
inBuffer.mPixelFormat == Pixel::BGRA8888)
{
- Dali::Internal::Platform::Resample(inBuffer.mBuffer, inDimensions, inBuffer.mStride, outBuffer->GetBuffer(), outDimensions, filterType, bytesPerPixel, hasAlpha);
+ Dali::Internal::Platform::Resample(inBuffer.mBuffer, inDimensions, inBuffer.mStrideBytes, outBuffer->GetBuffer(), outDimensions, filterType, bytesPerPixel, hasAlpha);
}
else
{
DALI_ASSERT_DEBUG(bytesPerPixel > 0 && "Pixel format is invalid!");
uint8_t* pixel = mBuffer;
- const uint32_t strideBytes = mStride * bytesPerPixel;
+ const uint32_t strideBytes = mStrideBytes;
const uint32_t widthBytes = mWidth * bytesPerPixel;
// Collect all valid channel list before lookup whole buffer
if(bytesPerPixel && mWidth && mHeight)
{
uint8_t* pixel = mBuffer;
- const uint32_t strideBytes = mStride * bytesPerPixel;
+ const uint32_t strideBytes = mStrideBytes;
const uint32_t widthBytes = mWidth * bytesPerPixel;
const uint32_t bufferSize = mWidth * mHeight;
#define DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
uint32_t GetStride() const;
+ /**
+ * @brief Gets the stride of the buffer in bytes.
+ * @return The stride of the buffer in bytes. 0 means the buffer is tightly packed.
+ */
+ uint32_t GetStrideBytes() const;
+
/**
* Get the pixel format
* @return The pixel format
uint32_t mBufferSize; ///< Buffer sized in bytes
uint32_t mWidth; ///< Buffer width in pixels
uint32_t mHeight; ///< Buffer height in pixels
- uint32_t mStride; ///< Buffer stride in bytes, 0 means the buffer is tightly packed
+ uint32_t mStrideBytes; ///< Buffer stride in bytes, 0 means the buffer is tightly packed
Pixel::Format mPixelFormat; ///< Pixel format
bool mPreMultiplied : 1; ///< PreMultiplied
if(frameBuffer != nullptr)
{
- Pixel::Format pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
- int32_t bufferSize = width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat);
- Internal::Adaptor::PixelBufferPtr internal = Internal::Adaptor::PixelBuffer::New(frameBuffer, bufferSize, width, height, width, pixelFormat);
- pixelBuffer = Devel::PixelBuffer(internal.Get());
+ Pixel::Format pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
+ const uint32_t bytesPerPixel = Dali::Pixel::GetBytesPerPixel(pixelFormat);
+ int32_t bufferSize = width * height * bytesPerPixel;
+
+ Internal::Adaptor::PixelBufferPtr internal = Internal::Adaptor::PixelBuffer::New(frameBuffer, bufferSize, width, height, width * bytesPerPixel, pixelFormat);
+
+ pixelBuffer = Devel::PixelBuffer(internal.Get());
}
}
}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Graphics::Texture* graphicsTexture = nullptr;
+ const Dali::Pixel::Format pixelFormat = pixelData.GetPixelFormat();
+
{
// We always need to create new one
auto createInfo = Graphics::TextureCreateInfo();
createInfo
.SetTextureType(Dali::Graphics::ConvertTextureType(Dali::TextureType::TEXTURE_2D))
.SetUsageFlags(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE))
- .SetFormat(Dali::Graphics::ConvertPixelFormat(pixelData.GetPixelFormat()))
+ .SetFormat(Dali::Graphics::ConvertPixelFormat(pixelFormat))
.SetSize({pixelData.GetWidth(), pixelData.GetHeight()})
.SetLayout(Graphics::TextureLayout::LINEAR)
.SetAllocationPolicy(Graphics::TextureAllocationPolicy::UPLOAD)
{
Graphics::TextureUpdateInfo info{};
+ const uint32_t bytesPerPixel = Dali::Pixel::GetBytesPerPixel(pixelFormat);
+
info.dstTexture = graphicsTexture;
info.dstOffset2D = {0u, 0u};
info.layer = 0u;
info.srcExtent2D = {pixelData.GetWidth(), pixelData.GetHeight()};
info.srcOffset = 0;
info.srcSize = Dali::Integration::GetPixelDataBuffer(pixelData).bufferSize;
- info.srcStride = pixelData.GetStride();
- info.srcFormat = Dali::Graphics::ConvertPixelFormat(pixelData.GetPixelFormat());
+ info.srcStride = bytesPerPixel ? (pixelData.GetStrideBytes() / bytesPerPixel) : 0u; ///< Note : Graphics stride use pixel scale!
+ info.srcFormat = Dali::Graphics::ConvertPixelFormat(pixelFormat);
Graphics::TextureUpdateSourceInfo updateSourceInfo{};
updateSourceInfo.sourceType = Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA;