-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathgamma.py
68 lines (57 loc) · 2.55 KB
/
gamma.py
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
# Lookup table generator
#
# Really it's correcting for the eye's luminance response, it's not actually gamma correction (it's misnamed!)
#
# We're generating a set of 256-entry lookup tables which you use to (separately) convert the 8-bit R, G and B components of your color
# into something you output, typically with an intelligent RGB LED such as a WS2812B; but a simple CPU-based PWM will give the same results (and benefit from this correction)
#
# We generate several sets (2,4,8...) of 256-entry tables so you can cycle through them, using a successive 8-bit lookup table each successive output frame.
# This is 'temporal dithering', which aims to give you better color resolution at the dark end of the scale.
# If you update at e.g. 100hz, try using two or three 'ditherBits' (i.e. 2^^2 or 2^^3=8 tables. The faster your update the more tables you can use
# and you get better color resolution. More than 5 ditherbits is probably excessive, even 2 will help somewhat.
#
# If you get objectionable flickering when displaying low-intensity pixels, you should either update your leds faster or reduce ditherBits
#
#
#
fout=open("gamma.h","wt")
#adjust me! Each extra bit doubles the table size
ditherBits=4
ditherMSB=1<<(ditherBits-1)
res="/* Dithered luminance correction table - autogenerated by gamma.py */\n#define DITHER_BITS %d\nconst unsigned char gammaTable[]={" % ditherBits
useRealLuminanceCalcuation=True # CIE 1931 formula
finalAdjust=0 #set this to 1 if you want your values to start at one (1..255). This is a quirky request for FastLED users only
for dither in range(1<<ditherBits):
out=[]
#reverse the low order bits so the dithering is less flickery
ditherValue=0
dread=1<<ditherBits
dout=1
for d in range(ditherBits):
dread>>=1
if dither & dread:
ditherValue|=dout
dout<<=1;
ditherValue=(ditherValue<<(8-ditherBits))
for n in range(256):
if useRealLuminanceCalcuation:
# CIE 1931
brightness=n/2.56
if brightness > 8:
pwmValue= pow( ((brightness + 16) / 116) , 3 )
else:
pwmValue = brightness / 903.3
pwmValue*=256
else:
#use simple power
pwmValue=pow(255,(n/256.0))-1
pwmValue=int(pwmValue*256)
pwmValue+=ditherValue
pwmValue=min(255, (pwmValue>>8)+finalAdjust)
out.append( pwmValue )
if dither:
res+=","
res+="\n\t"+(",".join([ "0x%x"%n for n in out]))
res+="\n\t};\n"
print >>fout,res
fout.close()