-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathQDSpy_gamma.py
123 lines (100 loc) · 3.49 KB
/
QDSpy_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
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
QDSpy module - gamma correction functions
Copyright (c) 2013-2024 Thomas Euler
All rights reserved.
2021-10-15 - Adapt to LINUX
"""
# ---------------------------------------------------------------------
__author__ = "code@eulerlab.de"
import numpy
import time
import platform
import QDSpy_global as glo
import QDSpy_stim as stm
import Libraries.log_helper as _log
PLATFORM_WINDOWS = platform.system == "Windows"
if PLATFORM_WINDOWS:
from ctypes import windll
from ctypes.wintypes import LPCVOID
# ---------------------------------------------------------------------
def generateLinearLUT():
'''Return a linear LUT (see setGammaLUT for details)
'''
tempLUT = []
for j in range(3):
temp = list(range(256))
temp = [float(v) / 255.0 for v in temp]
tempLUT.append(temp)
newLUT = numpy.array(tempLUT)
newLUT = (255 * newLUT).astype(numpy.uint16)
newLUT.byteswap(True)
return newLUT
# ---------------------------------------------------------------------
def generateInverseLUT():
'''.. for testing purposes
'''
tempLUT = []
for j in range(3):
temp = list(range(255, -1, -1))
temp = [float(v) / 255.0 for v in temp]
tempLUT.append(temp)
newLUT = numpy.array(tempLUT)
newLUT = (255 * newLUT).astype(numpy.uint16)
newLUT.byteswap(True)
return newLUT
# ---------------------------------------------------------------------
def setGammaLUT(_winDC, _LUT):
'''Set a look-up table (LUT) that allows to correct all presented color
values, e.g. if the presentation device is not linear.
`_LUT` has to be an uint16-type 3x256 numpy array.
'''
if not PLATFORM_WINDOWS:
return stm.StimErrC.notYetImplemented
if (len(_LUT) != 3) or (len(_LUT[0]) != 256):
return stm.StimErrC.invalidDimensions
# For some unclear reason it fails to return a valid result when called
# for the first time ...
for j in range(5):
try:
res = windll.gdi32.SetDeviceGammaRamp(
_winDC & LPCVOID(0xFFFFFFFF), _LUT.ctypes
)
except TypeError:
res = windll.gdi32.SetDeviceGammaRamp(_winDC, _LUT.ctypes)
time.sleep(0.1)
if res:
break
if res:
_log.Log.write("OK", "SetDeviceGammaRamp worked")
return stm.StimErrC.ok
else:
_log.Log.write("ERROR", "SetDeviceGammaRamp failed")
return stm.StimErrC.SetGammaLUTFailed
# ---------------------------------------------------------------------
def restoreGammaLUT(_winDC):
return setGammaLUT(_winDC, generateLinearLUT())
# ---------------------------------------------------------------------
def loadGammaLUT(_fName):
_log.Log.write(" ", "Loading user-defined gamma LUT file ...")
try:
rgb = []
r = []
g = []
b = []
fName = _fName + glo.QDSpy_LUTFileExt
with open(fName, "r") as LUTFile:
for line in LUTFile:
rgb = [int(v.strip()) for v in line.split(",")]
r.append(rgb[0])
g.append(rgb[1])
b.append(rgb[2])
newLUT = numpy.array([r, g, b])
newLUT = newLUT.astype(numpy.uint16)
_log.Log.write("ok", "... done")
return newLUT
except IOError:
_log.Log.write("ERROR", "gamma LUT file `{0}` not found".format(fName))
return generateLinearLUT()
# ---------------------------------------------------------------------