diff --git a/config.def.h b/config.def.h index b1e9c02..532de3f 100644 --- a/config.def.h +++ b/config.def.h @@ -43,7 +43,7 @@ static const float zoom_levels[] = { enum { GIF_DELAY = 100, /* delay time (in ms) */ GIF_AUTOPLAY = 1, /* autoplay when loaded [0/1] */ - GIF_LOOP = 0 /* endless loop [0/1] */ + GIF_LOOP = -1 /* endless loop [0 / 1 / -1=as specified in file] */ }; /* gamma correction: the user-visible ranges [-GAMMA_RANGE, 0] and diff --git a/image.c b/image.c index 2d82f95..12cc45f 100644 --- a/image.c +++ b/image.c @@ -83,6 +83,8 @@ 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->multi.anim_repeats = -1; + img->multi.repeats_currently_left = 0; img->cmod = imlib_create_color_modifier(); img->gamma = MIN(MAX(options->gamma, -GAMMA_RANGE), GAMMA_RANGE); @@ -144,6 +146,8 @@ bool img_load_gif(img_t *img, const fileinfo_t *file) } img->multi.cnt = 0; img->multi.sel = 0; + img->multi.anim_repeats = -1; + img->multi.repeats_currently_left = 0; #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 gif = DGifOpenFileName(file->path, NULL); @@ -170,7 +174,7 @@ bool img_load_gif(img_t *img, const fileinfo_t *file) DGifGetExtension(gif, &ext_code, &ext); while (ext) { - if (ext_code == 0xf9) { + if (ext_code == 0xf9) { /*Graphics Control Extension*/ if (ext[1] & 1) transp = (int) ext[4]; else @@ -181,6 +185,16 @@ bool img_load_gif(img_t *img, const fileinfo_t *file) delay = MAX(delay, MIN_GIF_DELAY); disposal = (unsigned int) ext[1] >> 2 & 0x7; + } else if (ext_code == 0xff) { /*Application Extension*/ + if(ext[0] == 11 && memcmp(ext+1, "NETSCAPE2.0", 11) == 0) { + DGifGetExtensionNext(gif, &ext); + + if(ext && ext[0] == 3 && ext[1] == 1) { + img->multi.repeats_currently_left = + img->multi.anim_repeats = + ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]); + } + } } ext = NULL; DGifGetExtensionNext(gif, &ext); @@ -797,8 +811,15 @@ bool img_frame_animate(img_t *img, bool restart) return false; if (img->multi.sel + 1 >= img->multi.cnt) { - if (restart || GIF_LOOP) { + if (GIF_LOOP == 1 || (GIF_LOOP == -1 && img->multi.anim_repeats == 0) ) { img_frame_goto(img, 0); + } else if(restart) { + img_frame_goto(img, 0); + img->multi.repeats_currently_left = + (img->multi.anim_repeats != -1 ? img->multi.anim_repeats : 0); + } else if(GIF_LOOP == -1 && img->multi.repeats_currently_left != 0) { + img_frame_goto(img, 0); + --img->multi.repeats_currently_left; } else { img->multi.animate = false; return false; diff --git a/image.h b/image.h index 04d48a3..9c3ced3 100644 --- a/image.h +++ b/image.h @@ -35,6 +35,8 @@ typedef struct { int cnt; int sel; bool animate; + int anim_repeats; // -1=don't repeat, 0=repeat infinitely, N=repeat N times + unsigned int repeats_currently_left; } multi_img_t; typedef struct {