Skip to content

Instantly share code, notes, and snippets.

@mrcodetastic
Forked from mathiasvr/cie1931.py
Last active March 16, 2025 00:45
Show Gist options
  • Save mrcodetastic/2474e472558f3cd69e76f1464c6d4640 to your computer and use it in GitHub Desktop.
Save mrcodetastic/2474e472558f3cd69e76f1464c6d4640 to your computer and use it in GitHub Desktop.
Convert LED brightness to PWM value based on CIE 1931 curve.
// Generate lookup table for converting between perceived LED brightness and PWM
// Adapted from: https://jared.geek.nz/2013/feb/linear-led-pwm
// See also: https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/
#include <iostream>
#include <cmath>
#include <iomanip>
constexpr int TABLE_SIZE = 256; // Number of steps (brightness)
constexpr int RESOLUTION = 1 << 8; // PWM resolution (8-bit = 256)
// CIE 1931 brightness curve function
double cie1931(double L) {
L *= 100;
if (L <= 8)
return L / 902.3;
else
return std::pow((L + 16) / 116, 3);
}
int main() {
uint16_t CIE[TABLE_SIZE];
// Compute values
for (int i = 0; i < TABLE_SIZE; ++i) {
CIE[i] = static_cast<uint16_t>(std::round(cie1931(static_cast<double>(i) / (TABLE_SIZE - 1)) * (RESOLUTION - 1)));
}
// Print the table
std::cout << "const uint16_t CIE[" << TABLE_SIZE << "] = {";
for (int i = 0; i < TABLE_SIZE; ++i) {
if (i % 16 == 0) std::cout << "\n ";
std::cout << std::setw(5) << CIE[i] << ",";
}
std::cout << "\n};\n";
return 0;
}
@mrcodetastic
Copy link
Author

constexpr int TABLE_SIZE = 256; // Number of steps (brightness)
constexpr int RESOLUTION = 1 << 8; // PWM resolution (8-bit = 256)

returns the following:

const uint16_t CIE[256] = {
        0,    0,    0,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    2,    2,
        2,    2,    2,    2,    2,    2,    2,    3,    3,    3,    3,    3,    3,    3,    3,    4,
        4,    4,    4,    4,    4,    5,    5,    5,    5,    5,    6,    6,    6,    6,    6,    7,
        7,    7,    7,    8,    8,    8,    8,    9,    9,    9,   10,   10,   10,   10,   11,   11,
       11,   12,   12,   12,   13,   13,   13,   14,   14,   15,   15,   15,   16,   16,   17,   17,
       17,   18,   18,   19,   19,   20,   20,   21,   21,   22,   22,   23,   23,   24,   24,   25,
       25,   26,   26,   27,   28,   28,   29,   29,   30,   31,   31,   32,   32,   33,   34,   34,
       35,   36,   37,   37,   38,   39,   39,   40,   41,   42,   43,   43,   44,   45,   46,   47,
       47,   48,   49,   50,   51,   52,   53,   54,   54,   55,   56,   57,   58,   59,   60,   61,
       62,   63,   64,   65,   66,   67,   68,   70,   71,   72,   73,   74,   75,   76,   77,   79,
       80,   81,   82,   83,   85,   86,   87,   88,   90,   91,   92,   94,   95,   96,   98,   99,
      100,  102,  103,  105,  106,  108,  109,  110,  112,  113,  115,  116,  118,  120,  121,  123,
      124,  126,  128,  129,  131,  132,  134,  136,  138,  139,  141,  143,  145,  146,  148,  150,
      152,  154,  155,  157,  159,  161,  163,  165,  167,  169,  171,  173,  175,  177,  179,  181,
      183,  185,  187,  189,  191,  193,  196,  198,  200,  202,  204,  207,  209,  211,  214,  216,
      218,  220,  223,  225,  228,  230,  232,  235,  237,  240,  242,  245,  247,  250,  252,  255,
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment