summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Ritger <aritger@nvidia.com>2012-08-24 15:53:08 -0700
committerAaron Plattner <aplattner@nvidia.com>2012-08-24 20:49:11 -0700
commit90afd01788be7bf19e441a59dca0d8057c5267b1 (patch)
tree966e126dcbfb7c6a19e63ac845c3168f9aacf602
parent6bf48ae8d8db58ab74182383e54332f120f024c2 (diff)
xrandr: fix gamma == 1.0 && sigbits != 8
The gamma-correction lookup table managed through XRR[GS]etCrtcGamma is 2^n in size, where 'n' is the number of significant bits in the X Color. Each element in the gamma-correction lookup table is a 16:16:16 X Color (i.e., in the range [0,65536) ). The significant bits of each component of each element in the lookup table are programmed into the hardware lookup table. Meaningful values in the gamma-correction lookup table are thus in the range [0,2^sigbits), where all values are shifted into the MSBs (i.e., left shifted by (16 - sigificant bits)). Signed-off-by: Andy Ritger <aritger@nvidia.com> Reviewed-by: Aaron Plattner <aplattner@nvidia.com> Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
-rw-r--r--xrandr.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/xrandr.c b/xrandr.c
index 75ed2ee..045fe29 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -1323,7 +1323,7 @@ set_gamma(void)
output_t *output;
for (output = outputs; output; output = output->next) {
- int i, size;
+ int i, size, shift;
crtc_t *crtc;
XRRCrtcGamma *gamma;
float gammaRed;
@@ -1347,6 +1347,24 @@ set_gamma(void)
continue;
}
+ /*
+ * The gamma-correction lookup table managed through XRR[GS]etCrtcGamma
+ * is 2^n in size, where 'n' is the number of significant bits in
+ * the X Color. Because an X Color is 16 bits, size cannot be larger
+ * than 2^16.
+ */
+ if (size > 65536) {
+ fatal("Gamma correction table is impossibly large.\n");
+ continue;
+ }
+
+ /*
+ * The hardware color lookup table has a number of significant
+ * bits equal to ffs(size) - 1; shift values so that they
+ * occupy the MSBs of the 16-bit X Color.
+ */
+ shift = 16 - (ffs(size) - 1);
+
gamma = XRRAllocGamma(size);
if (!gamma) {
fatal("Gamma allocation failed.\n");
@@ -1366,21 +1384,21 @@ set_gamma(void)
for (i = 0; i < size; i++) {
if (gammaRed == 1.0 && output->brightness == 1.0)
- gamma->red[i] = (i << 8) + i;
+ gamma->red[i] = (i << shift);
else
gamma->red[i] = dmin(pow((double)i/(double)(size - 1),
gammaRed) * output->brightness,
1.0) * 65535.0;
if (gammaGreen == 1.0 && output->brightness == 1.0)
- gamma->green[i] = (i << 8) + i;
+ gamma->green[i] = (i << shift);
else
gamma->green[i] = dmin(pow((double)i/(double)(size - 1),
gammaGreen) * output->brightness,
1.0) * 65535.0;
if (gammaBlue == 1.0 && output->brightness == 1.0)
- gamma->blue[i] = (i << 8) + i;
+ gamma->blue[i] = (i << shift);
else
gamma->blue[i] = dmin(pow((double)i/(double)(size - 1),
gammaBlue) * output->brightness,