diff options
| -rw-r--r-- | commands.c | 16 | ||||
| -rw-r--r-- | commands.h | 1 | ||||
| -rw-r--r-- | config.def.h | 11 | ||||
| -rw-r--r-- | image.c | 30 | ||||
| -rw-r--r-- | image.h | 5 | ||||
| -rw-r--r-- | main.c | 2 | ||||
| -rw-r--r-- | options.c | 15 | ||||
| -rw-r--r-- | options.h | 1 | ||||
| -rw-r--r-- | sxiv.1 | 13 | 
9 files changed, 91 insertions, 3 deletions
@@ -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); 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" }, @@ -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  | 
