@@ -474,6 +474,22 @@ bool i_toggle_antialias(arg_t a) | |||
} | |||
} | |||
/* a < 0: decrease gamma | |||
* a == 0: reset gamma | |||
* a > 0: increase gamma | |||
*/ | |||
bool i_change_gamma(arg_t a) | |||
{ | |||
if (mode == MODE_IMAGE) { | |||
long val = (long) a; | |||
int delta = val > 0 ? 1 : (val < 0 ? -1 : -img.gamma); | |||
img_set_gamma(&img, img.gamma + delta); | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
bool it_toggle_alpha(arg_t a) | |||
{ | |||
img.alpha = tns.alpha = !img.alpha; | |||
@@ -67,6 +67,7 @@ bool i_fit_to_img(arg_t); | |||
bool i_rotate(arg_t); | |||
bool i_flip(arg_t); | |||
bool i_toggle_antialias(arg_t); | |||
bool i_change_gamma(arg_t); | |||
bool it_toggle_alpha(arg_t); | |||
bool it_open_with(arg_t); | |||
bool it_shell_cmd(arg_t); | |||
@@ -46,6 +46,12 @@ enum { | |||
GIF_LOOP = 0 /* endless loop [0/1] */ | |||
}; | |||
/* gamma correction: the user-visible ranges [-GAMMA_RANGE, 0] and | |||
* (0, GAMMA_RANGE] are mapped to the ranges [0, 1], and (1, GAMMA_MAX]. | |||
* */ | |||
static const double GAMMA_MAX = 10.0; | |||
static const int GAMMA_RANGE = 32; | |||
#endif | |||
#ifdef _THUMBS_CONFIG | |||
@@ -141,6 +147,11 @@ static const keymap_t keys[] = { | |||
{ false, XK_a, i_toggle_antialias, (arg_t) None }, | |||
{ false, XK_A, it_toggle_alpha, (arg_t) None }, | |||
/* decrease/increase/reset gamma */ | |||
{ false, XK_braceleft, i_change_gamma, (arg_t) -1 }, | |||
{ false, XK_braceright, i_change_gamma, (arg_t) +1 }, | |||
{ true, XK_G, i_change_gamma, (arg_t) 0 }, | |||
/* open current image with given program: */ | |||
{ true, XK_g, it_open_with, (arg_t) "gimp" }, | |||
@@ -67,6 +67,9 @@ void img_init(img_t *img, win_t *win) | |||
img->alpha = !RENDER_WHITE_ALPHA; | |||
img->multi.cap = img->multi.cnt = 0; | |||
img->multi.animate = false; | |||
img->cmod = imlib_create_color_modifier(); | |||
img_set_gamma(img, options->gamma); | |||
} | |||
void exif_auto_orientate(const fileinfo_t *file) | |||
@@ -303,6 +306,8 @@ bool img_load(img_t *img, const fileinfo_t *file) | |||
img_load_gif(img, file); | |||
#endif | |||
img_set_gamma(img, img->gamma); | |||
img->w = imlib_image_get_width(); | |||
img->h = imlib_image_get_height(); | |||
img->scalemode = options->scalemode; | |||
@@ -335,6 +340,9 @@ void img_close(img_t *img, bool decache) | |||
imlib_free_image(); | |||
img->im = NULL; | |||
} | |||
if (img->cmod) | |||
imlib_context_set_color_modifier(NULL); | |||
} | |||
void img_check_pan(img_t *img, bool moved) | |||
@@ -706,6 +714,28 @@ void img_toggle_antialias(img_t *img) | |||
img->dirty = true; | |||
} | |||
void img_set_gamma(img_t *img, int gamma) | |||
{ | |||
if (img == NULL) | |||
return; | |||
img->gamma = MIN(MAX(gamma, -GAMMA_RANGE), GAMMA_RANGE); | |||
if (img->im && img->cmod) { | |||
if (img->gamma == 0) { | |||
imlib_context_set_color_modifier(NULL); | |||
} else { | |||
double range = img->gamma <= 0 ? 1.0 : GAMMA_MAX - 1.0; | |||
imlib_context_set_color_modifier(img->cmod); | |||
imlib_reset_color_modifier(); | |||
imlib_modify_color_modifier_gamma( | |||
1.0 + (double) img->gamma | |||
* (range / (double) GAMMA_RANGE)); | |||
} | |||
img->dirty = true; | |||
} | |||
} | |||
bool img_frame_goto(img_t *img, int n) | |||
{ | |||
if (img == NULL || img->im == NULL) | |||
@@ -55,6 +55,9 @@ typedef struct { | |||
bool aa; | |||
bool alpha; | |||
Imlib_Color_Modifier cmod; | |||
int gamma; | |||
multi_img_t multi; | |||
} img_t; | |||
@@ -81,6 +84,8 @@ void img_flip(img_t*, flipdir_t); | |||
void img_toggle_antialias(img_t*); | |||
void img_set_gamma(img_t*, int); | |||
bool img_frame_navigate(img_t*, int); | |||
bool img_frame_animate(img_t*, bool); | |||
@@ -352,6 +352,8 @@ void update_info(void) | |||
n += snprintf(rt + n, rlen - n, "%0*d/%d | ", | |||
fn, img.multi.sel + 1, img.multi.cnt); | |||
} | |||
if (img.gamma != 0) | |||
n += snprintf(rt + n, rlen - n, "g%d | ", img.gamma); | |||
n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt); | |||
ow_info = info.script == NULL; | |||
} | |||
@@ -33,7 +33,7 @@ const options_t *options = (const options_t*) &_options; | |||
void print_usage(void) | |||
{ | |||
printf("usage: sxiv [-bcdFfhioqrstvZ] [-g GEOMETRY] [-n NUM] " | |||
printf("usage: sxiv [-bcdFfhioqrstvZ] [-g GEOMETRY] [-G GAMMA] [-n NUM] " | |||
"[-N name] [-z ZOOM] FILES...\n"); | |||
} | |||
@@ -44,7 +44,7 @@ void print_version(void) | |||
void parse_options(int argc, char **argv) | |||
{ | |||
int opt, t; | |||
int opt, t, gamma; | |||
_options.from_stdin = false; | |||
_options.to_stdout = false; | |||
@@ -53,6 +53,7 @@ void parse_options(int argc, char **argv) | |||
_options.scalemode = SCALE_MODE; | |||
_options.zoom = 1.0; | |||
_options.gamma = 0; | |||
_options.fixed_win = false; | |||
_options.fullscreen = false; | |||
@@ -64,7 +65,7 @@ void parse_options(int argc, char **argv) | |||
_options.thumb_mode = false; | |||
_options.clean_cache = false; | |||
while ((opt = getopt(argc, argv, "bcdFfg:hin:N:oqrstvZz:")) != -1) { | |||
while ((opt = getopt(argc, argv, "bcdFfg:G:hin:N:oqrstvZz:")) != -1) { | |||
switch (opt) { | |||
case '?': | |||
print_usage(); | |||
@@ -87,6 +88,14 @@ void parse_options(int argc, char **argv) | |||
case 'g': | |||
_options.geometry = optarg; | |||
break; | |||
case 'G': | |||
if (sscanf(optarg, "%d", &gamma) <= 0) { | |||
fprintf(stderr, "sxiv: invalid argument for option -G: %s\n", | |||
optarg); | |||
exit(EXIT_FAILURE); | |||
} | |||
_options.gamma = gamma; | |||
break; | |||
case 'h': | |||
print_usage(); | |||
exit(EXIT_SUCCESS); | |||
@@ -34,6 +34,7 @@ typedef struct { | |||
/* image: */ | |||
scalemode_t scalemode; | |||
float zoom; | |||
int gamma; | |||
/* window: */ | |||
bool fixed_win; | |||
@@ -49,6 +49,9 @@ Set window position and size. See section GEOMETRY SPECIFICATIONS of X(7) for | |||
more information on | |||
.IR GEOMETRY . | |||
.TP | |||
.BI "\-G " GAMMA | |||
Set gamma to GAMMA (-32..32). | |||
.TP | |||
.BI "\-n " NUM | |||
Start at picture number NUM. | |||
.TP | |||
@@ -282,6 +285,16 @@ Flip image horizontally. | |||
.TP | |||
.B _ | |||
Flip image vertically. | |||
.SS Gamma Correction | |||
.TP | |||
.B { | |||
Decrease gamma. | |||
.TP | |||
.B } | |||
Increase gamma. | |||
.TP | |||
.B Ctrl-G | |||
Reset gamma. | |||
.SS Miscellaneous | |||
.TP | |||
.B a | |||