summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHristo Kovachev <bger@rockbox.org>2006-02-18 20:51:34 +0000
committerHristo Kovachev <bger@rockbox.org>2006-02-18 20:51:34 +0000
commitcc6f37b8d8aeaeeacdac0babdae1abeee846d0d1 (patch)
tree60b2168c162e8f54866eef6d986e95cdcbe01b4d
parent3ba5a0b24a72b8b694be5ae2ef224aef18136dd1 (diff)
downloadrockbox-cc6f37b8d8aeaeeacdac0babdae1abeee846d0d1.tar.gz
rockbox-cc6f37b8d8aeaeeacdac0babdae1abeee846d0d1.zip
"Next/Previous jpeg from within the JPEG viewer" addition by Alexander Spyridakis, modified a bit by me
Also tries to use the plugin buffer instead of the audio buffer on the platforms with more than 130kb plugin buffer size (thus not stopping the music playback). If the free buffer from the plugin buffer is not enough, asks for stopping playback. Needs a little more work, but seems stable as it is. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8728 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/jpeg.c407
-rw-r--r--apps/plugins/searchengine/dbinterface.c8
-rw-r--r--apps/plugins/searchengine/dbinterface.h4
5 files changed, 342 insertions, 86 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 6f3585b130..c9fb0ac8f5 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -400,7 +400,7 @@ static const struct plugin_api rockbox_api = {
400 400
401 /* new stuff at the end, sort into place next time 401 /* new stuff at the end, sort into place next time
402 the API gets incompatible */ 402 the API gets incompatible */
403 403 tree_get_context,
404}; 404};
405 405
406int plugin_load(const char* plugin, void* parameter) 406int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 286ca4087f..7c35902248 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -45,6 +45,7 @@
45#include "mpeg.h" 45#include "mpeg.h"
46#include "audio.h" 46#include "audio.h"
47#include "mp3_playback.h" 47#include "mp3_playback.h"
48#include "tree.h"
48#ifdef RB_PROFILE 49#ifdef RB_PROFILE
49#include "profile.h" 50#include "profile.h"
50#endif 51#endif
@@ -97,7 +98,7 @@
97#define PLUGIN_MAGIC 0x526F634B /* RocK */ 98#define PLUGIN_MAGIC 0x526F634B /* RocK */
98 99
99/* increase this every time the api struct changes */ 100/* increase this every time the api struct changes */
100#define PLUGIN_API_VERSION 7 101#define PLUGIN_API_VERSION 8
101 102
102/* update this to latest version if a change to the api struct breaks 103/* update this to latest version if a change to the api struct breaks
103 backwards compatibility (and please take the opportunity to sort in any 104 backwards compatibility (and please take the opportunity to sort in any
@@ -466,7 +467,9 @@ struct plugin_api {
466 467
467 /* new stuff at the end, sort into place next time 468 /* new stuff at the end, sort into place next time
468 the API gets incompatible */ 469 the API gets incompatible */
469 470
471 struct tree_context* (*tree_get_context)(void);
472
470}; 473};
471 474
472/* plugin header */ 475/* plugin header */
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index e11680f8d6..78eb98ff80 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -10,10 +10,11 @@
10* JPEG image viewer 10* JPEG image viewer
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* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon 14* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
14* Grayscale framework (c) 2004 Jens Arnold 15* Grayscale framework (C) 2004 Jens Arnold
15* Heavily borrowed from the IJG implementation (c) Thomas G. Lane 16* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16* Small & fast downscaling IDCT (c) 2002 by Guido Vollbeding JPEGclub.org 17* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
17* 18*
18* All files in this archive are subject to the GNU General Public License. 19* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement. 20* See the file COPYING in the source tree root for full license agreement.
@@ -40,16 +41,21 @@ PLUGIN_HEADER
40#define JPEG_LEFT BUTTON_LEFT 41#define JPEG_LEFT BUTTON_LEFT
41#define JPEG_RIGHT BUTTON_RIGHT 42#define JPEG_RIGHT BUTTON_RIGHT
42#define JPEG_QUIT BUTTON_OFF 43#define JPEG_QUIT BUTTON_OFF
44#define JPEG_NEXT BUTTON_F3
45#define JPEG_PREVIOUS BUTTON_F2
46
43 47
44#elif CONFIG_KEYPAD == ONDIO_PAD 48#elif CONFIG_KEYPAD == ONDIO_PAD
45#define JPEG_ZOOM_PRE BUTTON_MENU 49#define JPEG_ZOOM_PRE BUTTON_MENU
46#define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL) 50#define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
47#define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_REPEAT) 51#define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
48#define JPEG_UP BUTTON_UP 52#define JPEG_UP BUTTON_UP
49#define JPEG_DOWN BUTTON_DOWN 53#define JPEG_DOWN BUTTON_DOWN
50#define JPEG_LEFT BUTTON_LEFT 54#define JPEG_LEFT BUTTON_LEFT
51#define JPEG_RIGHT BUTTON_RIGHT 55#define JPEG_RIGHT BUTTON_RIGHT
52#define JPEG_QUIT BUTTON_OFF 56#define JPEG_QUIT BUTTON_OFF
57#define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
58#define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
53 59
54#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 60#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
55 (CONFIG_KEYPAD == IRIVER_H300_PAD) 61 (CONFIG_KEYPAD == IRIVER_H300_PAD)
@@ -60,6 +66,13 @@ PLUGIN_HEADER
60#define JPEG_LEFT BUTTON_LEFT 66#define JPEG_LEFT BUTTON_LEFT
61#define JPEG_RIGHT BUTTON_RIGHT 67#define JPEG_RIGHT BUTTON_RIGHT
62#define JPEG_QUIT BUTTON_OFF 68#define JPEG_QUIT BUTTON_OFF
69#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
70#define JPEG_NEXT BUTTON_ON
71#define JPEG_PREVIOUS BUTTON_REC
72#else
73#define JPEG_NEXT BUTTON_REC
74#define JPEG_PREVIOUS BUTTON_ON
75#endif
63 76
64#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) 77#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
65#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD 78#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
@@ -68,7 +81,9 @@ PLUGIN_HEADER
68#define JPEG_DOWN BUTTON_PLAY 81#define JPEG_DOWN BUTTON_PLAY
69#define JPEG_LEFT BUTTON_LEFT 82#define JPEG_LEFT BUTTON_LEFT
70#define JPEG_RIGHT BUTTON_RIGHT 83#define JPEG_RIGHT BUTTON_RIGHT
71#define JPEG_QUIT BUTTON_SELECT 84#define JPEG_QUIT (BUTTON_SELECT | BUTTON_MENU)
85#define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
86#define JPEG_PREVIOUS (BUTTON_SELECT |BUTTON_LEFT)
72 87
73#elif CONFIG_KEYPAD == IAUDIO_X5_PAD 88#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
74#define JPEG_ZOOM_IN_PRE BUTTON_MENU 89#define JPEG_ZOOM_IN_PRE BUTTON_MENU
@@ -79,6 +94,9 @@ PLUGIN_HEADER
79#define JPEG_LEFT BUTTON_LEFT 94#define JPEG_LEFT BUTTON_LEFT
80#define JPEG_RIGHT BUTTON_RIGHT 95#define JPEG_RIGHT BUTTON_RIGHT
81#define JPEG_QUIT BUTTON_POWER 96#define JPEG_QUIT BUTTON_POWER
97#define JPEG_NEXT BUTTON_PLAY
98#define JPEG_PREVIOUS BUTTON_REC
99
82#endif 100#endif
83 101
84/* different graphics libraries */ 102/* different graphics libraries */
@@ -93,6 +111,24 @@ PLUGIN_HEADER
93#define MYXLCD(fn) xlcd_ ## fn 111#define MYXLCD(fn) xlcd_ ## fn
94#endif 112#endif
95 113
114#define MAX_X_SIZE LCD_WIDTH*8
115
116/* Min memory allowing us to use the plugin buffer
117 * and thus not stopping the music
118 * *Very* rough estimation:
119 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
120 * + 20k code size = 60 000
121 * + 50k min for jpeg = 120 000
122 */
123#define MIN_MEM 120000
124
125/* Headings */
126#define DIR_PREV 1
127#define DIR_NEXT -1
128#define DIR_NONE 0
129
130#define PLUGIN_OTHER 10 /* State code for output with return. */
131
96/******************************* Globals ***********************************/ 132/******************************* Globals ***********************************/
97 133
98static struct plugin_api* rb; 134static struct plugin_api* rb;
@@ -825,7 +861,7 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
825 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; 861 p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
826 } 862 }
827 } /* while */ 863 } /* while */
828 p_src = p_temp+marker_size - 2; // skip possible residue 864 p_src = p_temp+marker_size - 2; /* skip possible residue */
829 } 865 }
830 break; 866 break;
831 867
@@ -1757,7 +1793,6 @@ struct t_disp
1757 int x, y; 1793 int x, y;
1758}; 1794};
1759 1795
1760
1761/************************* Globals ***************************/ 1796/************************* Globals ***************************/
1762 1797
1763/* decompressed image in the possible sizes (1,2,4,8), wasting the other */ 1798/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
@@ -1766,10 +1801,30 @@ struct t_disp disp[9];
1766/* my memory pool (from the mp3 buffer) */ 1801/* my memory pool (from the mp3 buffer) */
1767char print[32]; /* use a common snprintf() buffer */ 1802char print[32]; /* use a common snprintf() buffer */
1768unsigned char* buf; /* up to here currently used by image(s) */ 1803unsigned char* buf; /* up to here currently used by image(s) */
1769int buf_size; 1804
1770unsigned char* buf_root; /* the root of the images */ 1805/* the remaining free part of the buffer for compressed+uncompressed images */
1806unsigned char* buf_images;
1807
1808int buf_size, buf_images_size;
1809/* the root of the images, hereafter are decompresed ones */
1810unsigned char* buf_root;
1771int root_size; 1811int root_size;
1772 1812
1813int ds, ds_min, ds_max; /* downscaling and limits */
1814static struct jpeg jpg; /* too large for stack */
1815
1816static struct tree_context *tree;
1817
1818/* the current full file name */
1819static char np_file[MAX_PATH];
1820int curfile = 0, direction = DIR_NONE, entries = 0;
1821
1822/* list of the jpeg files */
1823char **file_pt;
1824/* are we using the plugin buffer or the audio buffer? */
1825bool plug_buf = false;
1826
1827
1773/************************* Implementation ***************************/ 1828/************************* Implementation ***************************/
1774 1829
1775#ifdef HAVE_LCD_COLOR 1830#ifdef HAVE_LCD_COLOR
@@ -1919,6 +1974,105 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1919} 1974}
1920#endif 1975#endif
1921 1976
1977
1978/* support function for qsort() */
1979static int compare(const void* p1, const void* p2)
1980{
1981 return rb->strcasecmp(*((char **)p1), *((char **)p2));
1982}
1983
1984bool jpg_ext(const char ext[])
1985{
1986 if(!rb->strcasecmp(ext,".jpg") ||
1987 !rb->strcasecmp(ext,".jpe") ||
1988 !rb->strcasecmp(ext,".jpeg"))
1989 return true;
1990 else
1991 return false;
1992}
1993
1994/*Read directory contents for scrolling. */
1995void get_pic_list(void)
1996{
1997 int i;
1998 long int str_len = 0;
1999 char *pname;
2000 tree = rb->tree_get_context();
2001
2002#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2003 file_pt = rb->plugin_get_buffer(&buf_size);
2004#else
2005 file_pt = rb->plugin_get_audio_buffer(&buf_size);
2006#endif
2007
2008 for(i = 0; i < tree->filesindir; i++)
2009 {
2010 if(jpg_ext(rb->strrchr(&tree->name_buffer[str_len],'.')))
2011 file_pt[entries++] = &tree->name_buffer[str_len];
2012
2013 str_len += rb->strlen(&tree->name_buffer[str_len]) + 1;
2014 }
2015
2016 rb->qsort(file_pt, entries, sizeof(char**), compare);
2017
2018 /* Remove path and leave only the name.*/
2019 pname = rb->strrchr(np_file,'/');
2020 pname++;
2021
2022 /* Find Selected File. */
2023 for(i = 0; i < entries; i++)
2024 if(!rb->strcmp(file_pt[i], pname))
2025 curfile = i;
2026}
2027
2028int change_filename(int direct)
2029{
2030 int count = 0;
2031 direction = direct;
2032
2033 if(direct == DIR_PREV)
2034 {
2035 do
2036 {
2037 count++;
2038 if(curfile == 0)
2039 curfile = entries - 1;
2040 else
2041 curfile--;
2042 }while(file_pt[curfile] == '\0' && count < entries);
2043 /* we "erase" the file name if we encounter
2044 * a non-supported file, so skip it now */
2045 }
2046 else /* DIR_NEXT/DIR_NONE */
2047 {
2048 do
2049 {
2050 count++;
2051 if(curfile == entries - 1)
2052 curfile = 0;
2053 else
2054 curfile++;
2055 }while(file_pt[curfile] == '\0' && count < entries);
2056 }
2057
2058 if(count == entries && file_pt[curfile] == '\0')
2059 {
2060 rb->splash(HZ,true,"No supported files");
2061 return PLUGIN_ERROR;
2062 }
2063 if(rb->strlen(tree->currdir) > 1)
2064 {
2065 rb->strcpy(np_file, tree->currdir);
2066 rb->strcat(np_file, "/");
2067 }
2068 else
2069 rb->strcpy(np_file, tree->currdir);
2070
2071 rb->strcat(np_file, file_pt[curfile]);
2072
2073 return PLUGIN_OTHER;
2074}
2075
1922/* switch off overlay, for handling SYS_ events */ 2076/* switch off overlay, for handling SYS_ events */
1923void cleanup(void *parameter) 2077void cleanup(void *parameter)
1924{ 2078{
@@ -1931,7 +2085,7 @@ void cleanup(void *parameter)
1931#define VSCROLL (LCD_HEIGHT/8) 2085#define VSCROLL (LCD_HEIGHT/8)
1932#define HSCROLL (LCD_WIDTH/10) 2086#define HSCROLL (LCD_WIDTH/10)
1933 2087
1934#define ZOOM_IN 100 // return codes for below function 2088#define ZOOM_IN 100 /* return codes for below function */
1935#define ZOOM_OUT 101 2089#define ZOOM_OUT 101
1936 2090
1937/* interactively scroll around the image */ 2091/* interactively scroll around the image */
@@ -1952,6 +2106,8 @@ int scroll_bmp(struct t_disp* pdisp)
1952 switch(button) 2106 switch(button)
1953 { 2107 {
1954 case JPEG_LEFT: 2108 case JPEG_LEFT:
2109 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2110 return change_filename(DIR_PREV);
1955 case JPEG_LEFT | BUTTON_REPEAT: 2111 case JPEG_LEFT | BUTTON_REPEAT:
1956 move = MIN(HSCROLL, pdisp->x); 2112 move = MIN(HSCROLL, pdisp->x);
1957 if (move > 0) 2113 if (move > 0)
@@ -1975,6 +2131,8 @@ int scroll_bmp(struct t_disp* pdisp)
1975 break; 2131 break;
1976 2132
1977 case JPEG_RIGHT: 2133 case JPEG_RIGHT:
2134 if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE)
2135 return change_filename(DIR_NEXT);
1978 case JPEG_RIGHT | BUTTON_REPEAT: 2136 case JPEG_RIGHT | BUTTON_REPEAT:
1979 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); 2137 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
1980 if (move > 0) 2138 if (move > 0)
@@ -2044,7 +2202,17 @@ int scroll_bmp(struct t_disp* pdisp)
2044 MYLCD_UPDATE(); 2202 MYLCD_UPDATE();
2045 } 2203 }
2046 break; 2204 break;
2047 2205
2206 case JPEG_NEXT:
2207 if (entries > 0)
2208 return change_filename(DIR_NEXT);
2209 break;
2210
2211 case JPEG_PREVIOUS:
2212 if (entries > 0)
2213 return change_filename(DIR_PREV);
2214 break;
2215
2048 case JPEG_ZOOM_IN: 2216 case JPEG_ZOOM_IN:
2049#ifdef JPEG_ZOOM_PRE 2217#ifdef JPEG_ZOOM_PRE
2050 if (lastbutton != JPEG_ZOOM_PRE) 2218 if (lastbutton != JPEG_ZOOM_PRE)
@@ -2101,16 +2269,6 @@ void cb_progess(int current, int total)
2101 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); 2269 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
2102} 2270}
2103 2271
2104/* helper to align a buffer to a given power of two */
2105void align(unsigned char** ppbuf, int* plen, int align)
2106{
2107 unsigned int orig = (unsigned int)*ppbuf;
2108 unsigned int aligned = (orig + (align-1)) & ~(align-1);
2109
2110 *plen -= aligned - orig;
2111 *ppbuf = (unsigned char*)aligned;
2112}
2113
2114int jpegmem(struct jpeg *p_jpg, int ds) 2272int jpegmem(struct jpeg *p_jpg, int ds)
2115{ 2273{
2116 int size; 2274 int size;
@@ -2236,7 +2394,8 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2236#endif 2394#endif
2237 if (status) 2395 if (status)
2238 { 2396 {
2239 rb->splash(HZ*2, true, "decode error %d", status); 2397 rb->splash(HZ, true, "decode error %d", status);
2398 file_pt[curfile] = '\0';
2240 return NULL; 2399 return NULL;
2241 } 2400 }
2242 time = *rb->current_tick - time; 2401 time = *rb->current_tick - time;
@@ -2280,63 +2439,98 @@ void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
2280 2439
2281 2440
2282/* load, decode, display the image */ 2441/* load, decode, display the image */
2283int plugin_main(char* filename) 2442int load_and_show(char* filename)
2284{ 2443{
2285 int fd; 2444 int fd;
2286 int filesize; 2445 int filesize;
2287#ifdef USEGSLIB
2288 int grayscales;
2289 long graysize; // helper
2290#endif
2291 unsigned char* buf_jpeg; /* compressed JPEG image */ 2446 unsigned char* buf_jpeg; /* compressed JPEG image */
2292 static struct jpeg jpg; /* too large for stack */
2293 int status; 2447 int status;
2294 int ds, ds_min, ds_max; /* scaling and limits */
2295 struct t_disp* p_disp; /* currenly displayed image */ 2448 struct t_disp* p_disp; /* currenly displayed image */
2296 int cx, cy; /* view center */ 2449 int cx, cy; /* view center */
2297 2450
2298 fd = rb->open(filename, O_RDONLY); 2451 fd = rb->open(filename, O_RDONLY);
2299 if (fd < 0) 2452 if (fd < 0)
2300 { 2453 {
2301 rb->splash(HZ*2, true, "fopen err"); 2454 rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
2455 rb->splash(HZ, true, print);
2302 return PLUGIN_ERROR; 2456 return PLUGIN_ERROR;
2303 } 2457 }
2304 filesize = rb->filesize(fd); 2458 filesize = rb->filesize(fd);
2305
2306 rb->memset(&disp, 0, sizeof(disp)); 2459 rb->memset(&disp, 0, sizeof(disp));
2307 2460
2308 buf = rb->plugin_get_audio_buffer(&buf_size); /* start munching memory */ 2461 buf = buf_images + filesize;
2309 2462 buf_size = buf_images_size - filesize;
2310
2311#ifdef USEGSLIB
2312 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2313 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT/8,
2314 32, &graysize) + 1;
2315 buf += graysize;
2316 buf_size -= graysize;
2317 if (grayscales < 33 || buf_size <= 0)
2318 {
2319 rb->splash(HZ*2, true, "gray buf error");
2320 rb->close(fd);
2321 return PLUGIN_ERROR;
2322 }
2323#else
2324 xlcd_init(rb);
2325#endif
2326
2327
2328 /* allocate JPEG buffer */ 2463 /* allocate JPEG buffer */
2329 align(&buf, &buf_size, 2); /* 16 bit align */ 2464 buf_jpeg = buf_images;
2330 buf_jpeg = buf; 2465
2331 buf += filesize;
2332 buf_size -= filesize;
2333 buf_root = buf; /* we can start the decompressed images behind it */ 2466 buf_root = buf; /* we can start the decompressed images behind it */
2334 root_size = buf_size; 2467 root_size = buf_size;
2335 if (buf_size <= 0) 2468
2469 if (buf_size <= 0)
2336 { 2470 {
2337 rb->splash(HZ*2, true, "out of memory"); 2471#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2338 rb->close(fd); 2472 if(plug_buf)
2339 return PLUGIN_ERROR; 2473 {
2474 rb->close(fd);
2475 rb->lcd_setfont(FONT_SYSFIXED);
2476 rb->lcd_clear_display();
2477 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
2478 rb->lcd_puts(0,0,print);
2479 rb->lcd_puts(0,1,"Not enough plugin memory!");
2480 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
2481 if(entries>1)
2482 rb->lcd_puts(0,3,"Left/Right: Skip File.");
2483 rb->lcd_puts(0,4,"Off: Quit.");
2484 rb->lcd_update();
2485 rb->lcd_setfont(FONT_UI);
2486
2487 rb->button_clear_queue();
2488
2489 while (1)
2490 {
2491 int button = rb->button_get(true);
2492 switch(button)
2493 {
2494 case JPEG_ZOOM_IN:
2495 plug_buf = false;
2496 buf_images =
2497 rb->plugin_get_audio_buffer(&buf_images_size);
2498 /*try again this file, now using the audio buffer */
2499 return PLUGIN_OTHER;
2500
2501 case JPEG_QUIT:
2502 return PLUGIN_OK;
2503
2504 case JPEG_LEFT:
2505 if(entries>1)
2506 {
2507 rb->lcd_clear_display();
2508 return change_filename(DIR_PREV);
2509 }
2510 break;
2511
2512 case JPEG_RIGHT:
2513 if(entries>1)
2514 {
2515 rb->lcd_clear_display();
2516 return change_filename(DIR_NEXT);
2517 }
2518 break;
2519 default:
2520 if(rb->default_event_handler_ex(button, cleanup, NULL)
2521 == SYS_USB_CONNECTED)
2522 return PLUGIN_USB_CONNECTED;
2523
2524 }
2525 }
2526 }
2527 else
2528#endif
2529 {
2530 rb->splash(HZ, true, "Out of Memory");
2531 rb->close(fd);
2532 return PLUGIN_ERROR;
2533 }
2340 } 2534 }
2341 2535
2342#ifdef HAVE_LCD_COLOR 2536#ifdef HAVE_LCD_COLOR
@@ -2345,30 +2539,40 @@ int plugin_main(char* filename)
2345 rb->lcd_clear_display(); 2539 rb->lcd_clear_display();
2346#endif 2540#endif
2347 2541
2348 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize); 2542 rb->lcd_clear_display();
2543 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
2349 rb->lcd_puts(0, 0, print); 2544 rb->lcd_puts(0, 0, print);
2350 rb->lcd_update(); 2545 rb->lcd_update();
2546
2547 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
2548 rb->lcd_puts(0, 1, print);
2549 rb->lcd_update();
2351 2550
2352 rb->read(fd, buf_jpeg, filesize); 2551 rb->read(fd, buf_jpeg, filesize);
2353 rb->close(fd); 2552 rb->close(fd);
2354 2553
2355 rb->snprintf(print, sizeof(print), "decoding markers"); 2554 rb->snprintf(print, sizeof(print), "decoding markers");
2356 rb->lcd_puts(0, 1, print); 2555 rb->lcd_puts(0, 2, print);
2357 rb->lcd_update(); 2556 rb->lcd_update();
2557
2558
2358 2559
2359 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ 2560 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
2360 /* process markers, unstuffing */ 2561 /* process markers, unstuffing */
2361 status = process_markers(buf_jpeg, filesize, &jpg); 2562 status = process_markers(buf_jpeg, filesize, &jpg);
2563
2362 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0)) 2564 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
2363 { /* bad format or minimum components not contained */ 2565 { /* bad format or minimum components not contained */
2364 rb->splash(HZ*2, true, "unsupported %d", status); 2566 rb->splash(HZ, true, "unsupported %d", status);
2365 return PLUGIN_ERROR; 2567 file_pt[curfile] = '\0';
2568 return change_filename(direction);
2366 } 2569 }
2570
2367 if (!(status & DHT)) /* if no Huffman table present: */ 2571 if (!(status & DHT)) /* if no Huffman table present: */
2368 default_huff_tbl(&jpg); /* use default */ 2572 default_huff_tbl(&jpg); /* use default */
2369 build_lut(&jpg); /* derive Huffman and other lookup-tables */ 2573 build_lut(&jpg); /* derive Huffman and other lookup-tables */
2370 2574
2371 rb->snprintf(print, sizeof(print), "image %d*%d", jpg.x_size, jpg.y_size); 2575 rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
2372 rb->lcd_puts(0, 2, print); 2576 rb->lcd_puts(0, 2, print);
2373 rb->lcd_update(); 2577 rb->lcd_update();
2374 2578
@@ -2376,9 +2580,11 @@ int plugin_main(char* filename)
2376 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */ 2580 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
2377 if (ds_min == 0) 2581 if (ds_min == 0)
2378 { 2582 {
2379 rb->splash(HZ*2, true, "too large"); 2583 rb->splash(HZ, true, "too large");
2380 return PLUGIN_ERROR; 2584 file_pt[curfile] = '\0';
2585 return change_filename(direction);
2381 } 2586 }
2587
2382 ds = ds_max; /* initials setting */ 2588 ds = ds_max; /* initials setting */
2383 cx = jpg.x_size/ds/2; /* center the view */ 2589 cx = jpg.x_size/ds/2; /* center the view */
2384 cy = jpg.y_size/ds/2; 2590 cy = jpg.y_size/ds/2;
@@ -2387,11 +2593,11 @@ int plugin_main(char* filename)
2387 { 2593 {
2388 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */ 2594 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
2389 if (p_disp == NULL) 2595 if (p_disp == NULL)
2390 return PLUGIN_ERROR; 2596 return change_filename(direction);
2391 2597
2392 set_view(p_disp, cx, cy); 2598 set_view(p_disp, cx, cy);
2393 2599
2394 rb->snprintf(print, sizeof(print), "showing %d*%d", 2600 rb->snprintf(print, sizeof(print), "showing %dx%d",
2395 p_disp->width, p_disp->height); 2601 p_disp->width, p_disp->height);
2396 rb->lcd_puts(0, 3, print); 2602 rb->lcd_puts(0, 3, print);
2397 rb->lcd_update(); 2603 rb->lcd_update();
@@ -2460,12 +2666,8 @@ int plugin_main(char* filename)
2460#endif 2666#endif
2461 2667
2462 } 2668 }
2463 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED); 2669 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
2464 2670 && status != PLUGIN_OTHER);
2465#ifdef USEGSLIB
2466 gray_release(); /* deinitialize */
2467#endif
2468
2469 return status; 2671 return status;
2470} 2672}
2471 2673
@@ -2473,10 +2675,61 @@ int plugin_main(char* filename)
2473 2675
2474enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 2676enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2475{ 2677{
2476 rb = api; /* copy to global api pointer */ 2678 rb = api;
2679
2680 int condition;
2681#ifdef USEGSLIB
2682 int grayscales;
2683 long graysize; /* helper */
2684#endif
2685
2686 rb->strcpy(np_file, parameter);
2687 get_pic_list();
2688
2689#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2690 if(rb->pcm_is_playing())
2691 {
2692 buf = rb->plugin_get_buffer(&buf_size) +
2693 (entries * sizeof(char**));
2694 buf_size -= (entries * sizeof(char**));
2695 plug_buf = true;
2696 }
2697 else
2698 buf = rb->plugin_get_audio_buffer(&buf_size);
2699#else
2700 buf = rb->plugin_get_audio_buffer(&buf_size) +
2701 (entries * sizeof(char**));
2702 buf_size -= (entries * sizeof(char**));
2703#endif
2704
2705#ifdef USEGSLIB
2706 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2707 grayscales = gray_init(rb, buf, buf_size, false, LCD_WIDTH, LCD_HEIGHT/8,
2708 32, &graysize) + 1;
2709 buf += graysize;
2710 buf_size -= graysize;
2711 if (grayscales < 33 || buf_size <= 0)
2712 {
2713 rb->splash(HZ, true, "gray buf error");
2714 return PLUGIN_ERROR;
2715 }
2716#else
2717 xlcd_init(rb);
2718#endif
2719
2720 buf_images = buf; buf_images_size = buf_size;
2721
2722 do
2723 {
2724 condition = load_and_show(np_file);
2725 }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
2726 && condition != PLUGIN_ERROR);
2477 2727
2478 return plugin_main((char*)parameter); 2728#ifdef USEGSLIB
2729 gray_release(); /* deinitialize */
2730#endif
2731
2732 return condition;
2479} 2733}
2480 2734
2481#endif /* HAVE_LCD_BITMAP && ((LCD_DEPTH >= 8) || !defined(SIMULATOR))*/ 2735#endif /* HAVE_LCD_BITMAP && ((LCD_DEPTH >= 8) || !defined(SIMULATOR))*/
2482
diff --git a/apps/plugins/searchengine/dbinterface.c b/apps/plugins/searchengine/dbinterface.c
index e10510604d..c3f1c7bfef 100644
--- a/apps/plugins/searchengine/dbinterface.c
+++ b/apps/plugins/searchengine/dbinterface.c
@@ -33,18 +33,18 @@
33 33
34#define FILERECORD2OFFSET(_x_) (rb->tagdbheader->filestart + _x_ * FILEENTRY_SIZE) 34#define FILERECORD2OFFSET(_x_) (rb->tagdbheader->filestart + _x_ * FILEENTRY_SIZE)
35 35
36struct entry *currententry; 36struct dbentry *currententry;
37struct dbglobals dbglobal; 37struct dbglobals dbglobal;
38static struct entry *entryarray; 38static struct dbentry *entryarray;
39 39
40int database_init() { 40int database_init() {
41 char *p; 41 char *p;
42 unsigned int i; 42 unsigned int i;
43 // allocate room for all entries 43 // allocate room for all entries
44 entryarray=(struct entry *)my_malloc(sizeof(struct entry)*rb->tagdbheader->filecount); 44 entryarray=(struct dbentry *)my_malloc(sizeof(struct dbentry)*rb->tagdbheader->filecount);
45 p=(char *)entryarray; 45 p=(char *)entryarray;
46 // zero all entries. 46 // zero all entries.
47 for(i=0;i<sizeof(struct entry)*rb->tagdbheader->filecount;i++) 47 for(i=0;i<sizeof(struct dbentry)*rb->tagdbheader->filecount;i++)
48 *(p++)=0; 48 *(p++)=0;
49 if(!*rb->tagdb_initialized) { 49 if(!*rb->tagdb_initialized) {
50 if(!rb->tagdb_init()) { 50 if(!rb->tagdb_init()) {
diff --git a/apps/plugins/searchengine/dbinterface.h b/apps/plugins/searchengine/dbinterface.h
index e762297d8f..f4560a805a 100644
--- a/apps/plugins/searchengine/dbinterface.h
+++ b/apps/plugins/searchengine/dbinterface.h
@@ -23,7 +23,7 @@ struct dbglobals {
23 int currententryindex; 23 int currententryindex;
24}; 24};
25 25
26struct entry { 26struct dbentry {
27 int loadedfiledata, 27 int loadedfiledata,
28 loadedsongdata, 28 loadedsongdata,
29 loadedrundbdata, 29 loadedrundbdata,
@@ -50,7 +50,7 @@ struct entry {
50 short samplerate; 50 short samplerate;
51}; 51};
52 52
53extern struct entry *currententry; 53extern struct dbentry *currententry;
54extern struct dbglobals dbglobal; 54extern struct dbglobals dbglobal;
55 55
56int database_init(void); 56int database_init(void);