LCOV - code coverage report
Current view: top level - src/rendering - color.hh (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 26 26 100.0 %
Date: 2022-06-15 20:16:21 Functions: 3 3 100.0 %
Branches: 24 34 70.6 %

           Branch data     Line data    Source code
       1                 :            : #ifndef bqtColorHH
       2                 :            : #define bqtColorHH
       3                 :            : /** @file rendering/color.hh
       4                 :            :  * @brief Defines conversions between different color formats and parsing colors defined in strings.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <array>
       8                 :            : #include <string>
       9                 :            : #include <algorithm>
      10                 :            : 
      11                 :            : /** ParseColorName() parses the given string and returns
      12                 :            :  * a corresponding RGB color as a 24-bit integer.
      13                 :            :  *
      14                 :            :  * Recognized formats are:
      15                 :            :  *     #RGB       (each color channel is 4-bit hexadecimal number; range: 0-F)
      16                 :            :  *     #RRGGBB    (each color channel is 8-bit hexadecimal number; range: 00-FF)
      17                 :            :  *     rgb:R/G/B  (each color channel is 4-bit hexadecimal number; range: 0-F)
      18                 :            :  *     rgbi:1/1/1 (each color channel is a decimal floating point value; range: 0-1)
      19                 :            :  *     gold       (color names recognized by X11 are recognized, case sensitive)
      20                 :            :  * Anything else produces undefined results.
      21                 :            :  */
      22                 :            : unsigned ParseColorName(std::string_view s);
      23                 :            : unsigned ParseColorName(std::u32string_view s);
      24                 :            : 
      25                 :            : /** Unpack() unpacks an RGB color in a 24-bit integer
      26                 :            :  * to its constituent r,g,b components.
      27                 :            :  */
      28                 :    1055071 : inline constexpr std::array<unsigned,3> Unpack(unsigned rgb)
      29                 :            : {
      30                 :    1055066 :     return { rgb>>16, (rgb>>8)&0xFF, rgb&0xFF };
      31                 :            : }
      32                 :            : 
      33                 :            : /** Repack() is the inverse of Unpack().
      34                 :            :  *
      35                 :            :  * Packs an RGB color represented in three color channels
      36                 :            :  * into a single 24-bit integer.
      37                 :            :  */
      38                 :    1055020 : inline constexpr unsigned Repack(std::array<unsigned,3> rgb)
      39                 :            : {
      40   [ +  +  +  -  :    1055020 :     if(rgb[0] > 255 || rgb[1] > 255 || rgb[2] > 255) [[unlikely]]
                   -  + ]
      41                 :          2 :     {
      42                 :            :         // Clamp with desaturation:
      43         [ +  - ]:          2 :         float l = (rgb[0]*299u + rgb[1]*587u + rgb[2]*114u)*1e-3f, s = 1.f;
      44   [ +  -  +  + ]:          3 :         if(rgb[0] > 255) s = std::min(s, (l-255.f) / (l-rgb[0]));
      45   [ +  +  -  + ]:          2 :         if(rgb[1] > 255) s = std::min(s, (l-255.f) / (l-rgb[1]));
      46   [ +  +  -  + ]:          2 :         if(rgb[2] > 255) s = std::min(s, (l-255.f) / (l-rgb[2]));
      47         [ +  + ]:          2 :         rgb[0] = (rgb[0] - l) * s + l + 0.5f;
      48                 :          2 :         rgb[1] = (rgb[1] - l) * s + l + 0.5f;
      49                 :          2 :         rgb[2] = (rgb[2] - l) * s + l + 0.5f;
      50         [ +  + ]:          2 :         return (std::min(rgb[0],255u)<<16)
      51         [ +  + ]:          2 :              + (std::min(rgb[1],255u)<<8)
      52         [ +  + ]:          3 :              + (std::min(rgb[2],255u)<<0);
      53                 :            :     }
      54                 :    1055018 :     return (rgb[0] << 16)
      55                 :    1055018 :          + (rgb[1] << 8)
      56                 :    1055018 :          + (rgb[2] << 0);
      57                 :            : }
      58                 :            : 
      59                 :            : /** Mix() mixes two colors such
      60                 :            :  * that the resulting color is (color1*fac1 + color2*fac2) / sum.
      61                 :            :  */
      62                 :    1055017 : inline constexpr unsigned Mix(unsigned color1,unsigned color2,
      63                 :            :                               unsigned fac1,unsigned fac2,
      64                 :            :                               unsigned sum)
      65                 :            : {
      66                 :    1055017 :     auto a = Unpack(color1), b = Unpack(color2);
      67         [ +  + ]:    4220068 :     for(unsigned n=0; n<3; ++n) a[n] = (a[n]*fac1 + b[n]*fac2)/(sum);
      68                 :    1055017 :     return Repack(a);
      69                 :            : }
      70                 :            : 
      71                 :            : /** cmy2rgb() Converts CMY into RGB
      72                 :            :  */
      73                 :          7 : inline unsigned cmy2rgb(unsigned cmy)
      74                 :            : {
      75   [ -  -  -  - ]:          7 :     return ~cmy & 0xFFFFFF;
      76                 :            : }
      77                 :            : /** cmyk2rgb() Converts CMYK into RGB
      78                 :            :  */
      79                 :          7 : inline unsigned cmyk2rgb(unsigned cmyk)
      80                 :            : {
      81                 :          7 :     return Mix(0u, ~cmyk >> 8, cmyk & 255, ~cmyk & 255, 255);
      82                 :            : }
      83                 :            : 
      84                 :            : #endif

Generated by: LCOV version 1.16