From 0353e6eea265f5f6fa53eb75300529d9ffa6d4fa Mon Sep 17 00:00:00 2001 From: AndrĂ¡s Mohari Date: Wed, 13 Nov 2013 20:54:09 +0100 Subject: Add support for changing the gamma value --- commands.c | 16 ++++++++++++++++ commands.h | 1 + config.def.h | 11 +++++++++++ image.c | 30 ++++++++++++++++++++++++++++++ image.h | 5 +++++ main.c | 2 ++ options.c | 15 ++++++++++++--- options.h | 1 + sxiv.1 | 13 +++++++++++++ 9 files changed, 91 insertions(+), 3 deletions(-) diff --git a/commands.c b/commands.c index ff95f36..20557e5 100644 --- a/commands.c +++ b/commands.c @@ -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; diff --git a/commands.h b/commands.h index 118c89a..16aee07 100644 --- a/commands.h +++ b/commands.h @@ -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); diff --git a/config.def.h b/config.def.h index f5d048a..b877aa1 100644 --- a/config.def.h +++ b/config.def.h @@ -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" }, diff --git a/image.c b/image.c index ec248e1..b1c7851 100644 --- a/image.c +++ b/image.c @@ -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) diff --git a/image.h b/image.h index 9a4efe6..7ed104e 100644 --- a/image.h +++ b/image.h @@ -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); diff --git a/main.c b/main.c index eac3574..376898d 100644 --- a/main.c +++ b/main.c @@ -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; } diff --git a/options.c b/options.c index e47ad37..574f871 100644 --- a/options.c +++ b/options.c @@ -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); diff --git a/options.h b/options.h index 848a6b2..982602f 100644 --- a/options.h +++ b/options.h @@ -34,6 +34,7 @@ typedef struct { /* image: */ scalemode_t scalemode; float zoom; + int gamma; /* window: */ bool fixed_win; diff --git a/sxiv.1 b/sxiv.1 index ee42a00..4c29dbf 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -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 -- cgit v1.2.3-54-g00ecf