421 lines
15 KiB
C++
421 lines
15 KiB
C++
/******************************************************************************
|
|
* Copyright (c) 2018(-2023) STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This file is part of the TouchGFX 4.22.0 distribution.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file in
|
|
* the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
/**
|
|
* @file touchgfx/Color.hpp
|
|
*
|
|
* Declares the touchgfx::Color class
|
|
*/
|
|
#ifndef TOUCHGFX_COLOR_HPP
|
|
#define TOUCHGFX_COLOR_HPP
|
|
|
|
#include <touchgfx/hal/Types.hpp>
|
|
#include <touchgfx/lcd/LCD.hpp>
|
|
|
|
namespace touchgfx
|
|
{
|
|
/** Contains functionality for color conversion. */
|
|
class Color
|
|
{
|
|
public:
|
|
/**
|
|
* Generates a color representation to be used on the LCD, based on 24 bit RGB values. The
|
|
* embedded alpha value is set to 255.
|
|
*
|
|
* @param red Value of the red part (0 to 255).
|
|
* @param green Value of the green part (0 to 255).
|
|
* @param blue Value of the blue part (0 to 255).
|
|
*
|
|
* @return The color representation depending on LCD color format.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static colortype getColorFromRGB(uint8_t red, uint8_t green, uint8_t blue)
|
|
{
|
|
return 0xFF000000 | (red << 16) | (green << 8) | (blue);
|
|
}
|
|
|
|
/**
|
|
* Gets the red color part of a color.
|
|
*
|
|
* @param color The color value.
|
|
*
|
|
* @return The red part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getRed(colortype color)
|
|
{
|
|
return color >> 16;
|
|
}
|
|
|
|
/**
|
|
* Gets the green color part of a color.
|
|
*
|
|
* @param color The color value.
|
|
*
|
|
* @return The green part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getGreen(colortype color)
|
|
{
|
|
return color >> 8;
|
|
}
|
|
|
|
/**
|
|
* Gets the blue color part of a color.
|
|
*
|
|
* @param color The color value.
|
|
*
|
|
* @return The blue part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getBlue(colortype color)
|
|
{
|
|
return color;
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from HSV (Hue, Saturation, Value) to RGB (Red, Green, Blue).
|
|
*
|
|
* @param hue The input Hue (0 to 255).
|
|
* @param saturation The input Saturation (0 to 255).
|
|
* @param value The input Value (0 to 255).
|
|
* @param [out] red The output Red (0 to 255).
|
|
* @param [out] green The output Green (0 to 255).
|
|
* @param [out] blue The output Blue (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
static void getRGBFromHSV(uint8_t hue, uint8_t saturation, uint8_t value, uint8_t& red, uint8_t& green, uint8_t& blue)
|
|
{
|
|
if (saturation == 0)
|
|
{
|
|
red = green = blue = value;
|
|
return;
|
|
}
|
|
|
|
const uint8_t region = (hue * 6) >> 8;
|
|
const int next_region_start = ((((region + 1) << 8) + 5) / 6); // Can go up to 256, uint8_t not enough
|
|
const uint8_t region_size = next_region_start - (((region << 8) + 5) / 6);
|
|
const uint8_t remainder = 255 - (next_region_start - hue) * 255 / region_size;
|
|
|
|
const uint8_t p = LCD::div255(value * (255 - saturation));
|
|
const uint8_t q = LCD::div255(value * (255 - LCD::div255(saturation * remainder)));
|
|
const uint8_t t = LCD::div255(value * (255 - LCD::div255(saturation * (255 - remainder))));
|
|
|
|
switch (region)
|
|
{
|
|
case 0:
|
|
red = value;
|
|
green = t;
|
|
blue = p;
|
|
break;
|
|
case 1:
|
|
red = q;
|
|
green = value;
|
|
blue = p;
|
|
break;
|
|
case 2:
|
|
red = p;
|
|
green = value;
|
|
blue = t;
|
|
break;
|
|
case 3:
|
|
red = p;
|
|
green = q;
|
|
blue = value;
|
|
break;
|
|
case 4:
|
|
red = t;
|
|
green = p;
|
|
blue = value;
|
|
break;
|
|
default:
|
|
red = value;
|
|
green = p;
|
|
blue = q;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from RGB (Red, Green, Blue) to HSV (Hue, Saturation, Value).
|
|
*
|
|
* @param red The input Red (0 to 255).
|
|
* @param green The input Green (0 to 255).
|
|
* @param blue The input Blue (0 to 255).
|
|
* @param [out] hue The output Hue (0 to 255).
|
|
* @param [out] saturation The output Saturation (0 to 255).
|
|
* @param [out] value The output Value (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
static void getHSVFromRGB(uint8_t red, uint8_t green, uint8_t blue, uint8_t& hue, uint8_t& saturation, uint8_t& value)
|
|
{
|
|
const uint8_t rgbMin = MIN(MIN(red, green), blue);
|
|
const uint8_t rgbMax = MAX(MAX(red, green), blue);
|
|
const uint8_t rgbRange = rgbMax - rgbMin;
|
|
|
|
value = rgbMax;
|
|
if (value == 0)
|
|
{
|
|
hue = 0;
|
|
saturation = 0;
|
|
return;
|
|
}
|
|
|
|
saturation = 255 * rgbRange / value;
|
|
if (saturation == 0)
|
|
{
|
|
hue = 0;
|
|
}
|
|
else if (rgbMax == red)
|
|
{
|
|
if (green < blue)
|
|
{
|
|
hue = 0 + (42 * (green - blue) + rgbRange / 2) / rgbRange; // [0-42; 0] = [214; 0]
|
|
}
|
|
else
|
|
{
|
|
hue = 0 + (43 * (green - blue) + rgbRange / 2) / rgbRange; // [0; 0+43] = [0; 43]
|
|
}
|
|
}
|
|
else if (rgbMax == green)
|
|
{
|
|
if (blue < red)
|
|
{
|
|
hue = 86 + (43 * (blue - red) + rgbRange / 2) / rgbRange; // [86-43; 86] = [43; 86]
|
|
}
|
|
else
|
|
{
|
|
hue = 86 + (42 * (blue - red) + rgbRange / 2) / rgbRange; // [86; 86+42] = [86; 128]
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hue = 171 + (43 * (red - green) + rgbRange / 2) / rgbRange; // [171-43; 171+43] = [128; 214]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from HSV (Hue, Saturation, Value) to colortype.
|
|
*
|
|
* @param hue The input Hue (0 to 255).
|
|
* @param saturation The input Saturation (0 to 255).
|
|
* @param value The input Value (0 to 255).
|
|
*
|
|
* @return The colortype color.
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static colortype getColorFromHSV(uint8_t hue, uint8_t saturation, uint8_t value)
|
|
{
|
|
uint8_t red, green, blue;
|
|
getRGBFromHSV(hue, saturation, value, red, green, blue);
|
|
return getColorFromRGB(red, green, blue);
|
|
}
|
|
|
|
/**
|
|
* Split a given colortype color to its RGB (Red, Green, Blue) components.
|
|
*
|
|
* @param color The input color.
|
|
* @param [out] red The output Red (0 to 255).
|
|
* @param [out] green The output Green (0 to 255).
|
|
* @param [out] blue The output Blue (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getRGBFromColor(colortype color, uint8_t& red, uint8_t& green, uint8_t& blue)
|
|
{
|
|
red = getRed(color);
|
|
green = getGreen(color);
|
|
blue = getBlue(color);
|
|
}
|
|
|
|
/**
|
|
* Convert a given colortype color to HSV (Hue, Saturation, Value).
|
|
*
|
|
* @param color The input color.
|
|
* @param [out] hue The output Hue (0 to 255).
|
|
* @param [out] saturation The output Saturation (0 to 255).
|
|
* @param [out] value The output Value (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getHSVFromColor(colortype color, uint8_t& hue, uint8_t& saturation, uint8_t& value)
|
|
{
|
|
getHSVFromRGB(getRed(color), getGreen(color), getBlue(color), hue, saturation, value);
|
|
}
|
|
|
|
/**
|
|
* Convert HSL (Hue, Saturation, Luminance) to HSV (Hue, Saturation, Value).
|
|
*
|
|
* @param hsl_hue The input HSL hue (0 to 255).
|
|
* @param hsl_saturation The input HSL saturation (0 to 255).
|
|
* @param hsl_luminance The input HSL luminance (0 to 255).
|
|
* @param [out] hsv_hue The output HSV hue (0 to 255).
|
|
* @param [out] hsv_saturation The output HSV saturation (0 to 255).
|
|
* @param [out] hsv_value The output HSV value (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getHSVFromHSL(uint8_t hsl_hue, uint8_t hsl_saturation, uint8_t hsl_luminance, uint8_t& hsv_hue, uint8_t& hsv_saturation, uint8_t& hsv_value)
|
|
{
|
|
hsv_hue = hsl_hue;
|
|
hsv_value = hsl_luminance + LCD::div255(hsl_saturation * MIN(hsl_luminance, 255 - hsl_luminance));
|
|
hsv_saturation = hsv_value == 0 ? 0 : 510 - ((hsl_luminance * 510) / hsv_value);
|
|
}
|
|
|
|
/**
|
|
* Convert HSV (Hue, Saturation, Value) to HSL (Hue, Saturation, Luminance).
|
|
*
|
|
* @param hsv_hue The input HSV hue (0 to 255).
|
|
* @param hsv_saturation The input HSV saturation (0 to 255).
|
|
* @param hsv_value The input HSV value (0 to 255).
|
|
* @param [out] hsl_hue The output HSL hue (0 to 255).
|
|
* @param [out] hsl_saturation The output HSL saturation (0 to 255).
|
|
* @param [out] hsl_luminance The output HSL luminance (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getHSLFromHSV(uint8_t hsv_hue, uint8_t hsv_saturation, uint8_t hsv_value, uint8_t& hsl_hue, uint8_t& hsl_saturation, uint8_t& hsl_luminance)
|
|
{
|
|
hsl_hue = hsv_hue;
|
|
uint16_t luminance2 = (hsv_value * (510 - hsv_saturation)) / 255;
|
|
hsl_luminance = luminance2 >> 1;
|
|
hsl_saturation = (hsl_luminance == 0 || hsl_luminance == 255) ? 0 : (uint8_t)(((hsv_value * 2 - luminance2) * 255) / MIN(luminance2, 510 - luminance2));
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from HSV (Hue, Saturation, Value) to RGB (Red, Green, Blue).
|
|
*
|
|
* @param hue The input Hue (0 to 255).
|
|
* @param saturation The input Saturation (0 to 255).
|
|
* @param luminance The input Value (0 to 255).
|
|
* @param [out] red The output Red (0 to 255).
|
|
* @param [out] green The output Green (0 to 255).
|
|
* @param [out] blue The output Blue (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getRGBFromHSL(uint8_t hue, uint8_t saturation, uint8_t luminance, uint8_t& red, uint8_t& green, uint8_t& blue)
|
|
{
|
|
uint8_t hsv_hue, hsv_saturation, hsv_value;
|
|
getHSVFromHSL(hue, saturation, luminance, hsv_hue, hsv_saturation, hsv_value);
|
|
getRGBFromHSV(hsv_hue, hsv_saturation, hsv_value, red, green, blue);
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from RGB (Red, Green, Blue) to HSV (Hue, Saturation, Value).
|
|
*
|
|
* @param red The input Red (0 to 255).
|
|
* @param green The input Green (0 to 255).
|
|
* @param blue The input Blue (0 to 255).
|
|
* @param [out] hue The output Hue (0 to 255).
|
|
* @param [out] saturation The output Saturation (0 to 255).
|
|
* @param [out] luminance The output Value (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getHSLFromRGB(uint8_t red, uint8_t green, uint8_t blue, uint8_t& hue, uint8_t& saturation, uint8_t& luminance)
|
|
{
|
|
uint8_t hsv_hue, hsv_saturation, hsv_value;
|
|
getHSVFromRGB(red, green, blue, hsv_hue, hsv_saturation, hsv_value);
|
|
getHSLFromHSV(hsv_hue, hsv_saturation, hsv_value, hue, saturation, luminance);
|
|
}
|
|
|
|
/**
|
|
* Convert a given color from HSV (Hue, Saturation, Value) to colortype.
|
|
*
|
|
* @param hue The input Hue (0 to 255).
|
|
* @param saturation The input Saturation (0 to 255).
|
|
* @param luminance The input Value (0 to 255).
|
|
*
|
|
* @return The colortype color.
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static colortype getColorFromHSL(uint8_t hue, uint8_t saturation, uint8_t luminance)
|
|
{
|
|
uint8_t red, green, blue;
|
|
getRGBFromHSL(hue, saturation, luminance, red, green, blue);
|
|
return getColorFromRGB(red, green, blue);
|
|
}
|
|
|
|
/**
|
|
* Convert a given colortype color to HSV (Hue, Saturation, Value).
|
|
*
|
|
* @param color The input color.
|
|
* @param [out] hue The output Hue (0 to 255).
|
|
* @param [out] saturation The output Saturation (0 to 255).
|
|
* @param [out] luminance The output Value (0 to 255).
|
|
*
|
|
* @note The conversion is an approximation.
|
|
*/
|
|
FORCE_INLINE_FUNCTION static void getHSLFromColor(colortype color, uint8_t& hue, uint8_t& saturation, uint8_t& luminance)
|
|
{
|
|
getHSLFromRGB(getRed(color), getGreen(color), getBlue(color), hue, saturation, luminance);
|
|
}
|
|
|
|
/**
|
|
* Gets the red color part of a 16bpp color also known as
|
|
* RGB565. The red part (5 bits) is extracted and scaled to the
|
|
* full 0-255 byte range.
|
|
*
|
|
* @param color The color value in RGB565.
|
|
*
|
|
* @return The red part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getRedFromRGB565(uint16_t color)
|
|
{
|
|
const uint8_t red = (color >> 8) & 0xF8;
|
|
return red | (red >> 5);
|
|
}
|
|
|
|
/**
|
|
* Gets the green color part of a 16bpp color also known as
|
|
* RGB565. The green part (6 bits) is extracted and scaled to the
|
|
* full 0-255 byte range.
|
|
*
|
|
* @param color The color value in RGB565.
|
|
*
|
|
* @return The green part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getGreenFromRGB565(uint16_t color)
|
|
{
|
|
const uint8_t green = (color >> 3) & 0xFC;
|
|
return green | (green >> 6);
|
|
}
|
|
|
|
/**
|
|
* Gets the blue color part of a 16bpp color also known as
|
|
* RGB565. The blue part (5 bits) is extracted and scaled to the
|
|
* full 0-255 byte range.
|
|
*
|
|
* @param color The color value in RGB565.
|
|
*
|
|
* @return The blue part of the color (0 to 255).
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint8_t getBlueFromRGB565(uint16_t color)
|
|
{
|
|
const uint8_t blue = color << 3;
|
|
return blue | (blue >> 5);
|
|
}
|
|
|
|
/**
|
|
* Convert 16bit RGB565 color to 32bit ARGB8888 color by expanding the 5,6,5 colors to full 8,8,
|
|
* 8 colors. The alpha value is set to zero.
|
|
*
|
|
* @param rgb565 The 16bit RGB565 color.
|
|
*
|
|
* @return The 32bit color value.
|
|
*
|
|
* @see getRedFromRGB565, getGreenFromRGB565, getBlueFromRGB565
|
|
*/
|
|
FORCE_INLINE_FUNCTION static uint32_t rgb565toXrgb8888(uint16_t rgb565)
|
|
{
|
|
return (getRedFromRGB565(rgb565) << 16) | (getGreenFromRGB565(rgb565) << 8) | getBlueFromRGB565(rgb565);
|
|
}
|
|
};
|
|
|
|
} // namespace touchgfx
|
|
|
|
#endif // TOUCHGFX_COLOR_HPP
|