summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/ColorUtils.cpp
blob: d153bc4c67cd988e7979e11658bc880dbcb555af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "ColorUtils.h"

#include "StringUtils.h"

#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace UTILS::COLOR;

namespace
{

void GetHSLValues(ColorInfo& colorInfo)
{
  double r = (colorInfo.colorARGB & 0x00FF0000) >> 16;
  double g = (colorInfo.colorARGB & 0x0000FF00) >> 8;
  double b = (colorInfo.colorARGB & 0x000000FF);
  r /= 255;
  g /= 255;
  b /= 255;
  const double& maxVal = std::max<double>({r, g, b});
  const double& minVal = std::min<double>({r, g, b});
  double h = 0;
  double s = 0;
  double l = (minVal + maxVal) / 2;
  double d = maxVal - minVal;

  if (d == 0)
  {
    h = s = 0; // achromatic
  }
  else
  {
    s = l > 0.5 ? d / (2 - maxVal - minVal) : d / (maxVal + minVal);
    if (maxVal == r)
    {
      h = (g - b) / d + (g < b ? 6 : 0);
    }
    else if (maxVal == g)
    {
      h = (b - r) / d + 2;
    }
    else if (maxVal == b)
    {
      h = (r - g) / d + 4;
    }
    h /= 6;
  }

  colorInfo.hue = h;
  colorInfo.saturation = s;
  colorInfo.lightness = l;
}

} // unnamed namespace

Color UTILS::COLOR::ChangeOpacity(const Color argb, const float opacity)
{
  int newAlpha = static_cast<int>(std::ceil(((argb >> 24) & 0xff) * opacity));
  return (argb & 0x00FFFFFF) | (newAlpha << 24);
};

Color UTILS::COLOR::ConvertToRGBA(const Color argb)
{
  return ((argb & 0x00FF0000) << 8) | //RR______
         ((argb & 0x0000FF00) << 8) | //__GG____
         ((argb & 0x000000FF) << 8) | //____BB__
         ((argb & 0xFF000000) >> 24); //______AA
}

Color UTILS::COLOR::ConvertToARGB(const Color rgba)
{
  return ((rgba & 0x000000FF) << 24) | //AA_____
         ((rgba & 0xFF000000) >> 8) | //__RR____
         ((rgba & 0x00FF0000) >> 8) | //____GG__
         ((rgba & 0x0000FF00) >> 8); //______BB
}

Color UTILS::COLOR::ConvertToBGR(const Color argb)
{
  return (argb & 0x00FF0000) >> 16 | //____RR
         (argb & 0x0000FF00) | //__GG__
         (argb & 0x000000FF) << 16; //BB____
}

Color UTILS::COLOR::ConvertHexToColor(const std::string& hexColor)
{
  Color value = 0;
  std::sscanf(hexColor.c_str(), "%x", &value);
  return value;
}

Color UTILS::COLOR::ConvertIntToRGB(int r, int g, int b)
{
  return ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff);
}

ColorInfo UTILS::COLOR::MakeColorInfo(const Color& argb)
{
  ColorInfo colorInfo;
  colorInfo.colorARGB = argb;
  GetHSLValues(colorInfo);
  return colorInfo;
}

ColorInfo UTILS::COLOR::MakeColorInfo(const std::string& hexColor)
{
  ColorInfo colorInfo;
  colorInfo.colorARGB = ConvertHexToColor(hexColor);
  GetHSLValues(colorInfo);
  return colorInfo;
}

bool UTILS::COLOR::comparePairColorInfo(const std::pair<std::string, ColorInfo>& a,
                                        const std::pair<std::string, ColorInfo>& b)
{
  if (a.second.hue == b.second.hue)
  {
    if (a.second.saturation == b.second.saturation)
      return (a.second.lightness < b.second.lightness);
    else
      return (a.second.saturation < b.second.saturation);
  }
  else
    return (a.second.hue < b.second.hue);
}

ColorFloats UTILS::COLOR::ConvertToFloats(const Color argb)
{
  ColorFloats c;
  c.alpha = static_cast<float>((argb >> 24) & 0xFF) * (1.0f / 255.0f);
  c.red = static_cast<float>((argb >> 16) & 0xFF) * (1.0f / 255.0f);
  c.green = static_cast<float>((argb >> 8) & 0xFF) * (1.0f / 255.0f);
  c.blue = static_cast<float>(argb & 0xFF) * (1.0f / 255.0f);
  return c;
}

std::string UTILS::COLOR::ConvertoToHexRGB(const Color argb)
{
  return StringUtils::Format("{:06X}", argb & ~0xFF000000);
}