diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-11-02 13:03:58 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-11-13 18:13:10 +0100 |
commit | 0ceaff2b65c50b75ad8cc5b2d12e7b3f864092e5 (patch) | |
tree | 49d8d297cbba93902bc612a9aa4ded1b6e2d46e5 /apps/plugins/imageviewer/imageviewer.c | |
parent | b35f82c91ff050b4405b19a3e56e9d031bf940e2 (diff) | |
download | rockbox-0ceaff2b65c50b75ad8cc5b2d12e7b3f864092e5.tar.gz rockbox-0ceaff2b65c50b75ad8cc5b2d12e7b3f864092e5.zip |
imageviewer: gif viewer based on giflib-5.0.2
This adds ability to view gif images in rockbox.
Works both on color and gray/monochrome targets (greylib).
Aspect correction is supported as well.
Limitations:
- animated gifs are restricted to 32 frames
- animated gifs loop always (loopcount is ignored)
- plain text extension is not supported
- animated gifs with interframe delay = 0 are treated as still
images (web browsers usually treat delay 0 as 100ms to prevent
exhaustive CPU load by such images)
Change-Id: I61501f801ddcd403410e38d83e6bddc9883e7ede
Diffstat (limited to 'apps/plugins/imageviewer/imageviewer.c')
-rw-r--r-- | apps/plugins/imageviewer/imageviewer.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c index 044c835d00..39507a1fcf 100644 --- a/apps/plugins/imageviewer/imageviewer.c +++ b/apps/plugins/imageviewer/imageviewer.c | |||
@@ -550,17 +550,38 @@ static void pan_view_down(struct image_info *info) | |||
550 | /* interactively scroll around the image */ | 550 | /* interactively scroll around the image */ |
551 | static int scroll_bmp(struct image_info *info) | 551 | static int scroll_bmp(struct image_info *info) |
552 | { | 552 | { |
553 | static long ss_timeout = 0; | ||
554 | |||
553 | int button; | 555 | int button; |
554 | #if defined(IMGVIEW_ZOOM_PRE) || defined(IMGVIEW_MENU_PRE) | 556 | #if defined(IMGVIEW_ZOOM_PRE) || defined(IMGVIEW_MENU_PRE) |
555 | int lastbutton = BUTTON_NONE; | 557 | int lastbutton = BUTTON_NONE; |
556 | #endif | 558 | #endif |
557 | 559 | ||
560 | if (!ss_timeout && iv_api.slideshow_enabled) | ||
561 | ss_timeout = *rb->current_tick + settings.ss_timeout * HZ; | ||
562 | |||
558 | while (true) | 563 | while (true) |
559 | { | 564 | { |
560 | if (iv_api.slideshow_enabled) | 565 | if (iv_api.slideshow_enabled) |
561 | button = rb->button_get_w_tmo(settings.ss_timeout * HZ); | 566 | { |
567 | if (info->frames_count > 1 && info->delay && | ||
568 | settings.ss_timeout * HZ > info->delay) | ||
569 | { | ||
570 | /* animated content and delay between subsequent frames | ||
571 | * is shorter then slideshow delay | ||
572 | */ | ||
573 | button = rb->button_get_w_tmo(info->delay); | ||
574 | } | ||
575 | else | ||
576 | button = rb->button_get_w_tmo(settings.ss_timeout * HZ); | ||
577 | } | ||
562 | else | 578 | else |
563 | button = rb->button_get(true); | 579 | { |
580 | if (info->frames_count > 1 && info->delay) | ||
581 | button = rb->button_get_w_tmo(info->delay); | ||
582 | else | ||
583 | button = rb->button_get(true); | ||
584 | } | ||
564 | 585 | ||
565 | iv_api.running_slideshow = false; | 586 | iv_api.running_slideshow = false; |
566 | 587 | ||
@@ -595,9 +616,28 @@ static int scroll_bmp(struct image_info *info) | |||
595 | case BUTTON_NONE: | 616 | case BUTTON_NONE: |
596 | if (iv_api.slideshow_enabled && entries > 1) | 617 | if (iv_api.slideshow_enabled && entries > 1) |
597 | { | 618 | { |
598 | iv_api.running_slideshow = true; | 619 | if (info->frames_count > 1) |
599 | return change_filename(DIR_NEXT); | 620 | { |
621 | /* animations */ | ||
622 | if (TIME_AFTER(*rb->current_tick, ss_timeout)) | ||
623 | { | ||
624 | iv_api.running_slideshow = true; | ||
625 | ss_timeout = 0; | ||
626 | return change_filename(DIR_NEXT); | ||
627 | } | ||
628 | else | ||
629 | return NEXT_FRAME; | ||
630 | } | ||
631 | else | ||
632 | { | ||
633 | /* still picture */ | ||
634 | iv_api.running_slideshow = true; | ||
635 | return change_filename(DIR_NEXT); | ||
636 | } | ||
600 | } | 637 | } |
638 | else | ||
639 | return NEXT_FRAME; | ||
640 | |||
601 | break; | 641 | break; |
602 | 642 | ||
603 | #ifdef IMGVIEW_SLIDE_SHOW | 643 | #ifdef IMGVIEW_SLIDE_SHOW |
@@ -838,9 +878,11 @@ static int load_and_show(char* filename, struct image_info *info) | |||
838 | cx = info->x_size/ds/2; /* center the view */ | 878 | cx = info->x_size/ds/2; /* center the view */ |
839 | cy = info->y_size/ds/2; | 879 | cy = info->y_size/ds/2; |
840 | 880 | ||
881 | /* used to loop through subimages in animated gifs */ | ||
882 | int frame = 0; | ||
841 | do /* loop the image prepare and decoding when zoomed */ | 883 | do /* loop the image prepare and decoding when zoomed */ |
842 | { | 884 | { |
843 | status = imgdec->get_image(info, ds); /* decode or fetch from cache */ | 885 | status = imgdec->get_image(info, frame, ds); /* decode or fetch from cache */ |
844 | if (status == PLUGIN_ERROR) | 886 | if (status == PLUGIN_ERROR) |
845 | { | 887 | { |
846 | file_pt[curfile] = NULL; | 888 | file_pt[curfile] = NULL; |
@@ -849,7 +891,7 @@ static int load_and_show(char* filename, struct image_info *info) | |||
849 | 891 | ||
850 | set_view(info, cx, cy); | 892 | set_view(info, cx, cy); |
851 | 893 | ||
852 | if(!iv_api.running_slideshow) | 894 | if(!iv_api.running_slideshow && (info->frames_count == 1)) |
853 | { | 895 | { |
854 | rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height); | 896 | rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height); |
855 | rb->lcd_update(); | 897 | rb->lcd_update(); |
@@ -870,6 +912,7 @@ static int load_and_show(char* filename, struct image_info *info) | |||
870 | while (1) | 912 | while (1) |
871 | { | 913 | { |
872 | status = scroll_bmp(info); | 914 | status = scroll_bmp(info); |
915 | |||
873 | if (status == ZOOM_IN) | 916 | if (status == ZOOM_IN) |
874 | { | 917 | { |
875 | if (ds > ds_min || (imgdec->unscaled_avail && ds > 1)) | 918 | if (ds > ds_min || (imgdec->unscaled_avail && ds > 1)) |
@@ -899,16 +942,19 @@ static int load_and_show(char* filename, struct image_info *info) | |||
899 | else | 942 | else |
900 | continue; | 943 | continue; |
901 | } | 944 | } |
945 | |||
946 | /* next frame in animated content */ | ||
947 | if (status == NEXT_FRAME) | ||
948 | frame = (frame + 1)%info->frames_count; | ||
949 | |||
902 | break; | 950 | break; |
903 | } | 951 | } |
904 | 952 | ||
905 | #ifdef USEGSLIB | ||
906 | grey_show(false); /* switch off overlay */ | ||
907 | #endif | ||
908 | rb->lcd_clear_display(); | 953 | rb->lcd_clear_display(); |
909 | } | 954 | } |
910 | while (status > PLUGIN_OTHER); | 955 | while (status > PLUGIN_OTHER); |
911 | #ifdef USEGSLIB | 956 | #ifdef USEGSLIB |
957 | grey_show(false); /* switch off overlay */ | ||
912 | rb->lcd_update(); | 958 | rb->lcd_update(); |
913 | #endif | 959 | #endif |
914 | return status; | 960 | return status; |