const unsigned int lastPair = EvenDown(width - 2);
- for(unsigned int pixel = 0, outPixel = 0; pixel <= lastPair; pixel += 2, ++outPixel)
- {
- // Load all the byte pixel components we need:
- const unsigned int c11 = pixels[pixel * 3];
- const unsigned int c12 = pixels[pixel * 3 + 1];
- const unsigned int c13 = pixels[pixel * 3 + 2];
- const unsigned int c21 = pixels[pixel * 3 + 3];
- const unsigned int c22 = pixels[pixel * 3 + 4];
- const unsigned int c23 = pixels[pixel * 3 + 5];
-
- // Save the averaged byte pixel components:
- pixels[outPixel * 3] = static_cast<unsigned char>(AverageComponent(c11, c21));
- pixels[outPixel * 3 + 1] = static_cast<unsigned char>(AverageComponent(c12, c22));
- pixels[outPixel * 3 + 2] = static_cast<unsigned char>(AverageComponent(c13, c23));
+ /**
+ * @code
+ * for(unsigned int pixel = 0, outPixel = 0; pixel <= lastPair; pixel += 2, ++outPixel)
+ * {
+ * // Load all the byte pixel components we need:
+ * const unsigned int c11 = pixels[pixel * 3];
+ * const unsigned int c12 = pixels[pixel * 3 + 1];
+ * const unsigned int c13 = pixels[pixel * 3 + 2];
+ * const unsigned int c21 = pixels[pixel * 3 + 3];
+ * const unsigned int c22 = pixels[pixel * 3 + 4];
+ * const unsigned int c23 = pixels[pixel * 3 + 5];
+ *
+ * // Save the averaged byte pixel components:
+ * pixels[outPixel * 3] = static_cast<unsigned char>(AverageComponent(c11, c21));
+ * pixels[outPixel * 3 + 1] = static_cast<unsigned char>(AverageComponent(c12, c22));
+ * pixels[outPixel * 3 + 2] = static_cast<unsigned char>(AverageComponent(c13, c23));
+ * }
+ * @endcode
+ */
+ //@ToDo : Fix here if we found that collect 12 bytes == 3 uint32_t with 4 colors, and calculate in one-operation
+ std::uint8_t* inPixelPtr = pixels;
+ std::uint8_t* outPixelPtr = pixels;
+ for(std::uint32_t scanedPixelCount = 0; scanedPixelCount <= lastPair; scanedPixelCount += 2)
+ {
+ *(outPixelPtr + 0) = ((*(inPixelPtr + 0) ^ *(inPixelPtr + 3)) >> 1) + (*(inPixelPtr + 0) & *(inPixelPtr + 3));
+ *(outPixelPtr + 1) = ((*(inPixelPtr + 1) ^ *(inPixelPtr + 4)) >> 1) + (*(inPixelPtr + 1) & *(inPixelPtr + 4));
+ *(outPixelPtr + 2) = ((*(inPixelPtr + 2) ^ *(inPixelPtr + 5)) >> 1) + (*(inPixelPtr + 2) & *(inPixelPtr + 5));
+ inPixelPtr += 6;
+ outPixelPtr += 3;
}
}
for(unsigned int pixel = 0, outPixel = 0; pixel <= lastPair; pixel += 2, ++outPixel)
{
- // Load all the byte pixel components we need:
- const unsigned int c11 = pixels[pixel * 2];
- const unsigned int c12 = pixels[pixel * 2 + 1];
- const unsigned int c21 = pixels[pixel * 2 + 2];
- const unsigned int c22 = pixels[pixel * 2 + 3];
-
- // Save the averaged byte pixel components:
- pixels[outPixel * 2] = static_cast<unsigned char>(AverageComponent(c11, c21));
- pixels[outPixel * 2 + 1] = static_cast<unsigned char>(AverageComponent(c12, c22));
+ /**
+ * @code
+ * // Load all the byte pixel components we need:
+ * const unsigned int c11 = pixels[pixel * 2];
+ * const unsigned int c12 = pixels[pixel * 2 + 1];
+ * const unsigned int c21 = pixels[pixel * 2 + 2];
+ * const unsigned int c22 = pixels[pixel * 2 + 3];
+ *
+ * // Save the averaged byte pixel components:
+ * pixels[outPixel * 2] = static_cast<unsigned char>(AverageComponent(c11, c21));
+ * pixels[outPixel * 2 + 1] = static_cast<unsigned char>(AverageComponent(c12, c22));
+ * @endcode
+ */
+ // Note : We can assume that pixel is even number. So we can use | operation instead of + operation.
+ pixels[(outPixel << 1)] = ((pixels[(pixel << 1)] ^ pixels[(pixel << 1) | 2]) >> 1) + (pixels[(pixel << 1)] & pixels[(pixel << 1) | 2]);
+ pixels[(outPixel << 1) | 1] = ((pixels[(pixel << 1) | 1] ^ pixels[(pixel << 1) | 3]) >> 1) + (pixels[(pixel << 1) | 1] & pixels[(pixel << 1) | 3]);
}
}
for(unsigned int pixel = 0, outPixel = 0; pixel <= lastPair; pixel += 2, ++outPixel)
{
- // Load all the byte pixel components we need:
- const unsigned int c1 = pixels[pixel];
- const unsigned int c2 = pixels[pixel + 1];
-
- // Save the averaged byte pixel component:
- pixels[outPixel] = static_cast<unsigned char>(AverageComponent(c1, c2));
+ /**
+ * @code
+ * // Load all the byte pixel components we need:
+ * const unsigned int c1 = pixels[pixel];
+ * const unsigned int c2 = pixels[pixel + 1];
+ *
+ * // Save the averaged byte pixel component:
+ * pixels[outPixel] = static_cast<unsigned char>(AverageComponent(c1, c2));
+ * @endcode
+ */
+ // Note : We can assume that pixel is even number. So we can use | operation instead of + operation.
+ pixels[outPixel] = ((pixels[pixel] ^ pixels[pixel | 1]) >> 1) + (pixels[pixel] & pixels[pixel | 1]);
}
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
**/
inline uint32_t AveragePixelRGBA8888(uint32_t a, uint32_t b)
{
- const unsigned int avg =
- ((AverageComponent((a & 0xff000000) >> 1u, (b & 0xff000000) >> 1u) << 1u) & 0xff000000) +
- (AverageComponent(a & 0x00ff0000, b & 0x00ff0000) & 0x00ff0000) +
- (AverageComponent(a & 0x0000ff00, b & 0x0000ff00) & 0x0000ff00) +
- (AverageComponent(a & 0x000000ff, b & 0x000000ff));
- return avg;
- ///@ToDo: Optimise by trying return (((a ^ b) & 0xfefefefeUL) >> 1) + (a & b);
+ /**
+ * @code
+ * const unsigned int avg =
+ * (AverageComponent((a & 0xff000000) >> 1u, (b & 0xff000000) >> 1u) << 1u) & 0xff000000) +
+ * (AverageComponent(a & 0x00ff0000, b & 0x00ff0000) & 0x00ff0000) +
+ * (AverageComponent(a & 0x0000ff00, b & 0x0000ff00) & 0x0000ff00) +
+ * (AverageComponent(a & 0x000000ff, b & 0x000000ff);
+ * return avg;
+ * @endcode
+ */
+ return (((a ^ b) & 0xfefefefeu) >> 1) + (a & b);
///@ToDo: Optimise for ARM using the single ARMV6 instruction: UHADD8 R4, R0, R5. This is not Neon. It runs in the normal integer pipeline so there is no downside like a stall moving between integer and copro.
}
**/
inline uint32_t AveragePixelRGB565(uint32_t a, uint32_t b)
{
- const unsigned int avg =
- (AverageComponent(a & 0xf800, b & 0xf800) & 0xf800) +
- (AverageComponent(a & 0x7e0, b & 0x7e0) & 0x7e0) +
- (AverageComponent(a & 0x1f, b & 0x1f));
- return avg;
+ /**
+ * @code
+ * const unsigned int avg =
+ * (AverageComponent(a & 0xf800, b & 0xf800) & 0xf800) +
+ * (AverageComponent(a & 0x7e0, b & 0x7e0) & 0x7e0) +
+ * (AverageComponent(a & 0x1f, b & 0x1f));
+ * return avg;
+ * @endcode
+ */
+ return (((a ^ b) & 0xf7deu) >> 1) + (a & b);
}
/** @return The weighted blend of two integers as a 16.16 fixed-point number, given a 0.16 fixed-point blending factor. */
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
for(unsigned int i = 0; i < bufferSize; ++i)
{
unsigned int alpha = ReadChannel(pixel, mPixelFormat, Adaptor::ALPHA);
+ if(alpha < 255)
{
- auto red = ReadChannel(pixel, mPixelFormat, Adaptor::RED);
- auto green = ReadChannel(pixel, mPixelFormat, Adaptor::GREEN);
- auto blue = ReadChannel(pixel, mPixelFormat, Adaptor::BLUE);
- auto luminance = ReadChannel(pixel, mPixelFormat, Adaptor::LUMINANCE);
- WriteChannel(pixel, mPixelFormat, Adaptor::RED, red * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::GREEN, green * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::BLUE, blue * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::LUMINANCE, luminance * alpha / 255);
+ // If alpha is 255, we don't need to change color. Skip current pixel
+ // But if alpha is not 255, we should change color.
+ if(alpha > 0)
+ {
+ auto red = ReadChannel(pixel, mPixelFormat, Adaptor::RED);
+ auto green = ReadChannel(pixel, mPixelFormat, Adaptor::GREEN);
+ auto blue = ReadChannel(pixel, mPixelFormat, Adaptor::BLUE);
+ auto luminance = ReadChannel(pixel, mPixelFormat, Adaptor::LUMINANCE);
+ WriteChannel(pixel, mPixelFormat, Adaptor::RED, red * alpha / 255);
+ WriteChannel(pixel, mPixelFormat, Adaptor::GREEN, green * alpha / 255);
+ WriteChannel(pixel, mPixelFormat, Adaptor::BLUE, blue * alpha / 255);
+ WriteChannel(pixel, mPixelFormat, Adaptor::LUMINANCE, luminance * alpha / 255);
+ }
+ else
+ {
+ // If alpha is 0, just set all pixel as zero.
+ memset(pixel, 0, bytesPerPixel);
+ }
}
pixel += bytesPerPixel;
}