summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2006-03-29 10:12:39 +0000
committerChristian Gmeiner <christian.gmeiner@gmail.com>2006-03-29 10:12:39 +0000
commit47bf642002d16e4973a9775e88354b99a035187f (patch)
tree4e8fca9af7de59fd412b0725b2e00d735e560836
parent6ce466ea2c3b0a4f07f6c64e34b3be72a92c08e8 (diff)
downloadrockbox-47bf642002d16e4973a9775e88354b99a035187f.tar.gz
rockbox-47bf642002d16e4973a9775e88354b99a035187f.zip
Patch #4936 from Jonathan Gordon with a small change by me. slideshow support for JPEG viewer
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9340 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/jpeg.c267
1 files changed, 185 insertions, 82 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index eb47e142aa..c192eb632c 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -11,7 +11,7 @@
11* (This is a real mess if it has to be coded in one single C file) 11* (This is a real mess if it has to be coded in one single C file)
12* 12*
13* File scrolling addition (C) 2005 Alexander Spyridakis 13* File scrolling addition (C) 2005 Alexander Spyridakis
14* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon 14* Copyright (C) 2004 J�g Hohensohn aka [IDC]Dragon
15* Grayscale framework (C) 2004 Jens Arnold 15* Grayscale framework (C) 2004 Jens Arnold
16* Heavily borrowed from the IJG implementation (C) Thomas G. Lane 16* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
17* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org 17* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
@@ -25,6 +25,7 @@
25****************************************************************************/ 25****************************************************************************/
26 26
27#include "plugin.h" 27#include "plugin.h"
28#include "playback_control.h"
28 29
29#ifdef HAVE_LCD_BITMAP 30#ifdef HAVE_LCD_BITMAP
30#include "gray.h" 31#include "gray.h"
@@ -40,9 +41,9 @@ PLUGIN_HEADER
40#define JPEG_DOWN BUTTON_DOWN 41#define JPEG_DOWN BUTTON_DOWN
41#define JPEG_LEFT BUTTON_LEFT 42#define JPEG_LEFT BUTTON_LEFT
42#define JPEG_RIGHT BUTTON_RIGHT 43#define JPEG_RIGHT BUTTON_RIGHT
43#define JPEG_QUIT BUTTON_OFF
44#define JPEG_NEXT BUTTON_F3 44#define JPEG_NEXT BUTTON_F3
45#define JPEG_PREVIOUS BUTTON_F2 45#define JPEG_PREVIOUS BUTTON_F2
46#define JPEG_MENU BUTTON_OFF
46 47
47 48
48#elif CONFIG_KEYPAD == ONDIO_PAD 49#elif CONFIG_KEYPAD == ONDIO_PAD
@@ -53,9 +54,9 @@ PLUGIN_HEADER
53#define JPEG_DOWN BUTTON_DOWN 54#define JPEG_DOWN BUTTON_DOWN
54#define JPEG_LEFT BUTTON_LEFT 55#define JPEG_LEFT BUTTON_LEFT
55#define JPEG_RIGHT BUTTON_RIGHT 56#define JPEG_RIGHT BUTTON_RIGHT
56#define JPEG_QUIT BUTTON_OFF
57#define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT) 57#define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
58#define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT) 58#define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
59#define JPEG_MENU BUTTON_OFF
59 60
60#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 61#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
61 (CONFIG_KEYPAD == IRIVER_H300_PAD) 62 (CONFIG_KEYPAD == IRIVER_H300_PAD)
@@ -65,7 +66,6 @@ PLUGIN_HEADER
65#define JPEG_DOWN BUTTON_DOWN 66#define JPEG_DOWN BUTTON_DOWN
66#define JPEG_LEFT BUTTON_LEFT 67#define JPEG_LEFT BUTTON_LEFT
67#define JPEG_RIGHT BUTTON_RIGHT 68#define JPEG_RIGHT BUTTON_RIGHT
68#define JPEG_QUIT BUTTON_OFF
69#if (CONFIG_KEYPAD == IRIVER_H100_PAD) 69#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
70#define JPEG_NEXT BUTTON_ON 70#define JPEG_NEXT BUTTON_ON
71#define JPEG_PREVIOUS BUTTON_REC 71#define JPEG_PREVIOUS BUTTON_REC
@@ -73,6 +73,7 @@ PLUGIN_HEADER
73#define JPEG_NEXT BUTTON_REC 73#define JPEG_NEXT BUTTON_REC
74#define JPEG_PREVIOUS BUTTON_ON 74#define JPEG_PREVIOUS BUTTON_ON
75#endif 75#endif
76#define JPEG_MENU BUTTON_OFF
76 77
77#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) 78#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
78#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD 79#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
@@ -81,8 +82,10 @@ PLUGIN_HEADER
81#define JPEG_DOWN BUTTON_PLAY 82#define JPEG_DOWN BUTTON_PLAY
82#define JPEG_LEFT BUTTON_LEFT 83#define JPEG_LEFT BUTTON_LEFT
83#define JPEG_RIGHT BUTTON_RIGHT 84#define JPEG_RIGHT BUTTON_RIGHT
84#define JPEG_QUIT (BUTTON_SELECT | BUTTON_MENU) 85#define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
85#define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT) 86#define JPEG_NEXT_PRE (BUTTON_SELECT | BUTTON_RIGHT)
87#define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REL)
88#define JPEG_TOGGLE_SLIDESHOW (BUTTON_SELECT | BUTTON_RIGHT | BUTTON_REPEAT)
86#define JPEG_PREVIOUS (BUTTON_SELECT |BUTTON_LEFT) 89#define JPEG_PREVIOUS (BUTTON_SELECT |BUTTON_LEFT)
87 90
88#elif CONFIG_KEYPAD == IAUDIO_X5_PAD 91#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
@@ -93,8 +96,10 @@ PLUGIN_HEADER
93#define JPEG_DOWN BUTTON_DOWN 96#define JPEG_DOWN BUTTON_DOWN
94#define JPEG_LEFT BUTTON_LEFT 97#define JPEG_LEFT BUTTON_LEFT
95#define JPEG_RIGHT BUTTON_RIGHT 98#define JPEG_RIGHT BUTTON_RIGHT
96#define JPEG_QUIT BUTTON_POWER 99#define JPEG_MENU BUTTON_POWER
97#define JPEG_NEXT BUTTON_PLAY 100#define JPEG_NEXT_PRE BUTTON_PLAY
101#define JPEG_NEXT (BUTTON_PLAY|BUTTON_REL)
102#define JPEG_TOGGLE_SLIDESHOW (BUTTON_PLAY|BUTTON_REPEAT)
98#define JPEG_PREVIOUS BUTTON_REC 103#define JPEG_PREVIOUS BUTTON_REC
99 104
100#elif CONFIG_KEYPAD == GIGABEAT_PAD 105#elif CONFIG_KEYPAD == GIGABEAT_PAD
@@ -105,7 +110,7 @@ PLUGIN_HEADER
105#define JPEG_DOWN BUTTON_DOWN 110#define JPEG_DOWN BUTTON_DOWN
106#define JPEG_LEFT BUTTON_LEFT 111#define JPEG_LEFT BUTTON_LEFT
107#define JPEG_RIGHT BUTTON_RIGHT 112#define JPEG_RIGHT BUTTON_RIGHT
108#define JPEG_QUIT BUTTON_A 113#define JPEG_MENU BUTTON_A
109#define JPEG_NEXT (BUTTON_POWER | BUTTON_RIGHT) 114#define JPEG_NEXT (BUTTON_POWER | BUTTON_RIGHT)
110#define JPEG_PREVIOUS (BUTTON_POWER | BUTTON_LEFT) 115#define JPEG_PREVIOUS (BUTTON_POWER | BUTTON_LEFT)
111 116
@@ -126,12 +131,12 @@ PLUGIN_HEADER
126#define MAX_X_SIZE LCD_WIDTH*8 131#define MAX_X_SIZE LCD_WIDTH*8
127 132
128/* Min memory allowing us to use the plugin buffer 133/* Min memory allowing us to use the plugin buffer
129 * and thus not stopping the music 134 * and thus not stopping the music
130 * *Very* rough estimation: 135 * *Very* rough estimation:
131 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes 136 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
132 * + 20k code size = 60 000 137 * + 20k code size = 60 000
133 * + 50k min for jpeg = 120 000 138 * + 50k min for jpeg = 120 000
134 */ 139 */
135#define MIN_MEM 120000 140#define MIN_MEM 120000
136 141
137/* Headings */ 142/* Headings */
@@ -151,7 +156,8 @@ static struct plugin_api* rb;
151#define INLINE static inline 156#define INLINE static inline
152#define ENDIAN_SWAP16(n) n /* only for poor little endian machines */ 157#define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
153 158
154 159static int slideshow_enabled = false;
160static int button_timeout = HZ*5;
155 161
156/**************** begin JPEG code ********************/ 162/**************** begin JPEG code ********************/
157 163
@@ -1135,7 +1141,7 @@ void build_lut(struct jpeg* p_jpeg)
1135 1141
1136 for (i=0; i<4; i++) 1142 for (i=0; i<4; i++)
1137 p_jpeg->store_pos[i] = i; /* default ordering */ 1143 p_jpeg->store_pos[i] = i; /* default ordering */
1138 1144
1139 /* assignments for the decoding of blocks */ 1145 /* assignments for the decoding of blocks */
1140 if (p_jpeg->frameheader[0].horizontal_sampling == 2 1146 if (p_jpeg->frameheader[0].horizontal_sampling == 2
1141 && p_jpeg->frameheader[0].vertical_sampling == 1) 1147 && p_jpeg->frameheader[0].vertical_sampling == 1)
@@ -1276,7 +1282,7 @@ INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1276 pb->next_input_byte++; 1282 pb->next_input_byte++;
1277 } 1283 }
1278 pb->get_buffer = (pb->get_buffer << 8) | byte; 1284 pb->get_buffer = (pb->get_buffer << 8) | byte;
1279 1285
1280 pb->bits_left += 16; 1286 pb->bits_left += 16;
1281 } 1287 }
1282} 1288}
@@ -1570,11 +1576,11 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1570 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */ 1576 p_byte[0] += skip_mcu[0]; /* unrolled for (i=0; i<3; i++) loop */
1571 p_byte[1] += skip_mcu[1]; 1577 p_byte[1] += skip_mcu[1];
1572 p_byte[2] += skip_mcu[2]; 1578 p_byte[2] += skip_mcu[2];
1573 if (p_jpeg->restart_interval && --restart == 0) 1579 if (p_jpeg->restart_interval && --restart == 0)
1574 { /* if a restart marker is due: */ 1580 { /* if a restart marker is due: */
1575 restart = p_jpeg->restart_interval; /* count again */ 1581 restart = p_jpeg->restart_interval; /* count again */
1576 search_restart(&bs); /* align the bitstream */ 1582 search_restart(&bs); /* align the bitstream */
1577 last_dc_val[0] = last_dc_val[1] = 1583 last_dc_val[0] = last_dc_val[1] =
1578 last_dc_val[2] = 0; /* reset decoder */ 1584 last_dc_val[2] = 0; /* reset decoder */
1579 } 1585 }
1580 } /* for x */ 1586 } /* for x */
@@ -1731,12 +1737,12 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1731 1737
1732 if (ci == 0) 1738 if (ci == 0)
1733 { /* only for Y component */ 1739 { /* only for Y component */
1734 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti], 1740 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1735 skip_line); 1741 skip_line);
1736 } 1742 }
1737 } /* for blkn */ 1743 } /* for blkn */
1738 p_byte += skip_mcu; 1744 p_byte += skip_mcu;
1739 if (p_jpeg->restart_interval && --restart == 0) 1745 if (p_jpeg->restart_interval && --restart == 0)
1740 { /* if a restart marker is due: */ 1746 { /* if a restart marker is due: */
1741 restart = p_jpeg->restart_interval; /* count again */ 1747 restart = p_jpeg->restart_interval; /* count again */
1742 search_restart(&bs); /* align the bitstream */ 1748 search_restart(&bs); /* align the bitstream */
@@ -1784,11 +1790,11 @@ char print[32]; /* use a common snprintf() buffer */
1784unsigned char* buf; /* up to here currently used by image(s) */ 1790unsigned char* buf; /* up to here currently used by image(s) */
1785 1791
1786/* the remaining free part of the buffer for compressed+uncompressed images */ 1792/* the remaining free part of the buffer for compressed+uncompressed images */
1787unsigned char* buf_images; 1793unsigned char* buf_images;
1788 1794
1789int buf_size, buf_images_size; 1795int buf_size, buf_images_size;
1790/* the root of the images, hereafter are decompresed ones */ 1796/* the root of the images, hereafter are decompresed ones */
1791unsigned char* buf_root; 1797unsigned char* buf_root;
1792int root_size; 1798int root_size;
1793 1799
1794int ds, ds_min, ds_max; /* downscaling and limits */ 1800int ds, ds_min, ds_max; /* downscaling and limits */
@@ -1834,7 +1840,7 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1834 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 1840 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
1835 || (x + width <= 0) || (y + height <= 0)) 1841 || (x + width <= 0) || (y + height <= 0))
1836 return; 1842 return;
1837 1843
1838 /* clipping */ 1844 /* clipping */
1839 if (x < 0) 1845 if (x < 0)
1840 { 1846 {
@@ -1855,7 +1861,7 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1855 1861
1856 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x; 1862 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
1857 dst_end = dst + LCD_WIDTH * height; 1863 dst_end = dst + LCD_WIDTH * height;
1858 1864
1859 do 1865 do
1860 { 1866 {
1861 fb_data *dst_row = dst; 1867 fb_data *dst_row = dst;
@@ -1880,7 +1886,7 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1880 rc = RVFAC * v + ROUNDOFFS; 1886 rc = RVFAC * v + ROUNDOFFS;
1881 gc = GVFAC * v + GUFAC * u + ROUNDOFFS; 1887 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
1882 bc = BUFAC * u + ROUNDOFFS; 1888 bc = BUFAC * u + ROUNDOFFS;
1883 1889
1884 do 1890 do
1885 { 1891 {
1886 y = *ysrc++; 1892 y = *ysrc++;
@@ -1947,11 +1953,11 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1947 } 1953 }
1948 while (dst_row < row_end); 1954 while (dst_row < row_end);
1949 } 1955 }
1950 1956
1951 src_y++; 1957 src_y++;
1952 dst += LCD_WIDTH; 1958 dst += LCD_WIDTH;
1953 } 1959 }
1954 while (dst < dst_end); 1960 while (dst < dst_end);
1955} 1961}
1956#endif 1962#endif
1957 1963
@@ -1968,7 +1974,7 @@ bool jpg_ext(const char ext[])
1968 !rb->strcasecmp(ext,".jpe") || 1974 !rb->strcasecmp(ext,".jpe") ||
1969 !rb->strcasecmp(ext,".jpeg")) 1975 !rb->strcasecmp(ext,".jpeg"))
1970 return true; 1976 return true;
1971 else 1977 else
1972 return false; 1978 return false;
1973} 1979}
1974 1980
@@ -1977,9 +1983,9 @@ void get_pic_list(void)
1977{ 1983{
1978 int i; 1984 int i;
1979 long int str_len = 0; 1985 long int str_len = 0;
1980 char *pname; 1986 char *pname;
1981 tree = rb->tree_get_context(); 1987 tree = rb->tree_get_context();
1982 1988
1983#if PLUGIN_BUFFER_SIZE >= MIN_MEM 1989#if PLUGIN_BUFFER_SIZE >= MIN_MEM
1984 file_pt = rb->plugin_get_buffer(&buf_size); 1990 file_pt = rb->plugin_get_buffer(&buf_size);
1985#else 1991#else
@@ -1989,17 +1995,17 @@ void get_pic_list(void)
1989 for(i = 0; i < tree->filesindir; i++) 1995 for(i = 0; i < tree->filesindir; i++)
1990 { 1996 {
1991 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.'))) 1997 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
1992 file_pt[entries++] = &tree->name_buffer[str_len]; 1998 file_pt[entries++] = &tree->name_buffer[str_len];
1993 1999
1994 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1; 2000 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
1995 } 2001 }
1996 2002
1997 rb->qsort(file_pt, entries, sizeof(char**), compare); 2003 rb->qsort(file_pt, entries, sizeof(char**), compare);
1998 2004
1999 /* Remove path and leave only the name.*/ 2005 /* Remove path and leave only the name.*/
2000 pname = rb->strrchr(np_file,'/'); 2006 pname = rb->strrchr(np_file,'/');
2001 pname++; 2007 pname++;
2002 2008
2003 /* Find Selected File. */ 2009 /* Find Selected File. */
2004 for(i = 0; i < entries; i++) 2010 for(i = 0; i < entries; i++)
2005 if(!rb->strcmp(file_pt[i], pname)) 2011 if(!rb->strcmp(file_pt[i], pname))
@@ -2010,7 +2016,7 @@ int change_filename(int direct)
2010{ 2016{
2011 int count = 0; 2017 int count = 0;
2012 direction = direct; 2018 direction = direct;
2013 2019
2014 if(direct == DIR_PREV) 2020 if(direct == DIR_PREV)
2015 { 2021 {
2016 do 2022 do
@@ -2021,21 +2027,21 @@ int change_filename(int direct)
2021 else 2027 else
2022 curfile--; 2028 curfile--;
2023 }while(file_pt[curfile] == '\0' && count < entries); 2029 }while(file_pt[curfile] == '\0' && count < entries);
2024 /* we "erase" the file name if we encounter 2030 /* we "erase" the file name if we encounter
2025 * a non-supported file, so skip it now */ 2031 * a non-supported file, so skip it now */
2026 } 2032 }
2027 else /* DIR_NEXT/DIR_NONE */ 2033 else /* DIR_NEXT/DIR_NONE */
2028 { 2034 {
2029 do 2035 do
2030 { 2036 {
2031 count++; 2037 count++;
2032 if(curfile == entries - 1) 2038 if(curfile == entries - 1)
2033 curfile = 0; 2039 curfile = 0;
2034 else 2040 else
2035 curfile++; 2041 curfile++;
2036 }while(file_pt[curfile] == '\0' && count < entries); 2042 }while(file_pt[curfile] == '\0' && count < entries);
2037 } 2043 }
2038 2044
2039 if(count == entries && file_pt[curfile] == '\0') 2045 if(count == entries && file_pt[curfile] == '\0')
2040 { 2046 {
2041 rb->splash(HZ,true,"No supported files"); 2047 rb->splash(HZ,true,"No supported files");
@@ -2049,7 +2055,7 @@ int change_filename(int direct)
2049 else 2055 else
2050 rb->strcpy(np_file, tree->currdir); 2056 rb->strcpy(np_file, tree->currdir);
2051 2057
2052 rb->strcat(np_file, file_pt[curfile]); 2058 rb->strcat(np_file, file_pt[curfile]);
2053 2059
2054 return PLUGIN_OTHER; 2060 return PLUGIN_OTHER;
2055} 2061}
@@ -2060,15 +2066,85 @@ void cleanup(void *parameter)
2060 (void)parameter; 2066 (void)parameter;
2061#ifdef USEGSLIB 2067#ifdef USEGSLIB
2062 gray_show(false); 2068 gray_show(false);
2063#endif 2069#endif
2064} 2070}
2065 2071
2066#define VSCROLL (LCD_HEIGHT/8) 2072#define VSCROLL (LCD_HEIGHT/8)
2067#define HSCROLL (LCD_WIDTH/10) 2073#define HSCROLL (LCD_WIDTH/10)
2068 2074
2069#define ZOOM_IN 100 /* return codes for below function */ 2075#define ZOOM_IN 100 /* return codes for below function */
2070#define ZOOM_OUT 101 2076#define ZOOM_OUT 101
2071 2077
2078int show_menu() /* return 1 to quit */
2079{
2080 int m;
2081 int result;
2082 static const struct menu_item items[] = {
2083 { "Quit", NULL },
2084 { "Toggle Slideshow Mode", NULL },
2085 { "Change Slideshow Timeout", NULL },
2086 { "Show Playback Menu", NULL },
2087 { "Return", NULL },
2088 };
2089 static const struct opt_items slideshow[2] = {
2090 {"Disable",NULL},
2091 {"Enable",NULL},
2092 };
2093 static const struct opt_items timeout[12] = {
2094 { "1 second", NULL },
2095 { "2 seconds", NULL },
2096 { "3 seconds", NULL },
2097 { "4 seconds", NULL },
2098 { "5 seconds", NULL },
2099 { "6 seconds", NULL },
2100 { "7 seconds", NULL },
2101 { "8 seconds", NULL },
2102 { "9 seconds", NULL },
2103 { "10 seconds", NULL },
2104 { "15 seconds", NULL },
2105 { "20 seconds", NULL },
2106 };
2107 m = rb->menu_init(items, sizeof(items) / sizeof(*items),
2108 NULL, NULL, NULL, NULL);
2109 result=rb->menu_show(m);
2110 switch (result)
2111 {
2112 case 0:
2113 rb->menu_exit(m);
2114 return 1;
2115 break;
2116 case 1: //toggle slideshow
2117 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
2118 slideshow , 2, NULL);
2119 break;
2120 case 2:
2121 switch (button_timeout/HZ)
2122 {
2123 case 10: result = 9; break;
2124 case 15: result = 10; break;
2125 case 20: result = 11; break;
2126 default: result = (button_timeout/HZ)-1; break;
2127 }
2128 rb->set_option("Slideshow Timeout", &result, INT,
2129 timeout , 12, NULL);
2130 switch (result)
2131 {
2132 case 9: button_timeout = 10*HZ; break;
2133 case 10: button_timeout = 15*HZ; break;
2134 case 11: button_timeout = 20*HZ; break;
2135 default: button_timeout = (result+1)*HZ; break;
2136 }
2137 break;
2138 case 3:
2139 playback_control(rb);
2140 break;
2141 case 4:
2142 MYLCD(clear_display)();
2143 break;
2144 }
2145 rb->menu_exit(m);
2146 return 0;
2147}
2072/* interactively scroll around the image */ 2148/* interactively scroll around the image */
2073int scroll_bmp(struct t_disp* pdisp) 2149int scroll_bmp(struct t_disp* pdisp)
2074{ 2150{
@@ -2079,13 +2155,15 @@ int scroll_bmp(struct t_disp* pdisp)
2079 int button; 2155 int button;
2080 int move; 2156 int move;
2081 2157
2082 button = rb->button_get(true); 2158 if (slideshow_enabled)
2083 2159 button = rb->button_get_w_tmo(button_timeout);
2160 else button = rb->button_get(true);
2161
2084 switch(button) 2162 switch(button)
2085 { 2163 {
2086 case JPEG_LEFT: 2164 case JPEG_LEFT:
2087 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) 2165 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2088 return change_filename(DIR_PREV); 2166 return change_filename(DIR_PREV);
2089 case JPEG_LEFT | BUTTON_REPEAT: 2167 case JPEG_LEFT | BUTTON_REPEAT:
2090 move = MIN(HSCROLL, pdisp->x); 2168 move = MIN(HSCROLL, pdisp->x);
2091 if (move > 0) 2169 if (move > 0)
@@ -2094,7 +2172,7 @@ int scroll_bmp(struct t_disp* pdisp)
2094 pdisp->x -= move; 2172 pdisp->x -= move;
2095#ifdef HAVE_LCD_COLOR 2173#ifdef HAVE_LCD_COLOR
2096 yuv_bitmap_part( 2174 yuv_bitmap_part(
2097 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, 2175 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2098 pdisp->x, pdisp->y, pdisp->stride, 2176 pdisp->x, pdisp->y, pdisp->stride,
2099 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ 2177 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
2100 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ 2178 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
@@ -2110,7 +2188,7 @@ int scroll_bmp(struct t_disp* pdisp)
2110 2188
2111 case JPEG_RIGHT: 2189 case JPEG_RIGHT:
2112 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) 2190 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2113 return change_filename(DIR_NEXT); 2191 return change_filename(DIR_NEXT);
2114 case JPEG_RIGHT | BUTTON_REPEAT: 2192 case JPEG_RIGHT | BUTTON_REPEAT:
2115 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); 2193 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
2116 if (move > 0) 2194 if (move > 0)
@@ -2180,17 +2258,26 @@ int scroll_bmp(struct t_disp* pdisp)
2180 MYLCD_UPDATE(); 2258 MYLCD_UPDATE();
2181 } 2259 }
2182 break; 2260 break;
2183 2261 case BUTTON_NONE:
2262 if (!slideshow_enabled)
2263 break;
2264 if (entries > 0)
2265 return change_filename(DIR_NEXT);
2266 break;
2184 case JPEG_NEXT: 2267 case JPEG_NEXT:
2268#ifdef JPEG_NEXT_PRE
2269 if (lastbutton != JPEG_NEXT_PRE)
2270 break;
2271#endif
2185 if (entries > 0) 2272 if (entries > 0)
2186 return change_filename(DIR_NEXT); 2273 return change_filename(DIR_NEXT);
2187 break; 2274 break;
2188 2275
2189 case JPEG_PREVIOUS: 2276 case JPEG_PREVIOUS:
2190 if (entries > 0) 2277 if (entries > 0)
2191 return change_filename(DIR_PREV); 2278 return change_filename(DIR_PREV);
2192 break; 2279 break;
2193 2280
2194 case JPEG_ZOOM_IN: 2281 case JPEG_ZOOM_IN:
2195#ifdef JPEG_ZOOM_PRE 2282#ifdef JPEG_ZOOM_PRE
2196 if (lastbutton != JPEG_ZOOM_PRE) 2283 if (lastbutton != JPEG_ZOOM_PRE)
@@ -2207,9 +2294,25 @@ int scroll_bmp(struct t_disp* pdisp)
2207 return ZOOM_OUT; 2294 return ZOOM_OUT;
2208 break; 2295 break;
2209 2296
2210 case JPEG_QUIT: 2297 case JPEG_MENU:
2211 return PLUGIN_OK; 2298#ifdef USEGSLIB
2212 2299 gray_show(false); /* switch off grayscale overlay */
2300#endif
2301 if (show_menu() == 1)
2302 return PLUGIN_OK;
2303#ifdef USEGSLIB
2304 gray_show(true); /* switch on grayscale overlay */
2305#else
2306 yuv_bitmap_part(
2307 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2308 pdisp->x, pdisp->y, pdisp->stride,
2309 MAX(0, (LCD_WIDTH - pdisp->width) / 2),
2310 MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
2311 MIN(LCD_WIDTH, pdisp->width),
2312 MIN(LCD_HEIGHT, pdisp->height));
2313 MYLCD_UPDATE();
2314#endif
2315 break;
2213 default: 2316 default:
2214 if (rb->default_event_handler_ex(button, cleanup, NULL) 2317 if (rb->default_event_handler_ex(button, cleanup, NULL)
2215 == SYS_USB_CONNECTED) 2318 == SYS_USB_CONNECTED)
@@ -2256,13 +2359,13 @@ int jpegmem(struct jpeg *p_jpg, int ds)
2256int min_downscale(struct jpeg *p_jpg, int bufsize) 2359int min_downscale(struct jpeg *p_jpg, int bufsize)
2257{ 2360{
2258 int downscale = 8; 2361 int downscale = 8;
2259 2362
2260 if (jpegmem(p_jpg, 8) > bufsize) 2363 if (jpegmem(p_jpg, 8) > bufsize)
2261 return 0; /* error, too large, even 1:8 doesn't fit */ 2364 return 0; /* error, too large, even 1:8 doesn't fit */
2262 2365
2263 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize) 2366 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
2264 downscale /= 2; 2367 downscale /= 2;
2265 2368
2266 return downscale; 2369 return downscale;
2267} 2370}
2268 2371
@@ -2271,13 +2374,13 @@ int min_downscale(struct jpeg *p_jpg, int bufsize)
2271int max_downscale(struct jpeg *p_jpg) 2374int max_downscale(struct jpeg *p_jpg)
2272{ 2375{
2273 int downscale = 1; 2376 int downscale = 1;
2274 2377
2275 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale 2378 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
2276 || p_jpg->y_size > LCD_HEIGHT*downscale)) 2379 || p_jpg->y_size > LCD_HEIGHT*downscale))
2277 { 2380 {
2278 downscale *= 2; 2381 downscale *= 2;
2279 } 2382 }
2280 2383
2281 return downscale; 2384 return downscale;
2282} 2385}
2283 2386
@@ -2309,7 +2412,7 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2309 buf = buf_root; /* start again from the beginning of the buffer */ 2412 buf = buf_root; /* start again from the beginning of the buffer */
2310 buf_size = root_size; 2413 buf_size = root_size;
2311 } 2414 }
2312 2415
2313#ifdef HAVE_LCD_COLOR 2416#ifdef HAVE_LCD_COLOR
2314 if (p_jpg->blocks > 1) /* colour jpeg */ 2417 if (p_jpg->blocks > 1) /* colour jpeg */
2315 { 2418 {
@@ -2416,7 +2519,7 @@ int load_and_show(char* filename)
2416 fd = rb->open(filename, O_RDONLY); 2519 fd = rb->open(filename, O_RDONLY);
2417 if (fd < 0) 2520 if (fd < 0)
2418 { 2521 {
2419 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd); 2522 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
2420 rb->splash(HZ, true, print); 2523 rb->splash(HZ, true, print);
2421 return PLUGIN_ERROR; 2524 return PLUGIN_ERROR;
2422 } 2525 }
@@ -2430,8 +2533,8 @@ int load_and_show(char* filename)
2430 2533
2431 buf_root = buf; /* we can start the decompressed images behind it */ 2534 buf_root = buf; /* we can start the decompressed images behind it */
2432 root_size = buf_size; 2535 root_size = buf_size;
2433 2536
2434 if (buf_size <= 0) 2537 if (buf_size <= 0)
2435 { 2538 {
2436#if PLUGIN_BUFFER_SIZE >= MIN_MEM 2539#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2437 if(plug_buf) 2540 if(plug_buf)
@@ -2448,9 +2551,9 @@ int load_and_show(char* filename)
2448 rb->lcd_puts(0,4,"Off: Quit."); 2551 rb->lcd_puts(0,4,"Off: Quit.");
2449 rb->lcd_update(); 2552 rb->lcd_update();
2450 rb->lcd_setfont(FONT_UI); 2553 rb->lcd_setfont(FONT_UI);
2451 2554
2452 rb->button_clear_queue(); 2555 rb->button_clear_queue();
2453 2556
2454 while (1) 2557 while (1)
2455 { 2558 {
2456 int button = rb->button_get(true); 2559 int button = rb->button_get(true);
@@ -2458,14 +2561,14 @@ int load_and_show(char* filename)
2458 { 2561 {
2459 case JPEG_ZOOM_IN: 2562 case JPEG_ZOOM_IN:
2460 plug_buf = false; 2563 plug_buf = false;
2461 buf_images = 2564 buf_images =
2462 rb->plugin_get_audio_buffer(&buf_images_size); 2565 rb->plugin_get_audio_buffer(&buf_images_size);
2463 /*try again this file, now using the audio buffer */ 2566 /*try again this file, now using the audio buffer */
2464 return PLUGIN_OTHER; 2567 return PLUGIN_OTHER;
2465 2568
2466 case JPEG_QUIT: 2569 case JPEG_MENU:
2467 return PLUGIN_OK; 2570 return PLUGIN_OK;
2468 2571
2469 case JPEG_LEFT: 2572 case JPEG_LEFT:
2470 if(entries>1) 2573 if(entries>1)
2471 { 2574 {
@@ -2473,31 +2576,31 @@ int load_and_show(char* filename)
2473 return change_filename(DIR_PREV); 2576 return change_filename(DIR_PREV);
2474 } 2577 }
2475 break; 2578 break;
2476 2579
2477 case JPEG_RIGHT: 2580 case JPEG_RIGHT:
2478 if(entries>1) 2581 if(entries>1)
2479 { 2582 {
2480 rb->lcd_clear_display(); 2583 rb->lcd_clear_display();
2481 return change_filename(DIR_NEXT); 2584 return change_filename(DIR_NEXT);
2482 } 2585 }
2483 break; 2586 break;
2484 default: 2587 default:
2485 if(rb->default_event_handler_ex(button, cleanup, NULL) 2588 if(rb->default_event_handler_ex(button, cleanup, NULL)
2486 == SYS_USB_CONNECTED) 2589 == SYS_USB_CONNECTED)
2487 return PLUGIN_USB_CONNECTED; 2590 return PLUGIN_USB_CONNECTED;
2488 2591
2489 } 2592 }
2490 } 2593 }
2491 } 2594 }
2492 else 2595 else
2493#endif 2596#endif
2494 { 2597 {
2495 rb->splash(HZ, true, "Out of Memory"); 2598 rb->splash(HZ, true, "Out of Memory");
2496 rb->close(fd); 2599 rb->close(fd);
2497 return PLUGIN_ERROR; 2600 return PLUGIN_ERROR;
2498 } 2601 }
2499 } 2602 }
2500 2603
2501#ifdef HAVE_LCD_COLOR 2604#ifdef HAVE_LCD_COLOR
2502 rb->lcd_set_foreground(LCD_WHITE); 2605 rb->lcd_set_foreground(LCD_WHITE);
2503 rb->lcd_set_background(LCD_BLACK); 2606 rb->lcd_set_background(LCD_BLACK);
@@ -2507,7 +2610,7 @@ int load_and_show(char* filename)
2507 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1); 2610 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
2508 rb->lcd_puts(0, 0, print); 2611 rb->lcd_puts(0, 0, print);
2509 rb->lcd_update(); 2612 rb->lcd_update();
2510 2613
2511 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize); 2614 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
2512 rb->lcd_puts(0, 1, print); 2615 rb->lcd_puts(0, 1, print);
2513 rb->lcd_update(); 2616 rb->lcd_update();
@@ -2518,20 +2621,20 @@ int load_and_show(char* filename)
2518 rb->snprintf(print, sizeof(print), "decoding markers"); 2621 rb->snprintf(print, sizeof(print), "decoding markers");
2519 rb->lcd_puts(0, 2, print); 2622 rb->lcd_puts(0, 2, print);
2520 rb->lcd_update(); 2623 rb->lcd_update();
2521 2624
2522 2625
2523 2626
2524 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ 2627 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
2525 /* process markers, unstuffing */ 2628 /* process markers, unstuffing */
2526 status = process_markers(buf_jpeg, filesize, &jpg); 2629 status = process_markers(buf_jpeg, filesize, &jpg);
2527 2630
2528 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0)) 2631 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
2529 { /* bad format or minimum components not contained */ 2632 { /* bad format or minimum components not contained */
2530 rb->splash(HZ, true, "unsupported %d", status); 2633 rb->splash(HZ, true, "unsupported %d", status);
2531 file_pt[curfile] = '\0'; 2634 file_pt[curfile] = '\0';
2532 return change_filename(direction); 2635 return change_filename(direction);
2533 } 2636 }
2534 2637
2535 if (!(status & DHT)) /* if no Huffman table present: */ 2638 if (!(status & DHT)) /* if no Huffman table present: */
2536 default_huff_tbl(&jpg); /* use default */ 2639 default_huff_tbl(&jpg); /* use default */
2537 build_lut(&jpg); /* derive Huffman and other lookup-tables */ 2640 build_lut(&jpg); /* derive Huffman and other lookup-tables */
@@ -2548,7 +2651,7 @@ int load_and_show(char* filename)
2548 file_pt[curfile] = '\0'; 2651 file_pt[curfile] = '\0';
2549 return change_filename(direction); 2652 return change_filename(direction);
2550 } 2653 }
2551 2654
2552 ds = ds_max; /* initials setting */ 2655 ds = ds_max; /* initials setting */
2553 cx = jpg.x_size/ds/2; /* center the view */ 2656 cx = jpg.x_size/ds/2; /* center the view */
2554 cy = jpg.y_size/ds/2; 2657 cy = jpg.y_size/ds/2;
@@ -2640,7 +2743,7 @@ int load_and_show(char* filename)
2640enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 2743enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2641{ 2744{
2642 rb = api; 2745 rb = api;
2643 2746
2644 int condition; 2747 int condition;
2645#ifdef USEGSLIB 2748#ifdef USEGSLIB
2646 int grayscales; 2749 int grayscales;
@@ -2648,12 +2751,12 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2648#endif 2751#endif
2649 2752
2650 rb->strcpy(np_file, parameter); 2753 rb->strcpy(np_file, parameter);
2651 get_pic_list(); 2754 get_pic_list();
2652 2755
2653#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR) 2756#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
2654#if CONFIG_CODEC == SWCODEC 2757#if CONFIG_CODEC == SWCODEC
2655 if(rb->pcm_is_playing()) 2758 if(rb->pcm_is_playing())
2656#else 2759#else
2657 if(rb->mp3_is_playing()) 2760 if(rb->mp3_is_playing())
2658#endif 2761#endif
2659 { 2762 {
@@ -2686,7 +2789,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2686#endif 2789#endif
2687 2790
2688 buf_images = buf; buf_images_size = buf_size; 2791 buf_images = buf; buf_images_size = buf_size;
2689 2792
2690 do 2793 do
2691 { 2794 {
2692 condition = load_and_show(np_file); 2795 condition = load_and_show(np_file);
@@ -2696,7 +2799,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2696#ifdef USEGSLIB 2799#ifdef USEGSLIB
2697 gray_release(); /* deinitialize */ 2800 gray_release(); /* deinitialize */
2698#endif 2801#endif
2699 2802
2700 return condition; 2803 return condition;
2701} 2804}
2702 2805