/*
- * Copyright (c) 2020 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.
#include <dali/internal/imaging/common/pixel-manipulation.h>
// INTERNAL HEADERS
-#include <dali/public-api/images/pixel.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/images/pixel.h>
namespace Dali
{
{
namespace Adaptor
{
-
namespace
{
-
-constexpr Channel ALPHA_CHANNEL_ONLY[] = {ALPHA};
-constexpr Channel LUMINANCE_CHANNEL_ONLY[] = {LUMINANCE};
-constexpr Channel LUMINANCE_ALPHA_CHANNELS[] = {LUMINANCE, ALPHA};
-constexpr Channel RGB_CHANNELS[] = {RED, GREEN, BLUE};
-constexpr Channel BGR_CHANNELS[] = {BLUE, GREEN, RED};
-constexpr Channel RGBA_CHANNELS[] = {RED, GREEN, BLUE, ALPHA};
-constexpr Channel BGRA_CHANNELS[] = {BLUE, GREEN, RED, ALPHA};
+// clang-format off
+/**
+ * @brief Pre-defined offset tables for each Channel.
+ * If invalid channel, return -1. else, return the offset bytes.
+ */
+// | LUMINANCE | RED | GREEN | BLUE | ALPHA | DEPTH | STENCIL |
+constexpr std::int8_t ALPHA_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , -1 , -1 , -1 , 0 , -1 , -1 };
+constexpr std::int8_t LUMINANCE_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { 0 , -1 , -1 , -1 , -1 , -1 , -1 };
+constexpr std::int8_t LUMINANCE_ALPHA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { 0 , -1 , -1 , -1 , 1 , -1 , -1 };
+constexpr std::int8_t RGB_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 0 , 1 , 2 , -1 , -1 , -1 };
+constexpr std::int8_t BGR_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 2 , 1 , 0 , -1 , -1 , -1 };
+constexpr std::int8_t RGBA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 0 , 1 , 2 , 3 , -1 , -1 };
+constexpr std::int8_t BGRA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 2 , 1 , 0 , 3 , -1 , -1 };
+// clang-format on
/**
* @brief Template to Read from a buffer with pixel formats that have one byte per channel.
* @tparam NumberOfChannels The number of channels to check
* @param pixelData The pixel data to retrieve the value from
* @param channel The channel we're after
- * @param channels The array of channels in the pixel format
+ * @param offsetTable The array of offset bytes for each channels in the pixel format
* @return The value of the required channel
*/
-template<size_t NumberOfChannels>
-unsigned int ReadChannel(unsigned char* pixelData, Channel channel, const Channel (&channels)[NumberOfChannels])
+unsigned int ReadChannelTable(unsigned char* pixelData, Channel channel, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
{
- auto num = 0u;
auto retVal = 0u;
- for(auto current : channels)
+ if(offsetTable[channel] >= 0)
{
- if( channel == current )
- {
- retVal = static_cast<unsigned int>(*(pixelData + num));
- break;
- }
- ++num;
+ retVal = static_cast<unsigned int>(*(pixelData + offsetTable[channel]));
}
return retVal;
}
* @param pixelData The pixel data to write the value to
* @param channel The channel we're after
* @param channelValue The value of the channel to set
- * @param channels The array of channels in the pixel format
+ * @param offsetTable The array of offset bytes for each channels in the pixel format
*/
-template<size_t NumberOfChannels>
-void WriteChannel(unsigned char* pixelData, Channel channel, unsigned int channelValue, const Channel (&channels)[NumberOfChannels])
+void WriteChannelTable(unsigned char* pixelData, Channel channel, unsigned int channelValue, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
{
- auto num = 0u;
- for( auto current : channels )
+ if(offsetTable[channel] >= 0)
{
- if( channel == current )
- {
- *(pixelData + num) = static_cast<unsigned char>( channelValue & 0xFF );
- break;
- }
- ++num;
+ *(pixelData + offsetTable[channel]) = static_cast<unsigned char>(channelValue & 0xFF);
}
}
*/
unsigned int ReadChannel565(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three)
{
- if( channel == one )
+ if(channel == one)
{
return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
}
- else if( channel == two )
+ else if(channel == two)
{
return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
- ((static_cast<unsigned int>(*(pixelData+1)) & 0xE0) >> 5);
+ ((static_cast<unsigned int>(*(pixelData + 1)) & 0xE0) >> 5);
}
- else if( channel == three )
+ else if(channel == three)
{
- return static_cast<unsigned int>(*(pixelData+1)) & 0x1F;
+ return static_cast<unsigned int>(*(pixelData + 1)) & 0x1F;
}
return 0u;
}
*/
void WriteChannel565(unsigned char* pixelData, Channel channel, unsigned int channelValue, Channel one, Channel two, Channel three)
{
- if( channel == one )
+ if(channel == one)
{
- *pixelData &= static_cast<unsigned char>( ~0xF8 );
- *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+ *pixelData &= static_cast<unsigned char>(~0xF8);
+ *pixelData |= static_cast<unsigned char>((channelValue << 3) & 0xF8);
}
- else if( channel == two )
+ else if(channel == two)
{
- *pixelData &= static_cast<unsigned char>( ~0x07 );
- *pixelData |= static_cast<unsigned char>( (channelValue >> 3) & 0x07 );
+ *pixelData &= static_cast<unsigned char>(~0x07);
+ *pixelData |= static_cast<unsigned char>((channelValue >> 3) & 0x07);
- *(pixelData+1) &= static_cast<unsigned char>( ~0xE0 );
- *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 5) & 0xE0 );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0xE0);
+ *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 5) & 0xE0);
}
- else if( channel == three )
+ else if(channel == three)
{
- *(pixelData+1) &= static_cast<unsigned char>( ~0x1F );
- *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x1F );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0x1F);
+ *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x1F);
}
}
*/
unsigned int ReadChannel4444(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three, Channel four)
{
- if( channel == one )
+ if(channel == one)
{
return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
}
- else if( channel == two )
+ else if(channel == two)
{
return (static_cast<unsigned int>(*pixelData) & 0x0F);
}
- else if( channel == three )
+ else if(channel == three)
{
- return (static_cast<unsigned int>(*(pixelData+1)) & 0xF0) >> 4;
+ return (static_cast<unsigned int>(*(pixelData + 1)) & 0xF0) >> 4;
}
- else if( channel == four )
+ else if(channel == four)
{
- return (static_cast<unsigned int>(*(pixelData+1)) & 0x0F);
+ return (static_cast<unsigned int>(*(pixelData + 1)) & 0x0F);
}
return 0u;
}
*/
void WriteChannel4444(unsigned char* pixelData, Channel channel, unsigned int channelValue, Channel one, Channel two, Channel three, Channel four)
{
- if( channel == one )
+ if(channel == one)
{
- *pixelData &= static_cast<unsigned char>( ~0xF0 );
- *pixelData |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+ *pixelData &= static_cast<unsigned char>(~0xF0);
+ *pixelData |= static_cast<unsigned char>((channelValue << 4) & 0xF0);
}
- else if( channel == two )
+ else if(channel == two)
{
- *pixelData &= static_cast<unsigned char>( ~0x0F );
- *pixelData |= static_cast<unsigned char>( channelValue & 0x0F );
+ *pixelData &= static_cast<unsigned char>(~0x0F);
+ *pixelData |= static_cast<unsigned char>(channelValue & 0x0F);
}
- else if( channel == three )
+ else if(channel == three)
{
- *(pixelData+1) &= static_cast<unsigned char>( ~0xF0 );
- *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0xF0);
+ *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 4) & 0xF0);
}
- else if( channel == four )
+ else if(channel == four)
{
- *(pixelData+1) &= static_cast<unsigned char>( ~0x0F );
- *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x0F );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0x0F);
+ *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x0F);
}
}
*/
unsigned int ReadChannel5551(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three, Channel four)
{
- if( channel == one )
+ if(channel == one)
{
return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
}
- else if( channel == two )
+ else if(channel == two)
{
return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
- ((static_cast<unsigned int>(*(pixelData+1)) & 0xC0) >> 6);
+ ((static_cast<unsigned int>(*(pixelData + 1)) & 0xC0) >> 6);
}
- else if( channel == three )
+ else if(channel == three)
{
- return (static_cast<unsigned int>(*(pixelData+1)) & 0x3E) >> 1;
+ return (static_cast<unsigned int>(*(pixelData + 1)) & 0x3E) >> 1;
}
- else if( channel == four )
+ else if(channel == four)
{
- return static_cast<unsigned int>(*(pixelData+1)) & 0x01;
+ return static_cast<unsigned int>(*(pixelData + 1)) & 0x01;
}
return 0u;
}
{
// 11111222 22333334
// F8 7 C0 3E 1
- if( channel == one )
+ if(channel == one)
{
- *pixelData &= static_cast<unsigned char>( ~0xF8 );
- *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+ *pixelData &= static_cast<unsigned char>(~0xF8);
+ *pixelData |= static_cast<unsigned char>((channelValue << 3) & 0xF8);
}
- else if( channel == two )
+ else if(channel == two)
{
- *pixelData &= static_cast<unsigned char>( ~0x07 );
- *pixelData |= static_cast<unsigned char>( (channelValue >> 2) & 0x07 );
+ *pixelData &= static_cast<unsigned char>(~0x07);
+ *pixelData |= static_cast<unsigned char>((channelValue >> 2) & 0x07);
- *(pixelData+1) &= static_cast<unsigned char>( ~0xC0 );
- *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 6) & 0xC0 );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0xC0);
+ *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 6) & 0xC0);
}
- else if( channel == three )
+ else if(channel == three)
{
- *(pixelData+1) &= static_cast<unsigned char>( ~0x3E );
- *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 1) & 0x3E );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0x3E);
+ *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 1) & 0x3E);
}
- else if( channel == four )
+ else if(channel == four)
{
- *(pixelData+1) &= static_cast<unsigned char>( ~0x01 );
- *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x01 );
+ *(pixelData + 1) &= static_cast<unsigned char>(~0x01);
+ *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x01);
}
}
{
unsigned int bitShift;
unsigned int bitMask;
- bool available;
+ bool available;
};
struct Locations
Location blue;
};
-
-bool HasChannel( Dali::Pixel::Format pixelFormat, Channel channel )
+bool HasChannel(Dali::Pixel::Format pixelFormat, Channel channel)
{
- switch (pixelFormat)
+ switch(pixelFormat)
{
case Dali::Pixel::A8:
{
}
case Dali::Pixel::LA88:
{
- return ( channel == LUMINANCE || channel == ALPHA );
+ return (channel == LUMINANCE || channel == ALPHA);
}
case Dali::Pixel::RGB565:
case Dali::Pixel::BGR565:
case Dali::Pixel::BGR8888:
case Dali::Pixel::RGB16F:
case Dali::Pixel::RGB32F:
+ case Dali::Pixel::R11G11B10F:
{
- return ( channel == RED || channel == GREEN || channel == BLUE );
+ return (channel == RED || channel == GREEN || channel == BLUE);
}
case Dali::Pixel::RGBA8888:
case Dali::Pixel::RGBA5551:
case Dali::Pixel::BGRA5551:
{
- return ( channel == RED || channel == GREEN || channel == BLUE || channel == ALPHA );
+ return (channel == RED || channel == GREEN || channel == BLUE || channel == ALPHA);
}
case Dali::Pixel::DEPTH_UNSIGNED_INT:
case Dali::Pixel::DEPTH_FLOAT:
{
- return ( channel == DEPTH );
+ return (channel == DEPTH);
}
case Dali::Pixel::DEPTH_STENCIL:
{
- return ( channel == DEPTH || channel == STENCIL );
+ return (channel == DEPTH || channel == STENCIL);
}
case Dali::Pixel::INVALID:
DALI_LOG_ERROR("Pixel formats for compressed images are not compatible with simple channels.\n");
break;
}
+
+ case Dali::Pixel::CHROMINANCE_U:
+ case Dali::Pixel::CHROMINANCE_V:
+ {
+ DALI_LOG_ERROR("Pixel formats for chrominance are not compatible with simple channels.\n");
+ break;
+ }
}
return false;
}
-unsigned int ReadChannel( unsigned char* pixelData,
- Dali::Pixel::Format pixelFormat,
- Channel channel )
+unsigned int ReadChannel(unsigned char* pixelData,
+ Dali::Pixel::Format pixelFormat,
+ Channel channel)
{
- switch (pixelFormat)
+ switch(pixelFormat)
{
case Dali::Pixel::A8:
{
- return ReadChannel(pixelData, channel, ALPHA_CHANNEL_ONLY);
+ return ReadChannelTable(pixelData, channel, ALPHA_ONLY_OFFSET_TABLE);
}
case Dali::Pixel::L8:
{
- return ReadChannel(pixelData, channel, LUMINANCE_CHANNEL_ONLY);
+ return ReadChannelTable(pixelData, channel, LUMINANCE_ONLY_OFFSET_TABLE);
}
case Dali::Pixel::LA88:
{
- return ReadChannel(pixelData, channel, LUMINANCE_ALPHA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, LUMINANCE_ALPHA_OFFSET_TABLE);
}
case Dali::Pixel::RGB565:
{
case Dali::Pixel::RGB888:
case Dali::Pixel::RGB8888:
{
- return ReadChannel(pixelData, channel, RGB_CHANNELS);
+ return ReadChannelTable(pixelData, channel, RGB_OFFSET_TABLE);
}
case Dali::Pixel::BGR8888:
{
- return ReadChannel(pixelData, channel, BGR_CHANNELS);
+ return ReadChannelTable(pixelData, channel, BGR_OFFSET_TABLE);
}
case Dali::Pixel::RGBA8888:
{
- return ReadChannel(pixelData, channel, RGBA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, RGBA_OFFSET_TABLE);
}
case Dali::Pixel::BGRA8888:
{
- return ReadChannel(pixelData, channel, BGRA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, BGRA_OFFSET_TABLE);
}
case Dali::Pixel::RGBA4444:
}
}
-void WriteChannel( unsigned char* pixelData,
- Dali::Pixel::Format pixelFormat,
- Channel channel,
- unsigned int channelValue )
+void WriteChannel(unsigned char* pixelData,
+ Dali::Pixel::Format pixelFormat,
+ Channel channel,
+ unsigned int channelValue)
{
- switch (pixelFormat)
+ switch(pixelFormat)
{
case Dali::Pixel::A8:
{
- WriteChannel(pixelData, channel, channelValue, ALPHA_CHANNEL_ONLY);
+ WriteChannelTable(pixelData, channel, channelValue, ALPHA_ONLY_OFFSET_TABLE);
break;
}
case Dali::Pixel::L8:
{
- WriteChannel(pixelData, channel, channelValue, LUMINANCE_CHANNEL_ONLY);
+ WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ONLY_OFFSET_TABLE);
break;
}
case Dali::Pixel::LA88:
{
- WriteChannel(pixelData, channel, channelValue, LUMINANCE_ALPHA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ALPHA_OFFSET_TABLE);
break;
}
case Dali::Pixel::RGB565:
case Dali::Pixel::RGB888:
case Dali::Pixel::RGB8888:
{
- WriteChannel(pixelData, channel, channelValue, RGB_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, RGB_OFFSET_TABLE);
break;
}
case Dali::Pixel::BGR8888:
{
- WriteChannel(pixelData, channel, channelValue, BGR_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, BGR_OFFSET_TABLE);
break;
}
case Dali::Pixel::RGBA8888:
{
- WriteChannel(pixelData, channel, channelValue, RGBA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, RGBA_OFFSET_TABLE);
break;
}
case Dali::Pixel::BGRA8888:
{
- WriteChannel(pixelData, channel, channelValue, BGRA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, BGRA_OFFSET_TABLE);
break;
}
}
void ConvertColorChannelsToRGBA8888(
- unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat,
- unsigned char* destPixel, int destOffset )
+ unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat, unsigned char* destPixel, int destOffset)
{
- int red = ReadChannel(srcPixel+srcOffset, srcFormat, RED );
- int green = ReadChannel(srcPixel+srcOffset, srcFormat, GREEN );
- int blue = ReadChannel(srcPixel+srcOffset, srcFormat, BLUE );
- switch( srcFormat )
+ int red = ReadChannel(srcPixel + srcOffset, srcFormat, RED);
+ int green = ReadChannel(srcPixel + srcOffset, srcFormat, GREEN);
+ int blue = ReadChannel(srcPixel + srcOffset, srcFormat, BLUE);
+ switch(srcFormat)
{
case Dali::Pixel::RGB565:
case Dali::Pixel::BGR565:
{
- red = (red<<3) | (red & 0x07);
+ red = (red << 3) | (red & 0x07);
green = (green << 2) | (green & 0x03);
- blue = (blue<<3) | (blue & 0x07);
+ blue = (blue << 3) | (blue & 0x07);
break;
}
case Dali::Pixel::RGBA4444:
case Dali::Pixel::BGRA4444:
{
- red = (red<<4) | (red&0x0F);
- green = (green<<4) | (green&0x0F);
- blue = (blue<<4) | (blue&0x0F);
+ red = (red << 4) | (red & 0x0F);
+ green = (green << 4) | (green & 0x0F);
+ blue = (blue << 4) | (blue & 0x0F);
break;
}
case Dali::Pixel::RGBA5551:
case Dali::Pixel::BGRA5551:
{
- red = (red<<3) | (red&0x07);
- green = (green<<3) | (green&0x07);
- blue = (blue<<3) | (blue&0x07);
+ red = (red << 3) | (red & 0x07);
+ green = (green << 3) | (green & 0x07);
+ blue = (blue << 3) | (blue & 0x07);
break;
}
default:
break;
}
- WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, RED, red);
- WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, GREEN, green);
- WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, BLUE, blue);
+ WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, RED, red);
+ WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, GREEN, green);
+ WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, BLUE, blue);
}
-
-int ConvertAlphaChannelToA8( unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat )
+int ConvertAlphaChannelToA8(unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat)
{
- int alpha = ReadChannel(srcPixel+srcOffset, srcFormat, ALPHA );
+ int alpha = ReadChannel(srcPixel + srcOffset, srcFormat, ALPHA);
int destAlpha = alpha;
- switch( srcFormat )
+ switch(srcFormat)
{
case Pixel::RGBA5551:
case Pixel::BGRA5551:
{
- destAlpha = (alpha==0)?0:255;
+ destAlpha = (alpha == 0) ? 0 : 255;
break;
}
case Pixel::RGBA4444:
case Pixel::BGRA4444:
{
- destAlpha = (alpha<<4) | (alpha&0x0F);
+ destAlpha = (alpha << 4) | (alpha & 0x0F);
break;
}
default:
return destAlpha;
}
-} // Adaptor
-} // Internal
-} // Dali
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali