Add support for changing the gamma value

This commit is contained in:
András Mohari 2013-11-13 20:54:09 +01:00
parent 450c1ed9b5
commit 0353e6eea2
9 changed files with 91 additions and 3 deletions

View file

@ -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) bool it_toggle_alpha(arg_t a)
{ {
img.alpha = tns.alpha = !img.alpha; img.alpha = tns.alpha = !img.alpha;

View file

@ -67,6 +67,7 @@ bool i_fit_to_img(arg_t);
bool i_rotate(arg_t); bool i_rotate(arg_t);
bool i_flip(arg_t); bool i_flip(arg_t);
bool i_toggle_antialias(arg_t); bool i_toggle_antialias(arg_t);
bool i_change_gamma(arg_t);
bool it_toggle_alpha(arg_t); bool it_toggle_alpha(arg_t);
bool it_open_with(arg_t); bool it_open_with(arg_t);
bool it_shell_cmd(arg_t); bool it_shell_cmd(arg_t);

View file

@ -46,6 +46,12 @@ enum {
GIF_LOOP = 0 /* endless loop [0/1] */ 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 #endif
#ifdef _THUMBS_CONFIG #ifdef _THUMBS_CONFIG
@ -141,6 +147,11 @@ static const keymap_t keys[] = {
{ false, XK_a, i_toggle_antialias, (arg_t) None }, { false, XK_a, i_toggle_antialias, (arg_t) None },
{ false, XK_A, it_toggle_alpha, (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: */ /* open current image with given program: */
{ true, XK_g, it_open_with, (arg_t) "gimp" }, { true, XK_g, it_open_with, (arg_t) "gimp" },

30
image.c
View file

@ -67,6 +67,9 @@ void img_init(img_t *img, win_t *win)
img->alpha = !RENDER_WHITE_ALPHA; img->alpha = !RENDER_WHITE_ALPHA;
img->multi.cap = img->multi.cnt = 0; img->multi.cap = img->multi.cnt = 0;
img->multi.animate = false; img->multi.animate = false;
img->cmod = imlib_create_color_modifier();
img_set_gamma(img, options->gamma);
} }
void exif_auto_orientate(const fileinfo_t *file) 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); img_load_gif(img, file);
#endif #endif
img_set_gamma(img, img->gamma);
img->w = imlib_image_get_width(); img->w = imlib_image_get_width();
img->h = imlib_image_get_height(); img->h = imlib_image_get_height();
img->scalemode = options->scalemode; img->scalemode = options->scalemode;
@ -335,6 +340,9 @@ void img_close(img_t *img, bool decache)
imlib_free_image(); imlib_free_image();
img->im = NULL; img->im = NULL;
} }
if (img->cmod)
imlib_context_set_color_modifier(NULL);
} }
void img_check_pan(img_t *img, bool moved) void img_check_pan(img_t *img, bool moved)
@ -706,6 +714,28 @@ void img_toggle_antialias(img_t *img)
img->dirty = true; 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) bool img_frame_goto(img_t *img, int n)
{ {
if (img == NULL || img->im == NULL) if (img == NULL || img->im == NULL)

View file

@ -55,6 +55,9 @@ typedef struct {
bool aa; bool aa;
bool alpha; bool alpha;
Imlib_Color_Modifier cmod;
int gamma;
multi_img_t multi; multi_img_t multi;
} img_t; } img_t;
@ -81,6 +84,8 @@ void img_flip(img_t*, flipdir_t);
void img_toggle_antialias(img_t*); void img_toggle_antialias(img_t*);
void img_set_gamma(img_t*, int);
bool img_frame_navigate(img_t*, int); bool img_frame_navigate(img_t*, int);
bool img_frame_animate(img_t*, bool); bool img_frame_animate(img_t*, bool);

2
main.c
View file

@ -352,6 +352,8 @@ void update_info(void)
n += snprintf(rt + n, rlen - n, "%0*d/%d | ", n += snprintf(rt + n, rlen - n, "%0*d/%d | ",
fn, img.multi.sel + 1, img.multi.cnt); 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); n += snprintf(rt + n, rlen - n, "%0*d/%d", fw, sel + 1, filecnt);
ow_info = info.script == NULL; ow_info = info.script == NULL;
} }

View file

@ -33,7 +33,7 @@ const options_t *options = (const options_t*) &_options;
void print_usage(void) 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"); "[-N name] [-z ZOOM] FILES...\n");
} }
@ -44,7 +44,7 @@ void print_version(void)
void parse_options(int argc, char **argv) void parse_options(int argc, char **argv)
{ {
int opt, t; int opt, t, gamma;
_options.from_stdin = false; _options.from_stdin = false;
_options.to_stdout = false; _options.to_stdout = false;
@ -53,6 +53,7 @@ void parse_options(int argc, char **argv)
_options.scalemode = SCALE_MODE; _options.scalemode = SCALE_MODE;
_options.zoom = 1.0; _options.zoom = 1.0;
_options.gamma = 0;
_options.fixed_win = false; _options.fixed_win = false;
_options.fullscreen = false; _options.fullscreen = false;
@ -64,7 +65,7 @@ void parse_options(int argc, char **argv)
_options.thumb_mode = false; _options.thumb_mode = false;
_options.clean_cache = 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) { switch (opt) {
case '?': case '?':
print_usage(); print_usage();
@ -87,6 +88,14 @@ void parse_options(int argc, char **argv)
case 'g': case 'g':
_options.geometry = optarg; _options.geometry = optarg;
break; 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': case 'h':
print_usage(); print_usage();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View file

@ -34,6 +34,7 @@ typedef struct {
/* image: */ /* image: */
scalemode_t scalemode; scalemode_t scalemode;
float zoom; float zoom;
int gamma;
/* window: */ /* window: */
bool fixed_win; bool fixed_win;

13
sxiv.1
View file

@ -49,6 +49,9 @@ Set window position and size. See section GEOMETRY SPECIFICATIONS of X(7) for
more information on more information on
.IR GEOMETRY . .IR GEOMETRY .
.TP .TP
.BI "\-G " GAMMA
Set gamma to GAMMA (-32..32).
.TP
.BI "\-n " NUM .BI "\-n " NUM
Start at picture number NUM. Start at picture number NUM.
.TP .TP
@ -282,6 +285,16 @@ Flip image horizontally.
.TP .TP
.B _ .B _
Flip image vertically. Flip image vertically.
.SS Gamma Correction
.TP
.B {
Decrease gamma.
.TP
.B }
Increase gamma.
.TP
.B Ctrl-G
Reset gamma.
.SS Miscellaneous .SS Miscellaneous
.TP .TP
.B a .B a