nsxiv2737fc8
Merge remote-tracking branch 'ariand/gamma'
+91 −3
9 files changed
- M commands.c +16 −0
- M commands.h +1 −0
- M config.def.h +11 −0
- M image.c +30 −0
- M image.h +5 −0
- M main.c +2 −0
- M options.c +12 −3
- M options.h +1 −0
- M sxiv.1 +13 −0
| @@ -474,6 +474,22 @@ bool i_toggle_antialias(arg_t a) | |||
| 474 | 474 | } | |
| 475 | 475 | } | |
| 476 | 476 | ||
| 477 | + | /* a < 0: decrease gamma | |
| 478 | + | * a == 0: reset gamma | |
| 479 | + | * a > 0: increase gamma | |
| 480 | + | */ | |
| 481 | + | bool i_change_gamma(arg_t a) | |
| 482 | + | { | |
| 483 | + | if (mode == MODE_IMAGE) { | |
| 484 | + | long val = (long) a; | |
| 485 | + | int delta = val > 0 ? 1 : (val < 0 ? -1 : -img.gamma); | |
| 486 | + | img_set_gamma(&img, img.gamma + delta); | |
| 487 | + | return true; | |
| 488 | + | } else { | |
| 489 | + | return false; | |
| 490 | + | } | |
| 491 | + | } | |
| 492 | + | ||
| 477 | 493 | bool it_toggle_alpha(arg_t a) | |
| 478 | 494 | { | |
| 479 | 495 | img.alpha = tns.alpha = !img.alpha; | |
| @@ -67,6 +67,7 @@ bool i_fit_to_img(arg_t); | |||
| 67 | 67 | bool i_rotate(arg_t); | |
| 68 | 68 | bool i_flip(arg_t); | |
| 69 | 69 | bool i_toggle_antialias(arg_t); | |
| 70 | + | bool i_change_gamma(arg_t); | |
| 70 | 71 | bool it_toggle_alpha(arg_t); | |
| 71 | 72 | bool it_open_with(arg_t); | |
| 72 | 73 | bool it_shell_cmd(arg_t); | |
| @@ -46,6 +46,12 @@ enum { | |||
| 46 | 46 | GIF_LOOP = 0 /* endless loop [0/1] */ | |
| 47 | 47 | }; | |
| 48 | 48 | ||
| 49 | + | /* gamma correction: the user-visible ranges [-GAMMA_RANGE, 0] and | |
| 50 | + | * (0, GAMMA_RANGE] are mapped to the ranges [0, 1], and (1, GAMMA_MAX]. | |
| 51 | + | * */ | |
| 52 | + | static const double GAMMA_MAX = 10.0; | |
| 53 | + | static const int GAMMA_RANGE = 32; | |
| 54 | + | ||
| 49 | 55 | #endif | |
| 50 | 56 | #ifdef _THUMBS_CONFIG | |
| 51 | 57 | ||
| @@ -141,6 +147,11 @@ static const keymap_t keys[] = { | |||
| 141 | 147 | { false, XK_a, i_toggle_antialias, (arg_t) None }, | |
| 142 | 148 | { false, XK_A, it_toggle_alpha, (arg_t) None }, | |
| 143 | 149 | ||
| 150 | + | /* decrease/increase/reset gamma */ | |
| 151 | + | { false, XK_braceleft, i_change_gamma, (arg_t) -1 }, | |
| 152 | + | { false, XK_braceright, i_change_gamma, (arg_t) +1 }, | |
| 153 | + | { true, XK_G, i_change_gamma, (arg_t) 0 }, | |
| 154 | + | ||
| 144 | 155 | /* open current image with given program: */ | |
| 145 | 156 | { true, XK_g, it_open_with, (arg_t) "gimp" }, | |
| 146 | 157 | ||
| @@ -67,6 +67,9 @@ void img_init(img_t *img, win_t *win) | |||
| 67 | 67 | img->alpha = !RENDER_WHITE_ALPHA; | |
| 68 | 68 | img->multi.cap = img->multi.cnt = 0; | |
| 69 | 69 | img->multi.animate = false; | |
| 70 | + | ||
| 71 | + | img->cmod = imlib_create_color_modifier(); | |
| 72 | + | img_set_gamma(img, options->gamma); | |
| 70 | 73 | } | |
| 71 | 74 | ||
| 72 | 75 | void exif_auto_orientate(const fileinfo_t *file) | |
| @@ -303,6 +306,8 @@ bool img_load(img_t *img, const fileinfo_t *file) | |||
| 303 | 306 | img_load_gif(img, file); | |
| 304 | 307 | #endif | |
| 305 | 308 | ||
| 309 | + | img_set_gamma(img, img->gamma); | |
| 310 | + | ||
| 306 | 311 | img->w = imlib_image_get_width(); | |
| 307 | 312 | img->h = imlib_image_get_height(); | |
| 308 | 313 | img->scalemode = options->scalemode; | |
| @@ -335,6 +340,9 @@ void img_close(img_t *img, bool decache) | |||
| 335 | 340 | imlib_free_image(); | |
| 336 | 341 | img->im = NULL; | |
| 337 | 342 | } | |
| 343 | + | ||
| 344 | + | if (img->cmod) | |
| 345 | + | imlib_context_set_color_modifier(NULL); | |
| 338 | 346 | } | |
| 339 | 347 | ||
| 340 | 348 | void img_check_pan(img_t *img, bool moved) | |
| @@ -706,6 +714,28 @@ void img_toggle_antialias(img_t *img) | |||
| 706 | 714 | img->dirty = true; | |
| 707 | 715 | } | |
| 708 | 716 | ||
| 717 | + | void img_set_gamma(img_t *img, int gamma) | |
| 718 | + | { | |
| 719 | + | if (img == NULL) | |
| 720 | + | return; | |
| 721 | + | ||
| 722 | + | img->gamma = MIN(MAX(gamma, -GAMMA_RANGE), GAMMA_RANGE); | |
| 723 | + | ||
| 724 | + | if (img->im && img->cmod) { | |
| 725 | + | if (img->gamma == 0) { | |
| 726 | + | imlib_context_set_color_modifier(NULL); | |
| 727 | + | } else { | |
| 728 | + | double range = img->gamma <= 0 ? 1.0 : GAMMA_MAX - 1.0; | |
| 729 | + | imlib_context_set_color_modifier(img->cmod); | |
| 730 | + | imlib_reset_color_modifier(); | |
| 731 | + | imlib_modify_color_modifier_gamma( | |
| 732 | + | 1.0 + (double) img->gamma | |
| 733 | + | * (range / (double) GAMMA_RANGE)); | |
| 734 | + | } | |
| 735 | + | img->dirty = true; | |
| 736 | + | } | |
| 737 | + | } | |
| 738 | + | ||
| 709 | 739 | bool img_frame_goto(img_t *img, int n) | |
| 710 | 740 | { | |
| 711 | 741 | if (img == NULL || img->im == NULL) | |
| @@ -55,6 +55,9 @@ typedef struct { | |||
| 55 | 55 | bool aa; | |
| 56 | 56 | bool alpha; | |
| 57 | 57 | ||
| 58 | + | Imlib_Color_Modifier cmod; | |
| 59 | + | int gamma; | |
| 60 | + | ||
| 58 | 61 | multi_img_t multi; | |
| 59 | 62 | } img_t; | |
| 60 | 63 | ||
| @@ -81,6 +84,8 @@ void img_flip(img_t*, flipdir_t); | |||
| 81 | 84 | ||
| 82 | 85 | void img_toggle_antialias(img_t*); | |
| 83 | 86 | ||
| 87 | + | void img_set_gamma(img_t*, int); | |
| 88 | + | ||
| 84 | 89 | bool img_frame_navigate(img_t*, int); | |
| 85 | 90 | bool img_frame_animate(img_t*, bool); | |
| 86 | 91 | ||
| @@ -351,6 +351,8 @@ void update_info(void) | |||
| 351 | 351 | n += snprintf(rt + n, rlen - n, "%0*d/%d | ", | |
| 352 | 352 | fn, img.multi.sel + 1, img.multi.cnt); | |
| 353 | 353 | } | |
| 354 | + | if (img.gamma != 0) | |
| 355 | + | n += snprintf(rt + n, rlen - n, "g%d | ", img.gamma); | |
| 354 | 356 | n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt); | |
| 355 | 357 | ow_info = info.script == NULL; | |
| 356 | 358 | } | |
| @@ -33,7 +33,7 @@ const options_t *options = (const options_t*) &_options; | |||
| 33 | 33 | ||
| 34 | 34 | void print_usage(void) | |
| 35 | 35 | { | |
| 36 | − | printf("usage: sxiv [-bcdFfhioqrstvZ] [-g GEOMETRY] [-n NUM] " | |
| 36 | + | printf("usage: sxiv [-bcdFfhioqrstvZ] [-g GEOMETRY] [-G GAMMA] [-n NUM] " | |
| 37 | 37 | "[-N name] [-z ZOOM] FILES...\n"); | |
| 38 | 38 | } | |
| 39 | 39 | ||
| @@ -44,7 +44,7 @@ void print_version(void) | |||
| 44 | 44 | ||
| 45 | 45 | void parse_options(int argc, char **argv) | |
| 46 | 46 | { | |
| 47 | − | int opt, t; | |
| 47 | + | int opt, t, gamma; | |
| 48 | 48 | ||
| 49 | 49 | _options.from_stdin = false; | |
| 50 | 50 | _options.to_stdout = false; | |
| @@ -53,6 +53,7 @@ void parse_options(int argc, char **argv) | |||
| 53 | 53 | ||
| 54 | 54 | _options.scalemode = SCALE_MODE; | |
| 55 | 55 | _options.zoom = 1.0; | |
| 56 | + | _options.gamma = 0; | |
| 56 | 57 | ||
| 57 | 58 | _options.fixed_win = false; | |
| 58 | 59 | _options.fullscreen = false; | |
| @@ -64,7 +65,7 @@ void parse_options(int argc, char **argv) | |||
| 64 | 65 | _options.thumb_mode = false; | |
| 65 | 66 | _options.clean_cache = false; | |
| 66 | 67 | ||
| 67 | − | while ((opt = getopt(argc, argv, "bcdFfg:hin:N:oqrstvZz:")) != -1) { | |
| 68 | + | while ((opt = getopt(argc, argv, "bcdFfg:G:hin:N:oqrstvZz:")) != -1) { | |
| 68 | 69 | switch (opt) { | |
| 69 | 70 | case '?': | |
| 70 | 71 | print_usage(); | |
| @@ -87,6 +88,14 @@ void parse_options(int argc, char **argv) | |||
| 87 | 88 | case 'g': | |
| 88 | 89 | _options.geometry = optarg; | |
| 89 | 90 | break; | |
| 91 | + | case 'G': | |
| 92 | + | if (sscanf(optarg, "%d", &gamma) <= 0) { | |
| 93 | + | fprintf(stderr, "sxiv: invalid argument for option -G: %s\n", | |
| 94 | + | optarg); | |
| 95 | + | exit(EXIT_FAILURE); | |
| 96 | + | } | |
| 97 | + | _options.gamma = gamma; | |
| 98 | + | break; | |
| 90 | 99 | case 'h': | |
| 91 | 100 | print_usage(); | |
| 92 | 101 | exit(EXIT_SUCCESS); | |
| @@ -34,6 +34,7 @@ typedef struct { | |||
| 34 | 34 | /* image: */ | |
| 35 | 35 | scalemode_t scalemode; | |
| 36 | 36 | float zoom; | |
| 37 | + | int gamma; | |
| 37 | 38 | ||
| 38 | 39 | /* window: */ | |
| 39 | 40 | bool fixed_win; | |
| @@ -49,6 +49,9 @@ Set window position and size. See section GEOMETRY SPECIFICATIONS of X(7) for | |||
| 49 | 49 | more information on | |
| 50 | 50 | .IR GEOMETRY . | |
| 51 | 51 | .TP | |
| 52 | + | .BI "\-G " GAMMA | |
| 53 | + | Set gamma to GAMMA (-32..32). | |
| 54 | + | .TP | |
| 52 | 55 | .BI "\-n " NUM | |
| 53 | 56 | Start at picture number NUM. | |
| 54 | 57 | .TP | |
| @@ -282,6 +285,16 @@ Flip image horizontally. | |||
| 282 | 285 | .TP | |
| 283 | 286 | .B _ | |
| 284 | 287 | Flip image vertically. | |
| 288 | + | .SS Gamma Correction | |
| 289 | + | .TP | |
| 290 | + | .B { | |
| 291 | + | Decrease gamma. | |
| 292 | + | .TP | |
| 293 | + | .B } | |
| 294 | + | Increase gamma. | |
| 295 | + | .TP | |
| 296 | + | .B Ctrl-G | |
| 297 | + | Reset gamma. | |
| 285 | 298 | .SS Miscellaneous | |
| 286 | 299 | .TP | |
| 287 | 300 | .B a | |