====== Setting contrast in X.org ======
Use-case: Enhance contrast when reading scanned document and document viewer does not support contrast adjustment.
XF86VidModeSetGammaRamp [[https://bugs.freedesktop.org/show_bug.cgi?id=27222#c27|is broken]] in recent X.org. I have created an [[https://jenda.hrach.eu/f/xlevels/redshift.d51c25e76eaf9d7f9318f5ec1b4e7eb04454f46c.patch|ugly patch]] for redshift (apply, compile, run "./src/redshift -O 3000 white_threshold black_treshold") to work around it.
I was unable to find a tool that can fix this (tried xcalib, xgamma, xrandr and redshift). So I have created one myself. Unfortunately I don't know how to set contrast per window, so your whole X session is affected.
Compile:
gcc -std=gnu99 -O2 -g -ggdb3 -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXxf86vm -lXext -o xlevels xlevels.c
Usage:
./xlevels white_threshold black_treshold
(it's the same syntax like in GIMP)
Examples:
* Web2.0 page using gray text on white background (like [[http://blog.cryptographyengineering.com/|this one]]) (very common, no idea why designers do this, and Firefox can't cope with this):
./xlevels 100 255
* Scanned or photographed document
./xlevels 50 230
* Help! I've broken my X server and I see only a white/black screen!
xcalib -c
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv) {
/* XF86 substitution table */
uint16_t rtable[256];
/* read input */
uint32_t lowcut = atoi(argv[1]);
uint32_t highcut = (255-atoi(argv[2]));
float slope = 257;
float range = 65535 - (lowcut*257 + highcut*257);
printf("range = %f\n", range);
if(range != 0) {
slope *= 65535/range;
}
printf("slope = %f\n", slope);
/* compute profile */
for(int i=0; i<256; i++) {
rtable[i] = (uint16_t) (slope*(i-lowcut));
if(i<=lowcut) {
rtable[i] = 0;
}
if(i>=255-highcut) {
rtable[i] = 0xffff;
}
printf("%05i ", rtable[i]);
if(i%16 == 15 && i>1) {
printf("\n");
}
}
/* X11 magic */
Display *dpy = NULL;
dpy = XOpenDisplay (NULL);
int screen = DefaultScreen (dpy);
XF86VidModeSetGammaRamp (dpy, screen, 256, rtable, rtable, rtable);
}