| @@ -32,6 +32,8 @@ |
| 32 | 32 | | #include "util.h" |
| 33 | 33 | | #include "config.h" |
| 34 | 34 | | |
| 35 | + | enum { MIN_GIF_DELAY = 50 }; |
| 36 | + | |
| 35 | 37 | | int zl_cnt; |
| 36 | 38 | | float zoom_min; |
| 37 | 39 | | float zoom_max; |
| @@ -44,6 +46,7 @@ void img_init(img_t *img, win_t *win) { |
| 44 | 46 | | if (img) { |
| 45 | 47 | | img->im = NULL; |
| 46 | 48 | | img->multi.cap = img->multi.cnt = 0; |
| 49 | + | img->multi.animate = 0; |
| 47 | 50 | | img->zoom = options->zoom; |
| 48 | 51 | | img->zoom = MAX(img->zoom, zoom_min); |
| 49 | 52 | | img->zoom = MIN(img->zoom, zoom_max); |
| @@ -72,11 +75,12 @@ int img_load_gif(img_t *img, const fileinfo_t *file) { |
| 72 | 75 | | int intoffset[] = { 0, 4, 2, 1 }; |
| 73 | 76 | | int intjump[] = { 8, 8, 4, 2 }; |
| 74 | 77 | | int err = 0, transp = -1; |
| 78 | + | unsigned int delay = 0; |
| 75 | 79 | | |
| 76 | 80 | | if (img->multi.cap == 0) { |
| 77 | 81 | | img->multi.cap = 8; |
| 78 | | − | img->multi.frames = (Imlib_Image**) |
| 79 | | − | s_malloc(sizeof(Imlib_Image*) * img->multi.cap); |
| 82 | + | img->multi.frames = (img_frame_t*) |
| 83 | + | s_malloc(sizeof(img_frame_t) * img->multi.cap); |
| 80 | 84 | | } |
| 81 | 85 | | img->multi.cnt = 0; |
| 82 | 86 | | img->multi.sel = 0; |
| @@ -107,6 +111,10 @@ int img_load_gif(img_t *img, const fileinfo_t *file) { |
| 107 | 111 | | transp = (int) ext[4]; |
| 108 | 112 | | else |
| 109 | 113 | | transp = -1; |
| 114 | + | |
| 115 | + | delay = 10 * ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]); |
| 116 | + | if (delay) |
| 117 | + | delay = MAX(delay, MIN_GIF_DELAY); |
| 110 | 118 | | } |
| 111 | 119 | | ext = NULL; |
| 112 | 120 | | DGifGetExtensionNext(gif, &ext); |
| @@ -186,11 +194,13 @@ int img_load_gif(img_t *img, const fileinfo_t *file) { |
| 186 | 194 | | |
| 187 | 195 | | if (img->multi.cnt == img->multi.cap) { |
| 188 | 196 | | img->multi.cap *= 2; |
| 189 | | − | img->multi.frames = (Imlib_Image**) |
| 197 | + | img->multi.frames = (img_frame_t*) |
| 190 | 198 | | s_realloc(img->multi.frames, |
| 191 | | − | img->multi.cap * sizeof(Imlib_Image*)); |
| 199 | + | img->multi.cap * sizeof(img_frame_t)); |
| 192 | 200 | | } |
| 193 | | − | img->multi.frames[img->multi.cnt++] = im; |
| 201 | + | img->multi.frames[img->multi.cnt].im = im; |
| 202 | + | img->multi.frames[img->multi.cnt].delay = delay ? delay : GIF_DELAY; |
| 203 | + | img->multi.cnt++; |
| 194 | 204 | | } |
| 195 | 205 | | } while (rec != TERMINATE_RECORD_TYPE); |
| 196 | 206 | | |
| @@ -199,13 +209,15 @@ int img_load_gif(img_t *img, const fileinfo_t *file) { |
| 199 | 209 | | if (!err && img->multi.cnt > 1) { |
| 200 | 210 | | imlib_context_set_image(img->im); |
| 201 | 211 | | imlib_free_image(); |
| 202 | | − | img->im = img->multi.frames[0]; |
| 212 | + | img->im = img->multi.frames[0].im; |
| 213 | + | img->multi.animate = GIF_AUTOPLAY; |
| 203 | 214 | | } else { |
| 204 | 215 | | for (i = 0; i < img->multi.cnt; i++) { |
| 205 | | − | imlib_context_set_image(img->multi.frames[i]); |
| 216 | + | imlib_context_set_image(img->multi.frames[i].im); |
| 206 | 217 | | imlib_free_image(); |
| 207 | 218 | | } |
| 208 | 219 | | img->multi.cnt = 0; |
| 220 | + | img->multi.animate = 0; |
| 209 | 221 | | } |
| 210 | 222 | | |
| 211 | 223 | | imlib_context_set_image(img->im); |
| @@ -256,7 +268,7 @@ void img_close(img_t *img, int decache) { |
| 256 | 268 | | |
| 257 | 269 | | if (img->multi.cnt) { |
| 258 | 270 | | for (i = 0; i < img->multi.cnt; i++) { |
| 259 | | − | imlib_context_set_image(img->multi.frames[i]); |
| 271 | + | imlib_context_set_image(img->multi.frames[i].im); |
| 260 | 272 | | imlib_free_image(); |
| 261 | 273 | | } |
| 262 | 274 | | img->multi.cnt = 0; |
| @@ -378,27 +390,6 @@ void img_render(img_t *img, win_t *win) { |
| 378 | 390 | | win_draw(win); |
| 379 | 391 | | } |
| 380 | 392 | | |
| 381 | | − | int img_change_frame(img_t *img, int d) { |
| 382 | | − | if (!img || !img->multi.cnt || !d) |
| 383 | | − | return 0; |
| 384 | | − | |
| 385 | | − | d += img->multi.sel; |
| 386 | | − | if (d < 0) |
| 387 | | − | d = 0; |
| 388 | | − | else if (d >= img->multi.cnt) |
| 389 | | − | d = img->multi.cnt - 1; |
| 390 | | − | |
| 391 | | − | img->multi.sel = d; |
| 392 | | − | img->im = img->multi.frames[d]; |
| 393 | | − | |
| 394 | | − | imlib_context_set_image(img->im); |
| 395 | | − | img->w = imlib_image_get_width(); |
| 396 | | − | img->h = imlib_image_get_height(); |
| 397 | | − | img->checkpan = 1; |
| 398 | | − | |
| 399 | | − | return 1; |
| 400 | | − | } |
| 401 | | − | |
| 402 | 393 | | int img_fit_win(img_t *img, win_t *win) { |
| 403 | 394 | | if (!img || !img->im || !win) |
| 404 | 395 | | return 0; |
| @@ -569,3 +560,58 @@ void img_toggle_antialias(img_t *img) { |
| 569 | 560 | | imlib_context_set_anti_alias(img->aa); |
| 570 | 561 | | } |
| 571 | 562 | | } |
| 563 | + | |
| 564 | + | int img_frame_goto(img_t *img, int n) { |
| 565 | + | if (!img || n < 0 || n >= img->multi.cnt) |
| 566 | + | return 0; |
| 567 | + | |
| 568 | + | if (n == img->multi.sel) |
| 569 | + | return 0; |
| 570 | + | |
| 571 | + | img->multi.sel = n; |
| 572 | + | img->im = img->multi.frames[n].im; |
| 573 | + | |
| 574 | + | imlib_context_set_image(img->im); |
| 575 | + | img->w = imlib_image_get_width(); |
| 576 | + | img->h = imlib_image_get_height(); |
| 577 | + | img->checkpan = 1; |
| 578 | + | |
| 579 | + | return 1; |
| 580 | + | } |
| 581 | + | |
| 582 | + | int img_frame_navigate(img_t *img, int d) { |
| 583 | + | if (!img || !img->multi.cnt || !d) |
| 584 | + | return 0; |
| 585 | + | |
| 586 | + | d += img->multi.sel; |
| 587 | + | if (d < 0) |
| 588 | + | d = 0; |
| 589 | + | else if (d >= img->multi.cnt) |
| 590 | + | d = img->multi.cnt - 1; |
| 591 | + | |
| 592 | + | return img_frame_goto(img, d); |
| 593 | + | } |
| 594 | + | |
| 595 | + | int img_frame_animate(img_t *img, int restart) { |
| 596 | + | if (!img || !img->multi.cnt) |
| 597 | + | return 0; |
| 598 | + | |
| 599 | + | if (!img->multi.animate && !restart) |
| 600 | + | return 0; |
| 601 | + | |
| 602 | + | if (restart) { |
| 603 | + | img_frame_goto(img, 0); |
| 604 | + | img->multi.animate = 1; |
| 605 | + | } else if (img->multi.sel + 1 >= img->multi.cnt) { |
| 606 | + | if (!GIF_LOOP) { |
| 607 | + | img->multi.animate = 0; |
| 608 | + | return 0; |
| 609 | + | } else { |
| 610 | + | img_frame_goto(img, 0); |
| 611 | + | } |
| 612 | + | } else { |
| 613 | + | img_frame_goto(img, img->multi.sel + 1); |
| 614 | + | } |
| 615 | + | |
| 616 | + | return img->multi.frames[img->multi.sel].delay; |
| 617 | + | } |