summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-01-18 12:46:19 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-01-18 12:46:19 +0000
commit5bd08237499dfc66309ba2a5a4dac75018e794ac (patch)
treefe742342707b8789ce0dbf1a18e5a8346ae2601d
parent135d983433e741cf9658ff5d7457bdf37ef48ce0 (diff)
downloadrockbox-5bd08237499dfc66309ba2a5a4dac75018e794ac.tar.gz
rockbox-5bd08237499dfc66309ba2a5a4dac75018e794ac.zip
jpeg,png: Merge user interface code and plugin entry point of the two plugins (part of FS#6321).
* Created new directory, imageviewer/ and moved both jpeg/ and png/ under it. - this still doesn't merge the two plugins. i.e. both jpeg.rock and png.rock will be made for color targets. - I'm thinking to merge the two plugins to single image viewer later. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24272 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/SUBDIRS5
-rw-r--r--apps/plugins/imageviewer/SUBDIRS4
-rw-r--r--apps/plugins/imageviewer/imageviewer.c (renamed from apps/plugins/jpeg/jpeg.c)696
-rw-r--r--apps/plugins/imageviewer/imageviewer.h414
-rw-r--r--apps/plugins/imageviewer/imageviewer.make16
-rw-r--r--apps/plugins/imageviewer/jpeg/SOURCES (renamed from apps/plugins/jpeg/SOURCES)1
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg.c308
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg.make (renamed from apps/plugins/jpeg/jpeg.make)4
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg_decoder.c (renamed from apps/plugins/jpeg/jpeg_decoder.c)0
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg_decoder.h (renamed from apps/plugins/jpeg/jpeg_decoder.h)0
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg_ui.c5
-rw-r--r--apps/plugins/imageviewer/jpeg/yuv2rgb.c (renamed from apps/plugins/jpeg/yuv2rgb.c)0
-rw-r--r--apps/plugins/imageviewer/jpeg/yuv2rgb.h (renamed from apps/plugins/jpeg/yuv2rgb.h)0
-rw-r--r--apps/plugins/imageviewer/png/SOURCES (renamed from apps/plugins/png/SOURCES)1
-rw-r--r--apps/plugins/imageviewer/png/adler32.c (renamed from apps/plugins/png/adler32.c)0
-rw-r--r--apps/plugins/imageviewer/png/crc32_png.c (renamed from apps/plugins/png/crc32_png.c)0
-rw-r--r--apps/plugins/imageviewer/png/crc32_png.h (renamed from apps/plugins/png/crc32_png.h)0
-rw-r--r--apps/plugins/imageviewer/png/inffast.c (renamed from apps/plugins/png/inffast.c)0
-rw-r--r--apps/plugins/imageviewer/png/inffast.h (renamed from apps/plugins/png/inffast.h)0
-rw-r--r--apps/plugins/imageviewer/png/inffixed.h (renamed from apps/plugins/png/inffixed.h)0
-rw-r--r--apps/plugins/imageviewer/png/inflate.c (renamed from apps/plugins/png/inflate.c)4
-rw-r--r--apps/plugins/imageviewer/png/inflate.h (renamed from apps/plugins/png/inflate.h)0
-rw-r--r--apps/plugins/imageviewer/png/inftrees.c (renamed from apps/plugins/png/inftrees.c)0
-rw-r--r--apps/plugins/imageviewer/png/inftrees.h (renamed from apps/plugins/png/inftrees.h)0
-rw-r--r--apps/plugins/imageviewer/png/png.c (renamed from apps/plugins/png/png.c)841
-rw-r--r--apps/plugins/imageviewer/png/png.h29
-rw-r--r--apps/plugins/imageviewer/png/png.make (renamed from apps/plugins/png/png.make)4
-rw-r--r--apps/plugins/imageviewer/png/png_ui.c5
-rw-r--r--apps/plugins/imageviewer/png/zconf.h (renamed from apps/plugins/png/zconf.h)0
-rw-r--r--apps/plugins/imageviewer/png/zlib.h (renamed from apps/plugins/png/zlib.h)0
-rw-r--r--apps/plugins/imageviewer/png/zutil.h (renamed from apps/plugins/png/zutil.h)0
-rw-r--r--apps/plugins/jpeg/jpeg.h340
-rw-r--r--apps/plugins/png/png.h366
33 files changed, 1048 insertions, 1995 deletions
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 5cb9356317..f1de3e8e48 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -21,7 +21,7 @@ pictureflow
21#endif 21#endif
22chessbox 22chessbox
23fractals 23fractals
24jpeg 24imageviewer
25sudoku 25sudoku
26reversi 26reversi
27goban 27goban
@@ -29,9 +29,6 @@ goban
29#if (CONFIG_CPU != SH7034) 29#if (CONFIG_CPU != SH7034)
30frotz 30frotz
31#endif 31#endif
32#ifdef HAVE_LCD_COLOR
33png
34#endif
35#ifndef OLYMPUS_MROBE_500 32#ifndef OLYMPUS_MROBE_500
36zxbox 33zxbox
37#endif 34#endif
diff --git a/apps/plugins/imageviewer/SUBDIRS b/apps/plugins/imageviewer/SUBDIRS
new file mode 100644
index 0000000000..6785e47781
--- /dev/null
+++ b/apps/plugins/imageviewer/SUBDIRS
@@ -0,0 +1,4 @@
1jpeg
2#ifdef HAVE_LCD_COLOR
3png
4#endif
diff --git a/apps/plugins/jpeg/jpeg.c b/apps/plugins/imageviewer/imageviewer.c
index 4a61f13e51..1b39c5a9e3 100644
--- a/apps/plugins/jpeg/jpeg.c
+++ b/apps/plugins/imageviewer/imageviewer.c
@@ -1,112 +1,70 @@
1/*************************************************************************** 1/***************************************************************************
2* __________ __ ___. 2 * __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8* $Id$ 8 * $Id$
9* 9 *
10* JPEG image viewer 10 * user intereface of image viewers (jpeg, png, etc.)
11* (This is a real mess if it has to be coded in one single C file) 11 *
12* 12 * This program is free software; you can redistribute it and/or
13* File scrolling addition (C) 2005 Alexander Spyridakis 13 * modify it under the terms of the GNU General Public License
14* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon 14 * as published by the Free Software Foundation; either version 2
15* Heavily borrowed from the IJG implementation (C) Thomas G. Lane 15 * of the License, or (at your option) any later version.
16* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org 16 *
17* 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* This program is free software; you can redistribute it and/or 18 * KIND, either express or implied.
19* modify it under the terms of the GNU General Public License 19 *
20* as published by the Free Software Foundation; either version 2 20 ****************************************************************************/
21* of the License, or (at your option) any later version.
22*
23* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24* KIND, either express or implied.
25*
26****************************************************************************/
27 21
28#include "plugin.h" 22#include "plugin.h"
29#include <lib/playback_control.h> 23#include <lib/playback_control.h>
30#include <lib/helper.h> 24#include <lib/helper.h>
31#include <lib/configfile.h> 25#include <lib/configfile.h>
32 26#include "imageviewer.h"
33#include <lib/grey.h>
34#include <lib/xlcd.h>
35
36#include "jpeg.h"
37#include "jpeg_decoder.h"
38 27
39PLUGIN_HEADER 28PLUGIN_HEADER
40 29
41#ifdef HAVE_LCD_COLOR 30#ifdef USEGSLIB
42#include "yuv2rgb.h"
43#endif
44
45/* different graphics libraries */
46#if LCD_DEPTH < 8
47#define USEGSLIB
48GREY_INFO_STRUCT 31GREY_INFO_STRUCT
49#define MYLCD(fn) grey_ub_ ## fn
50#define MYLCD_UPDATE()
51#define MYXLCD(fn) grey_ub_ ## fn
52#else
53#define MYLCD(fn) rb->lcd_ ## fn
54#define MYLCD_UPDATE() rb->lcd_update();
55#define MYXLCD(fn) xlcd_ ## fn
56#endif 32#endif
57 33
58/* Min memory allowing us to use the plugin buffer
59 * and thus not stopping the music
60 * *Very* rough estimation:
61 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
62 * + 20k code size = 60 000
63 * + 50k min for jpeg = 120 000
64 */
65#define MIN_MEM 120000
66
67/* Headings */ 34/* Headings */
68#define DIR_PREV 1 35#define DIR_PREV 1
69#define DIR_NEXT -1 36#define DIR_NEXT -1
70#define DIR_NONE 0 37#define DIR_NONE 0
71 38
72#define PLUGIN_OTHER 10 /* State code for output with return. */
73#define PLUGIN_ABORT 11
74#define PLUGIN_OUTOFMEM 12
75
76/******************************* Globals ***********************************/ 39/******************************* Globals ***********************************/
77 40
78static int slideshow_enabled = false; /* run slideshow */ 41bool slideshow_enabled = false; /* run slideshow */
79static int running_slideshow = false; /* loading image because of slideshw */ 42bool running_slideshow = false; /* loading image because of slideshw */
80#ifndef SIMULATOR 43#ifdef DISK_SPINDOWN
81static int immediate_ata_off = false; /* power down disk after loading */ 44bool immediate_ata_off = false; /* power down disk after loading */
82#endif 45#endif
83 46#if PLUGIN_BUFFER_SIZE >= MIN_MEM
84#ifdef HAVE_LCD_COLOR 47/* are we using the plugin buffer or the audio buffer? */
85fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when 48bool plug_buf = true;
86 DITHER_DIFFUSION is set */
87#endif 49#endif
88 50
89
90/* Persistent configuration */ 51/* Persistent configuration */
91#define JPEG_CONFIGFILE "jpeg.cfg" 52#define IMGVIEW_CONFIGFILE "imageviewer.cfg"
92#define JPEG_SETTINGS_MINVERSION 1 53#define IMGVIEW_SETTINGS_MINVERSION 1
93#define JPEG_SETTINGS_VERSION 2 54#define IMGVIEW_SETTINGS_VERSION 2
94 55
95/* Slideshow times */ 56/* Slideshow times */
96#define SS_MIN_TIMEOUT 1 57#define SS_MIN_TIMEOUT 1
97#define SS_MAX_TIMEOUT 20 58#define SS_MAX_TIMEOUT 20
98#define SS_DEFAULT_TIMEOUT 5 59#define SS_DEFAULT_TIMEOUT 5
99 60
100struct jpeg_settings
101{
102#ifdef HAVE_LCD_COLOR 61#ifdef HAVE_LCD_COLOR
103 int colour_mode; 62/* needed for value of settings */
104 int dither_mode; 63#include "jpeg/yuv2rgb.h"
105#endif 64#endif
106 int ss_timeout;
107};
108 65
109static struct jpeg_settings jpeg_settings = 66/* jpeg use this */
67struct imgview_settings settings =
110{ 68{
111#ifdef HAVE_LCD_COLOR 69#ifdef HAVE_LCD_COLOR
112 COLOURMODE_COLOUR, 70 COLOURMODE_COLOUR,
@@ -114,18 +72,18 @@ static struct jpeg_settings jpeg_settings =
114#endif 72#endif
115 SS_DEFAULT_TIMEOUT 73 SS_DEFAULT_TIMEOUT
116}; 74};
117static struct jpeg_settings old_settings; 75static struct imgview_settings old_settings;
118 76
119static struct configdata jpeg_config[] = 77static struct configdata config[] =
120{ 78{
121#ifdef HAVE_LCD_COLOR 79#ifdef HAVE_LCD_COLOR
122 { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &jpeg_settings.colour_mode }, 80 { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &settings.jpeg_colour_mode },
123 "Colour Mode", (char *[]){ "Colour", "Grayscale" } }, 81 "Colour Mode", (char *[]){ "Colour", "Grayscale" } },
124 { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &jpeg_settings.dither_mode }, 82 { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &settings.jpeg_dither_mode },
125 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" } }, 83 "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" } },
126#endif 84#endif
127 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, 85 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT,
128 { .int_p = &jpeg_settings.ss_timeout }, "Slideshow Time", NULL }, 86 { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL },
129}; 87};
130 88
131#if LCD_DEPTH > 1 89#if LCD_DEPTH > 1
@@ -135,43 +93,21 @@ static fb_data* old_backdrop;
135/**************** begin Application ********************/ 93/**************** begin Application ********************/
136 94
137 95
138/************************* Types ***************************/
139
140struct t_disp
141{
142#ifdef HAVE_LCD_COLOR
143 unsigned char* bitmap[3]; /* Y, Cr, Cb */
144 int csub_x, csub_y;
145#else
146 unsigned char* bitmap[1]; /* Y only */
147#endif
148 int width;
149 int height;
150 int stride;
151 int x, y;
152};
153
154/************************* Globals ***************************/ 96/************************* Globals ***************************/
155 97
156/* decompressed image in the possible sizes (1,2,4,8), wasting the other */ 98#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
157static struct t_disp disp[9]; 99static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
100 DITHER_DIFFUSION is set */
101#endif
158 102
159/* my memory pool (from the mp3 buffer) */ 103/* my memory pool (from the mp3 buffer) */
160static char print[32]; /* use a common snprintf() buffer */ 104static char print[32]; /* use a common snprintf() buffer */
161/* the remaining free part of the buffer for compressed+uncompressed images */ 105/* the remaining free part of the buffer for loaded+resized images */
162static unsigned char* buf; 106static unsigned char* buf;
163static ssize_t buf_size; 107static ssize_t buf_size;
164 108
165/* the root of the images, hereafter are decompresed ones */
166static unsigned char* buf_root;
167static int root_size;
168
169/* up to here currently used by image(s) */
170static unsigned char* buf_images;
171static ssize_t buf_images_size;
172
173static int ds, ds_min, ds_max; /* downscaling and limits */ 109static int ds, ds_min, ds_max; /* downscaling and limits */
174static struct jpeg jpg; /* too large for stack */ 110static struct image_info image_info;
175 111
176static struct tree_context *tree; 112static struct tree_context *tree;
177 113
@@ -179,30 +115,13 @@ static struct tree_context *tree;
179static char np_file[MAX_PATH]; 115static char np_file[MAX_PATH];
180static int curfile = 0, direction = DIR_NONE, entries = 0; 116static int curfile = 0, direction = DIR_NONE, entries = 0;
181 117
182/* list of the jpeg files */ 118/* list of the supported image files */
183static char **file_pt; 119static char **file_pt;
184#if PLUGIN_BUFFER_SIZE >= MIN_MEM
185/* are we using the plugin buffer or the audio buffer? */
186static bool plug_buf = true;
187#endif
188
189 120
190/************************* Implementation ***************************/ 121/************************* Implementation ***************************/
191 122
192bool jpg_ext(const char ext[])
193{
194 if(!ext)
195 return false;
196 if(!rb->strcasecmp(ext,".jpg") ||
197 !rb->strcasecmp(ext,".jpe") ||
198 !rb->strcasecmp(ext,".jpeg"))
199 return true;
200 else
201 return false;
202}
203
204/*Read directory contents for scrolling. */ 123/*Read directory contents for scrolling. */
205void get_pic_list(void) 124static void get_pic_list(void)
206{ 125{
207 int i; 126 int i;
208 struct entry *dircache; 127 struct entry *dircache;
@@ -219,7 +138,7 @@ void get_pic_list(void)
219 for (i = 0; i < tree->filesindir; i++) 138 for (i = 0; i < tree->filesindir; i++)
220 { 139 {
221 if (!(dircache[i].attr & ATTR_DIRECTORY) 140 if (!(dircache[i].attr & ATTR_DIRECTORY)
222 && jpg_ext(rb->strrchr(dircache[i].name,'.'))) 141 && img_ext(rb->strrchr(dircache[i].name,'.')))
223 { 142 {
224 file_pt[entries] = dircache[i].name; 143 file_pt[entries] = dircache[i].name;
225 /* Set Selected File. */ 144 /* Set Selected File. */
@@ -233,7 +152,7 @@ void get_pic_list(void)
233 buf_size -= (entries * sizeof(char**)); 152 buf_size -= (entries * sizeof(char**));
234} 153}
235 154
236int change_filename(int direct) 155static int change_filename(int direct)
237{ 156{
238 bool file_erased = (file_pt[curfile] == NULL); 157 bool file_erased = (file_pt[curfile] == NULL);
239 direction = direct; 158 direction = direct;
@@ -276,7 +195,7 @@ int change_filename(int direct)
276} 195}
277 196
278/* switch off overlay, for handling SYS_ events */ 197/* switch off overlay, for handling SYS_ events */
279void cleanup(void *parameter) 198static void cleanup(void *parameter)
280{ 199{
281 (void)parameter; 200 (void)parameter;
282#ifdef USEGSLIB 201#ifdef USEGSLIB
@@ -290,16 +209,16 @@ void cleanup(void *parameter)
290#define ZOOM_IN 100 /* return codes for below function */ 209#define ZOOM_IN 100 /* return codes for below function */
291#define ZOOM_OUT 101 210#define ZOOM_OUT 101
292 211
293#ifdef HAVE_LCD_COLOR 212#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
294bool set_option_grayscale(void) 213static bool set_option_grayscale(void)
295{ 214{
296 bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY; 215 bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY;
297 rb->set_bool("Grayscale", &gray); 216 rb->set_bool("Grayscale", &gray);
298 jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR; 217 settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
299 return false; 218 return false;
300} 219}
301 220
302bool set_option_dithering(void) 221static bool set_option_dithering(void)
303{ 222{
304 static const struct opt_items dithering[DITHER_NUM_MODES] = { 223 static const struct opt_items dithering[DITHER_NUM_MODES] = {
305 [DITHER_NONE] = { "Off", -1 }, 224 [DITHER_NONE] = { "Off", -1 },
@@ -307,7 +226,7 @@ bool set_option_dithering(void)
307 [DITHER_DIFFUSION] = { "Diffusion", -1 }, 226 [DITHER_DIFFUSION] = { "Diffusion", -1 },
308 }; 227 };
309 228
310 rb->set_option("Dithering", &jpeg_settings.dither_mode, INT, 229 rb->set_option("Dithering", &settings.jpeg_dither_mode, INT,
311 dithering, DITHER_NUM_MODES, NULL); 230 dithering, DITHER_NUM_MODES, NULL);
312 return false; 231 return false;
313} 232}
@@ -323,9 +242,9 @@ static void display_options(void)
323{ 242{
324 rb->do_menu(&display_menu, NULL, NULL, false); 243 rb->do_menu(&display_menu, NULL, NULL, false);
325} 244}
326#endif /* HAVE_LCD_COLOR */ 245#endif /* defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) */
327 246
328int show_menu(void) /* return 1 to quit */ 247static int show_menu(void) /* return 1 to quit */
329{ 248{
330#if LCD_DEPTH > 1 249#if LCD_DEPTH > 1
331 rb->lcd_set_backdrop(old_backdrop); 250 rb->lcd_set_backdrop(old_backdrop);
@@ -347,19 +266,19 @@ int show_menu(void) /* return 1 to quit */
347#if PLUGIN_BUFFER_SIZE >= MIN_MEM 266#if PLUGIN_BUFFER_SIZE >= MIN_MEM
348 MIID_SHOW_PLAYBACK_MENU, 267 MIID_SHOW_PLAYBACK_MENU,
349#endif 268#endif
350#ifdef HAVE_LCD_COLOR 269#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
351 MIID_DISPLAY_OPTIONS, 270 MIID_DISPLAY_OPTIONS,
352#endif 271#endif
353 MIID_QUIT, 272 MIID_QUIT,
354 }; 273 };
355 274
356 MENUITEM_STRINGLIST(menu, "Jpeg Menu", NULL, 275 MENUITEM_STRINGLIST(menu, MENU_TITLE, NULL,
357 "Return", "Toggle Slideshow Mode", 276 "Return", "Toggle Slideshow Mode",
358 "Change Slideshow Time", 277 "Change Slideshow Time",
359#if PLUGIN_BUFFER_SIZE >= MIN_MEM 278#if PLUGIN_BUFFER_SIZE >= MIN_MEM
360 "Show Playback Menu", 279 "Show Playback Menu",
361#endif 280#endif
362#ifdef HAVE_LCD_COLOR 281#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
363 "Display Options", 282 "Display Options",
364#endif 283#endif
365 "Quit"); 284 "Quit");
@@ -381,7 +300,7 @@ int show_menu(void) /* return 1 to quit */
381 break; 300 break;
382 case MIID_CHANGE_SS_MODE: 301 case MIID_CHANGE_SS_MODE:
383 rb->set_int("Slideshow Time", "s", UNIT_SEC, 302 rb->set_int("Slideshow Time", "s", UNIT_SEC,
384 &jpeg_settings.ss_timeout, NULL, 1, 303 &settings.ss_timeout, NULL, 1,
385 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL); 304 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
386 break; 305 break;
387 306
@@ -397,7 +316,7 @@ int show_menu(void) /* return 1 to quit */
397 } 316 }
398 break; 317 break;
399#endif 318#endif
400#ifdef HAVE_LCD_COLOR 319#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
401 case MIID_DISPLAY_OPTIONS: 320 case MIID_DISPLAY_OPTIONS:
402 display_options(); 321 display_options();
403 break; 322 break;
@@ -407,14 +326,14 @@ int show_menu(void) /* return 1 to quit */
407 break; 326 break;
408 } 327 }
409 328
410#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE) 329#ifdef DISK_SPINDOWN
411 /* change ata spindown time based on slideshow time setting */ 330 /* change ata spindown time based on slideshow time setting */
412 immediate_ata_off = false; 331 immediate_ata_off = false;
413 rb->storage_spindown(rb->global_settings->disk_spindown); 332 rb->storage_spindown(rb->global_settings->disk_spindown);
414 333
415 if (slideshow_enabled) 334 if (slideshow_enabled)
416 { 335 {
417 if(jpeg_settings.ss_timeout < 10) 336 if(settings.ss_timeout < 10)
418 { 337 {
419 /* slideshow times < 10s keep disk spinning */ 338 /* slideshow times < 10s keep disk spinning */
420 rb->storage_spindown(0); 339 rb->storage_spindown(0);
@@ -435,115 +354,96 @@ int show_menu(void) /* return 1 to quit */
435 return 0; 354 return 0;
436} 355}
437 356
438void draw_image_rect(struct t_disp* pdisp, int x, int y, int width, int height)
439{
440#ifdef HAVE_LCD_COLOR
441 yuv_bitmap_part(
442 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
443 pdisp->x + x, pdisp->y + y, pdisp->stride,
444 x + MAX(0, (LCD_WIDTH - pdisp->width) / 2),
445 y + MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
446 width, height,
447 jpeg_settings.colour_mode, jpeg_settings.dither_mode);
448#else
449 MYXLCD(gray_bitmap_part)(
450 pdisp->bitmap[0], pdisp->x + x, pdisp->y + y, pdisp->stride,
451 x + MAX(0, (LCD_WIDTH-pdisp->width)/2),
452 y + MAX(0, (LCD_HEIGHT-pdisp->height)/2),
453 width, height);
454#endif
455}
456
457/* Pan the viewing window right - move image to the left and fill in 357/* Pan the viewing window right - move image to the left and fill in
458 the right-hand side */ 358 the right-hand side */
459static void pan_view_right(struct t_disp* pdisp) 359static void pan_view_right(struct image_info *info)
460{ 360{
461 int move; 361 int move;
462 362
463 move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); 363 move = MIN(HSCROLL, info->width - info->x - LCD_WIDTH);
464 if (move > 0) 364 if (move > 0)
465 { 365 {
466 MYXLCD(scroll_left)(move); /* scroll left */ 366 MYXLCD(scroll_left)(move); /* scroll left */
467 pdisp->x += move; 367 info->x += move;
468 draw_image_rect(pdisp, LCD_WIDTH - move, 0, move, pdisp->height-pdisp->y); 368 draw_image_rect(info, LCD_WIDTH - move, 0, move, info->height-info->y);
469 MYLCD_UPDATE(); 369 MYLCD_UPDATE();
470 } 370 }
471} 371}
472 372
473/* Pan the viewing window left - move image to the right and fill in 373/* Pan the viewing window left - move image to the right and fill in
474 the left-hand side */ 374 the left-hand side */
475static void pan_view_left(struct t_disp* pdisp) 375static void pan_view_left(struct image_info *info)
476{ 376{
477 int move; 377 int move;
478 378
479 move = MIN(HSCROLL, pdisp->x); 379 move = MIN(HSCROLL, info->x);
480 if (move > 0) 380 if (move > 0)
481 { 381 {
482 MYXLCD(scroll_right)(move); /* scroll right */ 382 MYXLCD(scroll_right)(move); /* scroll right */
483 pdisp->x -= move; 383 info->x -= move;
484 draw_image_rect(pdisp, 0, 0, move, pdisp->height-pdisp->y); 384 draw_image_rect(info, 0, 0, move, info->height-info->y);
485 MYLCD_UPDATE(); 385 MYLCD_UPDATE();
486 } 386 }
487} 387}
488 388
489/* Pan the viewing window up - move image down and fill in 389/* Pan the viewing window up - move image down and fill in
490 the top */ 390 the top */
491static void pan_view_up(struct t_disp* pdisp) 391static void pan_view_up(struct image_info *info)
492{ 392{
493 int move; 393 int move;
494 394
495 move = MIN(VSCROLL, pdisp->y); 395 move = MIN(VSCROLL, info->y);
496 if (move > 0) 396 if (move > 0)
497 { 397 {
498 MYXLCD(scroll_down)(move); /* scroll down */ 398 MYXLCD(scroll_down)(move); /* scroll down */
499 pdisp->y -= move; 399 info->y -= move;
500#ifdef HAVE_LCD_COLOR 400#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
501 if (jpeg_settings.dither_mode == DITHER_DIFFUSION) 401 if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
502 { 402 {
503 /* Draw over the band at the top of the last update 403 /* Draw over the band at the top of the last update
504 caused by lack of error history on line zero. */ 404 caused by lack of error history on line zero. */
505 move = MIN(move + 1, pdisp->y + pdisp->height); 405 move = MIN(move + 1, info->y + info->height);
506 } 406 }
507#endif 407#endif
508 draw_image_rect(pdisp, 0, 0, pdisp->width-pdisp->x, move); 408 draw_image_rect(info, 0, 0, info->width-info->x, move);
509 MYLCD_UPDATE(); 409 MYLCD_UPDATE();
510 } 410 }
511} 411}
512 412
513/* Pan the viewing window down - move image up and fill in 413/* Pan the viewing window down - move image up and fill in
514 the bottom */ 414 the bottom */
515static void pan_view_down(struct t_disp* pdisp) 415static void pan_view_down(struct image_info *info)
516{ 416{
517 int move; 417 int move;
518 418
519 move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT); 419 move = MIN(VSCROLL, info->height - info->y - LCD_HEIGHT);
520 if (move > 0) 420 if (move > 0)
521 { 421 {
522 MYXLCD(scroll_up)(move); /* scroll up */ 422 MYXLCD(scroll_up)(move); /* scroll up */
523 pdisp->y += move; 423 info->y += move;
524#ifdef HAVE_LCD_COLOR 424#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
525 if (jpeg_settings.dither_mode == DITHER_DIFFUSION) 425 if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
526 { 426 {
527 /* Save the line that was on the last line of the display 427 /* Save the line that was on the last line of the display
528 and draw one extra line above then recover the line with 428 and draw one extra line above then recover the line with
529 image data that had an error history when it was drawn. 429 image data that had an error history when it was drawn.
530 */ 430 */
531 move++, pdisp->y--; 431 move++, info->y--;
532 rb->memcpy(rgb_linebuf, 432 rb->memcpy(rgb_linebuf,
533 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 433 rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
534 LCD_WIDTH*sizeof (fb_data)); 434 LCD_WIDTH*sizeof (fb_data));
535 } 435 }
536#endif 436#endif
537 437
538 draw_image_rect(pdisp, 0, LCD_HEIGHT - move, pdisp->width-pdisp->x, move); 438 draw_image_rect(info, 0, LCD_HEIGHT - move, info->width-info->x, move);
539 439
540#ifdef HAVE_LCD_COLOR 440#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
541 if (jpeg_settings.dither_mode == DITHER_DIFFUSION) 441 if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
542 { 442 {
543 /* Cover the first row drawn with previous image data. */ 443 /* Cover the first row drawn with previous image data. */
544 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 444 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
545 rgb_linebuf, LCD_WIDTH*sizeof (fb_data)); 445 rgb_linebuf, LCD_WIDTH*sizeof (fb_data));
546 pdisp->y++; 446 info->y++;
547 } 447 }
548#endif 448#endif
549 MYLCD_UPDATE(); 449 MYLCD_UPDATE();
@@ -551,7 +451,7 @@ static void pan_view_down(struct t_disp* pdisp)
551} 451}
552 452
553/* interactively scroll around the image */ 453/* interactively scroll around the image */
554int scroll_bmp(struct t_disp* pdisp) 454static int scroll_bmp(struct image_info *info)
555{ 455{
556 int button; 456 int button;
557 int lastbutton = 0; 457 int lastbutton = 0;
@@ -559,7 +459,7 @@ int scroll_bmp(struct t_disp* pdisp)
559 while (true) 459 while (true)
560 { 460 {
561 if (slideshow_enabled) 461 if (slideshow_enabled)
562 button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ); 462 button = rb->button_get_w_tmo(settings.ss_timeout * HZ);
563 else 463 else
564 button = rb->button_get(true); 464 button = rb->button_get(true);
565 465
@@ -567,30 +467,30 @@ int scroll_bmp(struct t_disp* pdisp)
567 467
568 switch(button) 468 switch(button)
569 { 469 {
570 case JPEG_LEFT: 470 case IMGVIEW_LEFT:
571 if (entries > 1 && pdisp->width <= LCD_WIDTH 471 if (entries > 1 && info->width <= LCD_WIDTH
572 && pdisp->height <= LCD_HEIGHT) 472 && info->height <= LCD_HEIGHT)
573 return change_filename(DIR_PREV); 473 return change_filename(DIR_PREV);
574 case JPEG_LEFT | BUTTON_REPEAT: 474 case IMGVIEW_LEFT | BUTTON_REPEAT:
575 pan_view_left(pdisp); 475 pan_view_left(info);
576 break; 476 break;
577 477
578 case JPEG_RIGHT: 478 case IMGVIEW_RIGHT:
579 if (entries > 1 && pdisp->width <= LCD_WIDTH 479 if (entries > 1 && info->width <= LCD_WIDTH
580 && pdisp->height <= LCD_HEIGHT) 480 && info->height <= LCD_HEIGHT)
581 return change_filename(DIR_NEXT); 481 return change_filename(DIR_NEXT);
582 case JPEG_RIGHT | BUTTON_REPEAT: 482 case IMGVIEW_RIGHT | BUTTON_REPEAT:
583 pan_view_right(pdisp); 483 pan_view_right(info);
584 break; 484 break;
585 485
586 case JPEG_UP: 486 case IMGVIEW_UP:
587 case JPEG_UP | BUTTON_REPEAT: 487 case IMGVIEW_UP | BUTTON_REPEAT:
588 pan_view_up(pdisp); 488 pan_view_up(info);
589 break; 489 break;
590 490
591 case JPEG_DOWN: 491 case IMGVIEW_DOWN:
592 case JPEG_DOWN | BUTTON_REPEAT: 492 case IMGVIEW_DOWN | BUTTON_REPEAT:
593 pan_view_down(pdisp); 493 pan_view_down(info);
594 break; 494 break;
595 495
596 case BUTTON_NONE: 496 case BUTTON_NONE:
@@ -601,48 +501,48 @@ int scroll_bmp(struct t_disp* pdisp)
601 return change_filename(DIR_NEXT); 501 return change_filename(DIR_NEXT);
602 break; 502 break;
603 503
604#ifdef JPEG_SLIDE_SHOW 504#ifdef IMGVIEW_SLIDE_SHOW
605 case JPEG_SLIDE_SHOW: 505 case IMGVIEW_SLIDE_SHOW:
606 slideshow_enabled = !slideshow_enabled; 506 slideshow_enabled = !slideshow_enabled;
607 running_slideshow = slideshow_enabled; 507 running_slideshow = slideshow_enabled;
608 break; 508 break;
609#endif 509#endif
610 510
611#ifdef JPEG_NEXT_REPEAT 511#ifdef IMGVIEW_NEXT_REPEAT
612 case JPEG_NEXT_REPEAT: 512 case IMGVIEW_NEXT_REPEAT:
613#endif 513#endif
614 case JPEG_NEXT: 514 case IMGVIEW_NEXT:
615 if (entries > 1) 515 if (entries > 1)
616 return change_filename(DIR_NEXT); 516 return change_filename(DIR_NEXT);
617 break; 517 break;
618 518
619#ifdef JPEG_PREVIOUS_REPEAT 519#ifdef IMGVIEW_PREVIOUS_REPEAT
620 case JPEG_PREVIOUS_REPEAT: 520 case IMGVIEW_PREVIOUS_REPEAT:
621#endif 521#endif
622 case JPEG_PREVIOUS: 522 case IMGVIEW_PREVIOUS:
623 if (entries > 1) 523 if (entries > 1)
624 return change_filename(DIR_PREV); 524 return change_filename(DIR_PREV);
625 break; 525 break;
626 526
627 case JPEG_ZOOM_IN: 527 case IMGVIEW_ZOOM_IN:
628#ifdef JPEG_ZOOM_PRE 528#ifdef IMGVIEW_ZOOM_PRE
629 if (lastbutton != JPEG_ZOOM_PRE) 529 if (lastbutton != IMGVIEW_ZOOM_PRE)
630 break; 530 break;
631#endif 531#endif
632 return ZOOM_IN; 532 return ZOOM_IN;
633 break; 533 break;
634 534
635 case JPEG_ZOOM_OUT: 535 case IMGVIEW_ZOOM_OUT:
636#ifdef JPEG_ZOOM_PRE 536#ifdef IMGVIEW_ZOOM_PRE
637 if (lastbutton != JPEG_ZOOM_PRE) 537 if (lastbutton != IMGVIEW_ZOOM_PRE)
638 break; 538 break;
639#endif 539#endif
640 return ZOOM_OUT; 540 return ZOOM_OUT;
641 break; 541 break;
642#ifdef JPEG_RC_MENU 542#ifdef IMGVIEW_RC_MENU
643 case JPEG_RC_MENU: 543 case IMGVIEW_RC_MENU:
644#endif 544#endif
645 case JPEG_MENU: 545 case IMGVIEW_MENU:
646#ifdef USEGSLIB 546#ifdef USEGSLIB
647 grey_show(false); /* switch off greyscale overlay */ 547 grey_show(false); /* switch off greyscale overlay */
648#endif 548#endif
@@ -652,8 +552,8 @@ int scroll_bmp(struct t_disp* pdisp)
652#ifdef USEGSLIB 552#ifdef USEGSLIB
653 grey_show(true); /* switch on greyscale overlay */ 553 grey_show(true); /* switch on greyscale overlay */
654#else 554#else
655 draw_image_rect(pdisp, 0, 0, 555 draw_image_rect(info, 0, 0,
656 pdisp->width-pdisp->x, pdisp->height-pdisp->y); 556 info->width-info->x, info->height-info->y);
657 MYLCD_UPDATE(); 557 MYLCD_UPDATE();
658#endif 558#endif
659 break; 559 break;
@@ -672,7 +572,7 @@ int scroll_bmp(struct t_disp* pdisp)
672 572
673/********************* main function *************************/ 573/********************* main function *************************/
674 574
675/* callback updating a progress meter while JPEG decoding */ 575/* callback updating a progress meter while image decoding */
676void cb_progress(int current, int total) 576void cb_progress(int current, int total)
677{ 577{
678 rb->yield(); /* be nice to the other threads */ 578 rb->yield(); /* be nice to the other threads */
@@ -695,45 +595,27 @@ void cb_progress(int current, int total)
695#endif 595#endif
696} 596}
697 597
698int jpegmem(struct jpeg *p_jpg, int ds)
699{
700 int size;
701
702 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
703 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
704#ifdef HAVE_LCD_COLOR
705 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
706 {
707 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
708 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
709 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
710 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
711 }
712#endif
713 return size;
714}
715
716/* how far can we zoom in without running out of memory */ 598/* how far can we zoom in without running out of memory */
717int min_downscale(struct jpeg *p_jpg, int bufsize) 599static int min_downscale(int bufsize)
718{ 600{
719 int downscale = 8; 601 int downscale = 8;
720 602
721 if (jpegmem(p_jpg, 8) > bufsize) 603 if (img_mem(8) > bufsize)
722 return 0; /* error, too large, even 1:8 doesn't fit */ 604 return 0; /* error, too large, even 1:8 doesn't fit */
723 605
724 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize) 606 while (downscale > 1 && img_mem(downscale/2) <= bufsize)
725 downscale /= 2; 607 downscale /= 2;
726 608
727 return downscale; 609 return downscale;
728} 610}
729 611
730/* how far can we zoom out, to fit image into the LCD */ 612/* how far can we zoom out, to fit image into the LCD */
731int max_downscale(struct jpeg *p_jpg) 613static int max_downscale(struct image_info *info)
732{ 614{
733 int downscale = 1; 615 int downscale = 1;
734 616
735 while (downscale < 8 && (p_jpg->x_size/downscale > LCD_WIDTH 617 while (downscale < 8 && (info->x_size/downscale > LCD_WIDTH
736 || p_jpg->y_size/downscale > LCD_HEIGHT)) 618 || info->y_size/downscale > LCD_HEIGHT))
737 { 619 {
738 downscale *= 2; 620 downscale *= 2;
739 } 621 }
@@ -741,218 +623,40 @@ int max_downscale(struct jpeg *p_jpg)
741 return downscale; 623 return downscale;
742} 624}
743 625
744/* load image from filename. */
745int load_image(char* filename, struct jpeg *p_jpg)
746{
747 int fd;
748 int filesize;
749 unsigned char* buf_jpeg; /* compressed JPEG image */
750 int status;
751
752 fd = rb->open(filename, O_RDONLY);
753 if (fd < 0)
754 {
755 rb->splashf(HZ, "err opening %s:%d", filename, fd);
756 return PLUGIN_ERROR;
757 }
758 filesize = rb->filesize(fd);
759
760 /* allocate JPEG buffer */
761 buf_jpeg = buf;
762
763 /* we can start the decompressed images behind it */
764 buf_images = buf_root = buf + filesize;
765 buf_images_size = root_size = buf_size - filesize;
766
767 if (buf_images_size <= 0)
768 {
769 rb->close(fd);
770 return PLUGIN_OUTOFMEM;
771 }
772
773 if(!running_slideshow)
774 {
775 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
776 rb->lcd_puts(0, 0, print);
777 rb->lcd_update();
778
779 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
780 rb->lcd_puts(0, 1, print);
781 rb->lcd_update();
782 }
783
784 rb->read(fd, buf_jpeg, filesize);
785 rb->close(fd);
786
787 if(!running_slideshow)
788 {
789 rb->snprintf(print, sizeof(print), "decoding markers");
790 rb->lcd_puts(0, 2, print);
791 rb->lcd_update();
792 }
793#ifndef SIMULATOR
794 else if(immediate_ata_off)
795 {
796 /* running slideshow and time is long enough: power down disk */
797 rb->storage_sleep();
798 }
799#endif
800
801 /* process markers, unstuffing */
802 status = process_markers(buf_jpeg, filesize, p_jpg);
803
804 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
805 { /* bad format or minimum components not contained */
806 rb->splashf(HZ, "unsupported %d", status);
807 return PLUGIN_ERROR;
808 }
809
810 if (!(status & DHT)) /* if no Huffman table present: */
811 default_huff_tbl(p_jpg); /* use default */
812 build_lut(p_jpg); /* derive Huffman and other lookup-tables */
813
814 if(!running_slideshow)
815 {
816 rb->snprintf(print, sizeof(print), "image %dx%d",
817 p_jpg->x_size, p_jpg->y_size);
818 rb->lcd_puts(0, 2, print);
819 rb->lcd_update();
820 }
821
822 return PLUGIN_OK;
823}
824
825/* return decoded or cached image */
826struct t_disp* get_image(struct jpeg* p_jpg, int ds)
827{
828 int w, h; /* used to center output */
829 int size; /* decompressed image size */
830 long time; /* measured ticks */
831 int status;
832
833 struct t_disp* p_disp = &disp[ds]; /* short cut */
834
835 if (p_disp->bitmap[0] != NULL)
836 {
837 return p_disp; /* we still have it */
838 }
839
840 /* assign image buffer */
841
842 /* physical size needed for decoding */
843 size = jpegmem(p_jpg, ds);
844 if (buf_images_size <= size)
845 { /* have to discard the current */
846 int i;
847 for (i=1; i<=8; i++)
848 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
849 buf_images = buf_root; /* start again from the beginning of the buffer */
850 buf_images_size = root_size;
851 }
852
853#ifdef HAVE_LCD_COLOR
854 if (p_jpg->blocks > 1) /* colour jpeg */
855 {
856 int i;
857
858 for (i = 1; i < 3; i++)
859 {
860 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
861 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
862 p_disp->bitmap[i] = buf_images;
863 buf_images += size;
864 buf_images_size -= size;
865 }
866 p_disp->csub_x = p_jpg->subsample_x[1];
867 p_disp->csub_y = p_jpg->subsample_y[1];
868 }
869 else
870 {
871 p_disp->csub_x = p_disp->csub_y = 0;
872 p_disp->bitmap[1] = p_disp->bitmap[2] = buf_images;
873 }
874#endif
875 /* size may be less when decoded (if height is not block aligned) */
876 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
877 p_disp->bitmap[0] = buf_images;
878 buf_images += size;
879 buf_images_size -= size;
880
881 if(!running_slideshow)
882 {
883 rb->snprintf(print, sizeof(print), "decoding %d*%d",
884 p_jpg->x_size/ds, p_jpg->y_size/ds);
885 rb->lcd_puts(0, 3, print);
886 rb->lcd_update();
887 }
888
889 /* update image properties */
890 p_disp->width = p_jpg->x_size / ds;
891 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
892 p_disp->height = p_jpg->y_size / ds;
893
894 /* the actual decoding */
895 time = *rb->current_tick;
896#ifdef HAVE_ADJUSTABLE_CPU_FREQ
897 rb->cpu_boost(true);
898 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
899 rb->cpu_boost(false);
900#else
901 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
902#endif
903 if (status)
904 {
905 rb->splashf(HZ, "decode error %d", status);
906 return NULL;
907 }
908 time = *rb->current_tick - time;
909
910 if(!running_slideshow)
911 {
912 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
913 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
914 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
915 rb->lcd_update();
916 }
917
918 return p_disp;
919}
920
921
922/* set the view to the given center point, limit if necessary */ 626/* set the view to the given center point, limit if necessary */
923void set_view (struct t_disp* p_disp, int cx, int cy) 627static void set_view(struct image_info *info, int cx, int cy)
924{ 628{
925 int x, y; 629 int x, y;
926 630
927 /* plain center to available width/height */ 631 /* plain center to available width/height */
928 x = cx - MIN(LCD_WIDTH, p_disp->width) / 2; 632 x = cx - MIN(LCD_WIDTH, info->width) / 2;
929 y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2; 633 y = cy - MIN(LCD_HEIGHT, info->height) / 2;
930 634
931 /* limit against upper image size */ 635 /* limit against upper image size */
932 x = MIN(p_disp->width - LCD_WIDTH, x); 636 x = MIN(info->width - LCD_WIDTH, x);
933 y = MIN(p_disp->height - LCD_HEIGHT, y); 637 y = MIN(info->height - LCD_HEIGHT, y);
934 638
935 /* limit against negative side */ 639 /* limit against negative side */
936 x = MAX(0, x); 640 x = MAX(0, x);
937 y = MAX(0, y); 641 y = MAX(0, y);
938 642
939 p_disp->x = x; /* set the values */ 643 info->x = x; /* set the values */
940 p_disp->y = y; 644 info->y = y;
941} 645}
942 646
943/* calculate the view center based on the bitmap position */ 647/* calculate the view center based on the bitmap position */
944void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy) 648static void get_view(struct image_info *info, int *p_cx, int *p_cy)
945{ 649{
946 *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2; 650 *p_cx = info->x + MIN(LCD_WIDTH, info->width) / 2;
947 *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2; 651 *p_cy = info->y + MIN(LCD_HEIGHT, info->height) / 2;
948} 652}
949 653
950/* load, decode, display the image */ 654/* load, decode, display the image */
951int load_and_show(char* filename) 655static int load_and_show(char* filename, struct image_info *info)
952{ 656{
953 int status; 657 int status;
954 struct t_disp* p_disp; /* currenly displayed image */ 658 int cx, cy;
955 int cx, cy; /* view center */ 659 ssize_t remaining;
956 660
957#if LCD_DEPTH > 1 661#if LCD_DEPTH > 1
958 rb->lcd_set_foreground(LCD_WHITE); 662 rb->lcd_set_foreground(LCD_WHITE);
@@ -961,13 +665,13 @@ int load_and_show(char* filename)
961#endif 665#endif
962 rb->lcd_clear_display(); 666 rb->lcd_clear_display();
963 667
964 rb->memset(&disp, 0, sizeof(disp)); 668 rb->memset(info, 0, sizeof(*info));
965 rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ 669 remaining = buf_size;
966 670
967 if (rb->button_get(false) == JPEG_MENU) 671 if (rb->button_get(false) == IMGVIEW_MENU)
968 status = PLUGIN_ABORT; 672 status = PLUGIN_ABORT;
969 else 673 else
970 status = load_image(filename, &jpg); 674 status = load_image(filename, info, buf, &remaining);
971 675
972 if (status == PLUGIN_OUTOFMEM) 676 if (status == PLUGIN_OUTOFMEM)
973 { 677 {
@@ -993,18 +697,18 @@ int load_and_show(char* filename)
993 int button = rb->button_get(true); 697 int button = rb->button_get(true);
994 switch(button) 698 switch(button)
995 { 699 {
996 case JPEG_ZOOM_IN: 700 case IMGVIEW_ZOOM_IN:
997 plug_buf = false; 701 plug_buf = false;
998 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size); 702 buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
999 /*try again this file, now using the audio buffer */ 703 /*try again this file, now using the audio buffer */
1000 return PLUGIN_OTHER; 704 return PLUGIN_OTHER;
1001#ifdef JPEG_RC_MENU 705#ifdef IMGVIEW_RC_MENU
1002 case JPEG_RC_MENU: 706 case IMGVIEW_RC_MENU:
1003#endif 707#endif
1004 case JPEG_MENU: 708 case IMGVIEW_MENU:
1005 return PLUGIN_OK; 709 return PLUGIN_OK;
1006 710
1007 case JPEG_LEFT: 711 case IMGVIEW_LEFT:
1008 if(entries>1) 712 if(entries>1)
1009 { 713 {
1010 rb->lcd_clear_display(); 714 rb->lcd_clear_display();
@@ -1012,7 +716,7 @@ int load_and_show(char* filename)
1012 } 716 }
1013 break; 717 break;
1014 718
1015 case JPEG_RIGHT: 719 case IMGVIEW_RIGHT:
1016 if(entries>1) 720 if(entries>1)
1017 { 721 {
1018 rb->lcd_clear_display(); 722 rb->lcd_clear_display();
@@ -1045,43 +749,49 @@ int load_and_show(char* filename)
1045 return PLUGIN_OK; 749 return PLUGIN_OK;
1046 } 750 }
1047 751
1048 ds_max = max_downscale(&jpg); /* check display constraint */ 752 ds_max = max_downscale(info); /* check display constraint */
1049 ds_min = min_downscale(&jpg, buf_images_size); /* check memory constraint */ 753 ds_min = min_downscale(remaining); /* check memory constraint */
1050 if (ds_min == 0) 754 if (ds_min == 0)
1051 { 755 {
756#if UNSCALED_IS_AVAILABLE
757 /* Can not resize the image but original one is available, so use it. */
758 ds_min = ds_max = 1;
759#else
760 /* not enough memory to decode image. */
1052 rb->splash(HZ, "too large"); 761 rb->splash(HZ, "too large");
1053 file_pt[curfile] = NULL; 762 file_pt[curfile] = NULL;
1054 return change_filename(direction); 763 return change_filename(direction);
764#endif
1055 } 765 }
1056 else if (ds_max < ds_min) 766 else if (ds_max < ds_min)
1057 ds_max = ds_min; 767 ds_max = ds_min;
1058 768
1059 ds = ds_max; /* initialize setting */ 769 ds = ds_max; /* initialize setting */
1060 cx = jpg.x_size/ds/2; /* center the view */ 770 cx = info->x_size/ds/2; /* center the view */
1061 cy = jpg.y_size/ds/2; 771 cy = info->y_size/ds/2;
1062 772
1063 do /* loop the image prepare and decoding when zoomed */ 773 do /* loop the image prepare and decoding when zoomed */
1064 { 774 {
1065 p_disp = get_image(&jpg, ds); /* decode or fetch from cache */ 775 status = get_image(info, ds); /* decode or fetch from cache */
1066 if (p_disp == NULL) 776 if (status == PLUGIN_ERROR)
1067 { 777 {
1068 file_pt[curfile] = NULL; 778 file_pt[curfile] = NULL;
1069 return change_filename(direction); 779 return change_filename(direction);
1070 } 780 }
1071 781
1072 set_view(p_disp, cx, cy); 782 set_view(info, cx, cy);
1073 783
1074 if(!running_slideshow) 784 if(!running_slideshow)
1075 { 785 {
1076 rb->snprintf(print, sizeof(print), "showing %dx%d", 786 rb->snprintf(print, sizeof(print), "showing %dx%d",
1077 p_disp->width, p_disp->height); 787 info->width, info->height);
1078 rb->lcd_puts(0, 3, print); 788 rb->lcd_puts(0, 3, print);
1079 rb->lcd_update(); 789 rb->lcd_update();
1080 } 790 }
1081 791
1082 MYLCD(clear_display)(); 792 MYLCD(clear_display)();
1083 draw_image_rect(p_disp, 0, 0, 793 draw_image_rect(info, 0, 0,
1084 p_disp->width-p_disp->x, p_disp->height-p_disp->y); 794 info->width-info->x, info->height-info->y);
1085 MYLCD_UPDATE(); 795 MYLCD_UPDATE();
1086 796
1087#ifdef USEGSLIB 797#ifdef USEGSLIB
@@ -1093,15 +803,25 @@ int load_and_show(char* filename)
1093 */ 803 */
1094 while (1) 804 while (1)
1095 { 805 {
1096 status = scroll_bmp(p_disp); 806 status = scroll_bmp(info);
1097 if (status == ZOOM_IN) 807 if (status == ZOOM_IN)
1098 { 808 {
809#if UNSCALED_IS_AVAILABLE
810 if (ds > 1)
811#else
1099 if (ds > ds_min) 812 if (ds > ds_min)
813#endif
1100 { 814 {
1101 ds /= 2; /* reduce downscaling to zoom in */ 815#if UNSCALED_IS_AVAILABLE
1102 get_view(p_disp, &cx, &cy); 816 /* if 1/1 is always available, jump ds from ds_min to 1. */
1103 cx *= 2; /* prepare the position in the new image */ 817 int zoom = (ds == ds_min)? ds_min: 2;
1104 cy *= 2; 818#else
819 const int zoom = 2;
820#endif
821 ds /= zoom; /* reduce downscaling to zoom in */
822 get_view(info, &cx, &cy);
823 cx *= zoom; /* prepare the position in the new image */
824 cy *= zoom;
1105 } 825 }
1106 else 826 else
1107 continue; 827 continue;
@@ -1111,10 +831,16 @@ int load_and_show(char* filename)
1111 { 831 {
1112 if (ds < ds_max) 832 if (ds < ds_max)
1113 { 833 {
1114 ds *= 2; /* increase downscaling to zoom out */ 834#if UNSCALED_IS_AVAILABLE
1115 get_view(p_disp, &cx, &cy); 835 /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */
1116 cx /= 2; /* prepare the position in the new image */ 836 int zoom = (ds < ds_min)? ds_min: 2;
1117 cy /= 2; 837#else
838 const int zoom = 2;
839#endif
840 ds *= zoom; /* increase downscaling to zoom out */
841 get_view(info, &cx, &cy);
842 cx /= zoom; /* prepare the position in the new image */
843 cy /= zoom;
1118 } 844 }
1119 else 845 else
1120 continue; 846 continue;
@@ -1160,7 +886,7 @@ enum plugin_status plugin_start(const void* parameter)
1160 886
1161 if(!entries) return PLUGIN_ERROR; 887 if(!entries) return PLUGIN_ERROR;
1162 888
1163#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR) 889#if PLUGIN_BUFFER_SIZE >= MIN_MEM
1164 if(!rb->audio_status()) 890 if(!rb->audio_status())
1165 { 891 {
1166 plug_buf = false; 892 plug_buf = false;
@@ -1181,28 +907,28 @@ enum plugin_status plugin_start(const void* parameter)
1181 907
1182 /* should be ok to just load settings since the plugin itself has 908 /* should be ok to just load settings since the plugin itself has
1183 just been loaded from disk and the drive should be spinning */ 909 just been loaded from disk and the drive should be spinning */
1184 configfile_load(JPEG_CONFIGFILE, jpeg_config, 910 configfile_load(IMGVIEW_CONFIGFILE, config,
1185 ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION); 911 ARRAYLEN(config), IMGVIEW_SETTINGS_MINVERSION);
1186 old_settings = jpeg_settings; 912 rb->memcpy(&old_settings, &settings, sizeof (settings));
1187 913
1188 /* Turn off backlight timeout */ 914 /* Turn off backlight timeout */
1189 backlight_force_on(); /* backlight control in lib/helper.c */ 915 backlight_force_on(); /* backlight control in lib/helper.c */
1190 916
1191 do 917 do
1192 { 918 {
1193 condition = load_and_show(np_file); 919 condition = load_and_show(np_file, &image_info);
1194 } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED 920 } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
1195 && condition != PLUGIN_ERROR); 921 && condition != PLUGIN_ERROR);
1196 922
1197 if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings))) 923 if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
1198 { 924 {
1199 /* Just in case drive has to spin, keep it from looking locked */ 925 /* Just in case drive has to spin, keep it from looking locked */
1200 rb->splash(0, "Saving Settings"); 926 rb->splash(0, "Saving Settings");
1201 configfile_save(JPEG_CONFIGFILE, jpeg_config, 927 configfile_save(IMGVIEW_CONFIGFILE, config,
1202 ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION); 928 ARRAYLEN(config), IMGVIEW_SETTINGS_VERSION);
1203 } 929 }
1204 930
1205#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE) 931#ifdef DISK_SPINDOWN
1206 /* set back ata spindown time in case we changed it */ 932 /* set back ata spindown time in case we changed it */
1207 rb->storage_spindown(rb->global_settings->disk_spindown); 933 rb->storage_spindown(rb->global_settings->disk_spindown);
1208#endif 934#endif
diff --git a/apps/plugins/imageviewer/imageviewer.h b/apps/plugins/imageviewer/imageviewer.h
new file mode 100644
index 0000000000..3851e1f2a2
--- /dev/null
+++ b/apps/plugins/imageviewer/imageviewer.h
@@ -0,0 +1,414 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * user intereface of image viewers (jpeg, png, etc.)
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _IMGVIEW_IMGVIEW_H
23#define _IMGVIEW_IMGVIEW_H
24
25#include "plugin.h"
26
27/* variable button definitions */
28#if CONFIG_KEYPAD == RECORDER_PAD
29#define IMGVIEW_ZOOM_IN BUTTON_PLAY
30#define IMGVIEW_ZOOM_OUT BUTTON_ON
31#define IMGVIEW_UP BUTTON_UP
32#define IMGVIEW_DOWN BUTTON_DOWN
33#define IMGVIEW_LEFT BUTTON_LEFT
34#define IMGVIEW_RIGHT BUTTON_RIGHT
35#define IMGVIEW_NEXT BUTTON_F3
36#define IMGVIEW_PREVIOUS BUTTON_F2
37#define IMGVIEW_MENU BUTTON_OFF
38
39#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
40#define IMGVIEW_ZOOM_IN BUTTON_SELECT
41#define IMGVIEW_ZOOM_OUT BUTTON_ON
42#define IMGVIEW_UP BUTTON_UP
43#define IMGVIEW_DOWN BUTTON_DOWN
44#define IMGVIEW_LEFT BUTTON_LEFT
45#define IMGVIEW_RIGHT BUTTON_RIGHT
46#define IMGVIEW_NEXT BUTTON_F3
47#define IMGVIEW_PREVIOUS BUTTON_F2
48#define IMGVIEW_MENU BUTTON_OFF
49
50#elif CONFIG_KEYPAD == ONDIO_PAD
51#define IMGVIEW_ZOOM_PRE BUTTON_MENU
52#define IMGVIEW_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
53#define IMGVIEW_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
54#define IMGVIEW_UP BUTTON_UP
55#define IMGVIEW_DOWN BUTTON_DOWN
56#define IMGVIEW_LEFT BUTTON_LEFT
57#define IMGVIEW_RIGHT BUTTON_RIGHT
58#define IMGVIEW_NEXT (BUTTON_MENU | BUTTON_RIGHT)
59#define IMGVIEW_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
60#define IMGVIEW_MENU BUTTON_OFF
61
62#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
63 (CONFIG_KEYPAD == IRIVER_H300_PAD)
64#define IMGVIEW_ZOOM_IN BUTTON_SELECT
65#define IMGVIEW_ZOOM_OUT BUTTON_MODE
66#define IMGVIEW_UP BUTTON_UP
67#define IMGVIEW_DOWN BUTTON_DOWN
68#define IMGVIEW_LEFT BUTTON_LEFT
69#define IMGVIEW_RIGHT BUTTON_RIGHT
70#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
71#define IMGVIEW_NEXT BUTTON_ON
72#define IMGVIEW_PREVIOUS BUTTON_REC
73#else
74#define IMGVIEW_NEXT BUTTON_REC
75#define IMGVIEW_PREVIOUS BUTTON_ON
76#endif
77#define IMGVIEW_MENU BUTTON_OFF
78#define IMGVIEW_RC_MENU BUTTON_RC_STOP
79
80#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
81 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
82#define IMGVIEW_ZOOM_IN BUTTON_SCROLL_FWD
83#define IMGVIEW_ZOOM_OUT BUTTON_SCROLL_BACK
84#define IMGVIEW_UP BUTTON_MENU
85#define IMGVIEW_DOWN BUTTON_PLAY
86#define IMGVIEW_LEFT BUTTON_LEFT
87#define IMGVIEW_RIGHT BUTTON_RIGHT
88#define IMGVIEW_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
89#define IMGVIEW_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
90#define IMGVIEW_MENU (BUTTON_SELECT | BUTTON_MENU)
91
92#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
93#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
94#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
95#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
96#define IMGVIEW_UP BUTTON_UP
97#define IMGVIEW_DOWN BUTTON_DOWN
98#define IMGVIEW_LEFT BUTTON_LEFT
99#define IMGVIEW_RIGHT BUTTON_RIGHT
100#define IMGVIEW_NEXT BUTTON_PLAY
101#define IMGVIEW_PREVIOUS BUTTON_REC
102#define IMGVIEW_MENU BUTTON_POWER
103
104#elif CONFIG_KEYPAD == GIGABEAT_PAD
105#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
106#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
107#define IMGVIEW_UP BUTTON_UP
108#define IMGVIEW_DOWN BUTTON_DOWN
109#define IMGVIEW_LEFT BUTTON_LEFT
110#define IMGVIEW_RIGHT BUTTON_RIGHT
111#define IMGVIEW_NEXT (BUTTON_A | BUTTON_RIGHT)
112#define IMGVIEW_PREVIOUS (BUTTON_A | BUTTON_LEFT)
113#define IMGVIEW_MENU BUTTON_MENU
114
115#elif CONFIG_KEYPAD == SANSA_E200_PAD
116#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
117#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
118#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
119#define IMGVIEW_UP BUTTON_UP
120#define IMGVIEW_DOWN BUTTON_DOWN
121#define IMGVIEW_LEFT BUTTON_LEFT
122#define IMGVIEW_RIGHT BUTTON_RIGHT
123#define IMGVIEW_NEXT BUTTON_SCROLL_FWD
124#define IMGVIEW_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
125#define IMGVIEW_PREVIOUS BUTTON_SCROLL_BACK
126#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
127#define IMGVIEW_MENU BUTTON_POWER
128#define IMGVIEW_SLIDE_SHOW BUTTON_REC
129
130#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
131#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
132#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
133#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
134#define IMGVIEW_UP BUTTON_UP
135#define IMGVIEW_DOWN BUTTON_DOWN
136#define IMGVIEW_LEFT BUTTON_LEFT
137#define IMGVIEW_RIGHT BUTTON_RIGHT
138#define IMGVIEW_NEXT BUTTON_SCROLL_FWD
139#define IMGVIEW_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
140#define IMGVIEW_PREVIOUS BUTTON_SCROLL_BACK
141#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
142#define IMGVIEW_MENU (BUTTON_HOME|BUTTON_REPEAT)
143
144#elif CONFIG_KEYPAD == SANSA_C200_PAD
145#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
146#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
147#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
148#define IMGVIEW_UP BUTTON_UP
149#define IMGVIEW_DOWN BUTTON_DOWN
150#define IMGVIEW_LEFT BUTTON_LEFT
151#define IMGVIEW_RIGHT BUTTON_RIGHT
152#define IMGVIEW_NEXT BUTTON_VOL_UP
153#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
154#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
155#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
156#define IMGVIEW_MENU BUTTON_POWER
157#define IMGVIEW_SLIDE_SHOW BUTTON_REC
158
159#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
160#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
161#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
162#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
163#define IMGVIEW_UP BUTTON_UP
164#define IMGVIEW_DOWN BUTTON_DOWN
165#define IMGVIEW_LEFT BUTTON_LEFT
166#define IMGVIEW_RIGHT BUTTON_RIGHT
167#define IMGVIEW_NEXT BUTTON_VOL_UP
168#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
169#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
170#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
171#define IMGVIEW_MENU BUTTON_POWER
172#define IMGVIEW_SLIDE_SHOW BUTTON_HOME
173
174#elif CONFIG_KEYPAD == SANSA_M200_PAD
175#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
176#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
177#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
178#define IMGVIEW_UP BUTTON_UP
179#define IMGVIEW_DOWN BUTTON_DOWN
180#define IMGVIEW_LEFT BUTTON_LEFT
181#define IMGVIEW_RIGHT BUTTON_RIGHT
182#define IMGVIEW_NEXT BUTTON_VOL_UP
183#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
184#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
185#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
186#define IMGVIEW_MENU BUTTON_POWER
187#define IMGVIEW_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
188
189#elif CONFIG_KEYPAD == IRIVER_H10_PAD
190#define IMGVIEW_ZOOM_PRE BUTTON_PLAY
191#define IMGVIEW_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
192#define IMGVIEW_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
193#define IMGVIEW_UP BUTTON_SCROLL_UP
194#define IMGVIEW_DOWN BUTTON_SCROLL_DOWN
195#define IMGVIEW_LEFT BUTTON_LEFT
196#define IMGVIEW_RIGHT BUTTON_RIGHT
197#define IMGVIEW_NEXT BUTTON_FF
198#define IMGVIEW_PREVIOUS BUTTON_REW
199#define IMGVIEW_MENU BUTTON_POWER
200
201#elif CONFIG_KEYPAD == MROBE500_PAD
202#define IMGVIEW_MENU BUTTON_POWER
203
204#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
205#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
206#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
207#define IMGVIEW_UP BUTTON_UP
208#define IMGVIEW_DOWN BUTTON_DOWN
209#define IMGVIEW_LEFT BUTTON_LEFT
210#define IMGVIEW_RIGHT BUTTON_RIGHT
211#define IMGVIEW_NEXT BUTTON_NEXT
212#define IMGVIEW_PREVIOUS BUTTON_PREV
213#define IMGVIEW_MENU BUTTON_MENU
214
215#elif CONFIG_KEYPAD == MROBE100_PAD
216#define IMGVIEW_ZOOM_IN BUTTON_SELECT
217#define IMGVIEW_ZOOM_OUT BUTTON_PLAY
218#define IMGVIEW_UP BUTTON_UP
219#define IMGVIEW_DOWN BUTTON_DOWN
220#define IMGVIEW_LEFT BUTTON_LEFT
221#define IMGVIEW_RIGHT BUTTON_RIGHT
222#define IMGVIEW_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
223#define IMGVIEW_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
224#define IMGVIEW_MENU BUTTON_MENU
225
226#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
227#define IMGVIEW_ZOOM_PRE BUTTON_RC_PLAY
228#define IMGVIEW_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
229#define IMGVIEW_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
230#define IMGVIEW_UP BUTTON_RC_VOL_UP
231#define IMGVIEW_DOWN BUTTON_RC_VOL_DOWN
232#define IMGVIEW_LEFT BUTTON_RC_REW
233#define IMGVIEW_RIGHT BUTTON_RC_FF
234#define IMGVIEW_NEXT BUTTON_RC_MODE
235#define IMGVIEW_PREVIOUS BUTTON_RC_MENU
236#define IMGVIEW_MENU BUTTON_RC_REC
237
238#elif CONFIG_KEYPAD == COWON_D2_PAD
239
240#elif CONFIG_KEYPAD == IAUDIO67_PAD
241#define IMGVIEW_ZOOM_IN BUTTON_VOLUP
242#define IMGVIEW_ZOOM_OUT BUTTON_VOLDOWN
243#define IMGVIEW_UP BUTTON_STOP
244#define IMGVIEW_DOWN BUTTON_PLAY
245#define IMGVIEW_LEFT BUTTON_LEFT
246#define IMGVIEW_RIGHT BUTTON_RIGHT
247#define IMGVIEW_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
248#define IMGVIEW_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
249#define IMGVIEW_MENU BUTTON_MENU
250
251#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
252
253#define IMGVIEW_ZOOM_IN BUTTON_PLAY
254#define IMGVIEW_ZOOM_OUT BUTTON_CUSTOM
255#define IMGVIEW_UP BUTTON_UP
256#define IMGVIEW_DOWN BUTTON_DOWN
257#define IMGVIEW_LEFT BUTTON_LEFT
258#define IMGVIEW_RIGHT BUTTON_RIGHT
259#define IMGVIEW_NEXT BUTTON_SELECT
260#define IMGVIEW_PREVIOUS BUTTON_BACK
261#define IMGVIEW_MENU BUTTON_MENU
262
263#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
264#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
265#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
266#define IMGVIEW_UP BUTTON_UP
267#define IMGVIEW_DOWN BUTTON_DOWN
268#define IMGVIEW_LEFT BUTTON_LEFT
269#define IMGVIEW_RIGHT BUTTON_RIGHT
270#define IMGVIEW_NEXT BUTTON_VIEW
271#define IMGVIEW_PREVIOUS BUTTON_PLAYLIST
272#define IMGVIEW_MENU BUTTON_MENU
273
274#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
275#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
276#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
277#define IMGVIEW_UP BUTTON_UP
278#define IMGVIEW_DOWN BUTTON_DOWN
279#define IMGVIEW_LEFT BUTTON_PREV
280#define IMGVIEW_RIGHT BUTTON_NEXT
281#define IMGVIEW_NEXT BUTTON_RIGHT
282#define IMGVIEW_PREVIOUS BUTTON_LEFT
283#define IMGVIEW_MENU BUTTON_MENU
284
285#elif CONFIG_KEYPAD == ONDAVX747_PAD
286#elif CONFIG_KEYPAD == ONDAVX777_PAD
287
288#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
289#define IMGVIEW_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
290#define IMGVIEW_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
291#define IMGVIEW_UP BUTTON_UP
292#define IMGVIEW_DOWN BUTTON_DOWN
293#define IMGVIEW_LEFT BUTTON_LEFT
294#define IMGVIEW_RIGHT BUTTON_RIGHT
295#define IMGVIEW_NEXT BUTTON_FFWD
296#define IMGVIEW_PREVIOUS BUTTON_REW
297#define IMGVIEW_MENU BUTTON_PLAY
298
299#else
300#error No keymap defined!
301#endif
302
303#ifdef HAVE_TOUCHSCREEN
304#ifndef IMGVIEW_UP
305#define IMGVIEW_UP BUTTON_TOPMIDDLE
306#endif
307#ifndef IMGVIEW_DOWN
308#define IMGVIEW_DOWN BUTTON_BOTTOMMIDDLE
309#endif
310#ifndef IMGVIEW_LEFT
311#define IMGVIEW_LEFT BUTTON_MIDLEFT
312#endif
313#ifndef IMGVIEW_RIGHT
314#define IMGVIEW_RIGHT BUTTON_MIDRIGHT
315#endif
316#ifndef IMGVIEW_ZOOM_IN
317#define IMGVIEW_ZOOM_IN BUTTON_TOPRIGHT
318#endif
319#ifndef IMGVIEW_ZOOM_OUT
320#define IMGVIEW_ZOOM_OUT BUTTON_TOPLEFT
321#endif
322#ifndef IMGVIEW_MENU
323#define IMGVIEW_MENU (BUTTON_CENTER|BUTTON_REL)
324#endif
325#ifndef IMGVIEW_NEXT
326#define IMGVIEW_NEXT BUTTON_BOTTOMRIGHT
327#endif
328#ifndef IMGVIEW_PREVIOUS
329#define IMGVIEW_PREVIOUS BUTTON_BOTTOMLEFT
330#endif
331#endif
332
333/* different graphics libraries */
334#if LCD_DEPTH < 8
335#define USEGSLIB
336#include <lib/grey.h>
337#define MYLCD(fn) grey_ub_ ## fn
338#define MYLCD_UPDATE()
339#define MYXLCD(fn) grey_ub_ ## fn
340#else
341#include <lib/xlcd.h>
342#define MYLCD(fn) rb->lcd_ ## fn
343#define MYLCD_UPDATE() rb->lcd_update();
344#define MYXLCD(fn) xlcd_ ## fn
345#endif
346
347/* Min memory allowing us to use the plugin buffer
348 * and thus not stopping the music
349 * *Very* rough estimation:
350 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
351 * + 30k code size = 70 000
352 * + 50k min for image = 120 000
353 */
354#define MIN_MEM 120000
355
356/* State code for output with return. */
357#define PLUGIN_OTHER 10
358#define PLUGIN_ABORT 11
359#define PLUGIN_OUTOFMEM 12
360
361#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
362#define DISK_SPINDOWN
363#endif
364
365/* Settings. jpeg needs these */
366struct imgview_settings
367{
368 /* include all settings for varias decoders as using same setting file. */
369#ifdef HAVE_LCD_COLOR
370 int jpeg_colour_mode;
371 int jpeg_dither_mode;
372#endif
373 int ss_timeout;
374};
375
376/* structure passed to decoder. */
377struct image_info {
378 int x_size, y_size; /* set size of loaded image in load_image(). */
379 int width, height; /* set size of resized image in get_image(). */
380 int x, y; /* display position */
381 void *data; /* use freely in decoder. not touched in ui. */
382};
383
384/* callback updating a progress meter while image decoding */
385extern void cb_progress(int current, int total);
386
387extern struct imgview_settings settings;
388extern bool slideshow_enabled;
389extern bool running_slideshow;
390#ifdef DISK_SPINDOWN
391extern bool immediate_ata_off;
392#endif
393#if PLUGIN_BUFFER_SIZE >= MIN_MEM
394extern bool plug_buf;
395#endif
396
397/* functions needed to be implemented in each image decoders. */
398/* return true if ext is supported by the decoder. */
399extern bool img_ext(const char *ext);
400/* return needed size of buffer to store downscaled image by ds */
401extern int img_mem(int ds);
402/* load image from filename. set width and height of info properly. alos, set
403 * buf_size to remaining size of buf after load image. it is used to caluclate
404 * min downscale. */
405extern int load_image(char *filename, struct image_info *info,
406 unsigned char *buf, ssize_t *buf_size);
407/* downscale loaded image by ds. note that buf to store reszied image is not
408 * provided. return PLUGIN_ERROR for error. ui will skip to next image. */
409extern int get_image(struct image_info *info, int ds);
410/* draw part of image */
411extern void draw_image_rect(struct image_info *info,
412 int x, int y, int width, int height);
413
414#endif /* _IMGVIEW_IMGVIEW_H */
diff --git a/apps/plugins/imageviewer/imageviewer.make b/apps/plugins/imageviewer/imageviewer.make
new file mode 100644
index 0000000000..76af8d24e5
--- /dev/null
+++ b/apps/plugins/imageviewer/imageviewer.make
@@ -0,0 +1,16 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10IMGVSRCDIR := $(APPSDIR)/plugins/imageviewer
11IMGVBUILDDIR := $(BUILDDIR)/apps/plugins/imageviewer
12
13# include actual viewer's make file
14IMGVSUBDIRS := $(call preprocess, $(IMGVSRCDIR)/SUBDIRS)
15$(foreach dir,$(IMGVSUBDIRS),$(eval include $(dir)/$(notdir $(dir)).make))
16
diff --git a/apps/plugins/jpeg/SOURCES b/apps/plugins/imageviewer/jpeg/SOURCES
index c3524001e2..8e80722a5a 100644
--- a/apps/plugins/jpeg/SOURCES
+++ b/apps/plugins/imageviewer/jpeg/SOURCES
@@ -1,3 +1,4 @@
1jpeg_ui.c
1jpeg.c 2jpeg.c
2jpeg_decoder.c 3jpeg_decoder.c
3#ifdef HAVE_LCD_COLOR 4#ifdef HAVE_LCD_COLOR
diff --git a/apps/plugins/imageviewer/jpeg/jpeg.c b/apps/plugins/imageviewer/jpeg/jpeg.c
new file mode 100644
index 0000000000..b4ac6c0fce
--- /dev/null
+++ b/apps/plugins/imageviewer/jpeg/jpeg.c
@@ -0,0 +1,308 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* JPEG image viewer
11* (This is a real mess if it has to be coded in one single C file)
12*
13* File scrolling addition (C) 2005 Alexander Spyridakis
14* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
15* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
17*
18* This program is free software; you can redistribute it and/or
19* modify it under the terms of the GNU General Public License
20* as published by the Free Software Foundation; either version 2
21* of the License, or (at your option) any later version.
22*
23* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24* KIND, either express or implied.
25*
26****************************************************************************/
27
28#include "plugin.h"
29
30#include "../imageviewer.h"
31#include "jpeg_decoder.h"
32
33#ifdef HAVE_LCD_COLOR
34#include "yuv2rgb.h"
35#endif
36
37/**************** begin Application ********************/
38
39/************************* Types ***************************/
40
41struct t_disp
42{
43#ifdef HAVE_LCD_COLOR
44 unsigned char* bitmap[3]; /* Y, Cr, Cb */
45 int csub_x, csub_y;
46#else
47 unsigned char* bitmap[1]; /* Y only */
48#endif
49 int stride;
50};
51
52/************************* Globals ***************************/
53
54/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
55static struct t_disp disp[9];
56
57/* my memory pool (from the mp3 buffer) */
58static char print[32]; /* use a common snprintf() buffer */
59
60/* the root of the images, hereafter are decompresed ones */
61static unsigned char* buf_root;
62static int root_size;
63
64/* up to here currently used by image(s) */
65static unsigned char* buf_images;
66static ssize_t buf_images_size;
67
68static struct jpeg jpg; /* too large for stack */
69
70/************************* Implementation ***************************/
71
72bool img_ext(const char *ext)
73{
74 if(!ext)
75 return false;
76 if(!rb->strcasecmp(ext,".jpg") ||
77 !rb->strcasecmp(ext,".jpe") ||
78 !rb->strcasecmp(ext,".jpeg"))
79 return true;
80 else
81 return false;
82}
83
84void draw_image_rect(struct image_info *info,
85 int x, int y, int width, int height)
86{
87 struct t_disp* pdisp = (struct t_disp*)info->data;
88#ifdef HAVE_LCD_COLOR
89 yuv_bitmap_part(
90 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
91 info->x + x, info->y + y, pdisp->stride,
92 x + MAX(0, (LCD_WIDTH - info->width) / 2),
93 y + MAX(0, (LCD_HEIGHT - info->height) / 2),
94 width, height,
95 settings.jpeg_colour_mode, settings.jpeg_dither_mode);
96#else
97 MYXLCD(gray_bitmap_part)(
98 pdisp->bitmap[0], info->x + x, info->y + y, pdisp->stride,
99 x + MAX(0, (LCD_WIDTH-info->width)/2),
100 y + MAX(0, (LCD_HEIGHT-info->height)/2),
101 width, height);
102#endif
103}
104
105int img_mem(int ds)
106{
107 int size;
108 struct jpeg *p_jpg = &jpg;
109
110 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
111 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
112#ifdef HAVE_LCD_COLOR
113 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
114 {
115 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
116 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
117 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
118 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
119 }
120#endif
121 return size;
122}
123
124int load_image(char *filename, struct image_info *info,
125 unsigned char *buf, ssize_t *buf_size)
126{
127 int fd;
128 int filesize;
129 unsigned char* buf_jpeg; /* compressed JPEG image */
130 int status;
131 struct jpeg *p_jpg = &jpg;
132
133 rb->memset(&disp, 0, sizeof(disp));
134 rb->memset(&jpg, 0, sizeof(jpg));
135
136 fd = rb->open(filename, O_RDONLY);
137 if (fd < 0)
138 {
139 rb->splashf(HZ, "err opening %s:%d", filename, fd);
140 return PLUGIN_ERROR;
141 }
142 filesize = rb->filesize(fd);
143
144 /* allocate JPEG buffer */
145 buf_jpeg = buf;
146
147 /* we can start the decompressed images behind it */
148 buf_images = buf_root = buf + filesize;
149 buf_images_size = root_size = *buf_size - filesize;
150
151 if (buf_images_size <= 0)
152 {
153 rb->close(fd);
154 return PLUGIN_OUTOFMEM;
155 }
156
157 if(!running_slideshow)
158 {
159 rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
160 rb->lcd_puts(0, 0, print);
161 rb->lcd_update();
162
163 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
164 rb->lcd_puts(0, 1, print);
165 rb->lcd_update();
166 }
167
168 rb->read(fd, buf_jpeg, filesize);
169 rb->close(fd);
170
171 if(!running_slideshow)
172 {
173 rb->snprintf(print, sizeof(print), "decoding markers");
174 rb->lcd_puts(0, 2, print);
175 rb->lcd_update();
176 }
177#ifdef DISK_SPINDOWN
178 else if(immediate_ata_off)
179 {
180 /* running slideshow and time is long enough: power down disk */
181 rb->storage_sleep();
182 }
183#endif
184
185 /* process markers, unstuffing */
186 status = process_markers(buf_jpeg, filesize, p_jpg);
187
188 if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
189 { /* bad format or minimum components not contained */
190 rb->splashf(HZ, "unsupported %d", status);
191 return PLUGIN_ERROR;
192 }
193
194 if (!(status & DHT)) /* if no Huffman table present: */
195 default_huff_tbl(p_jpg); /* use default */
196 build_lut(p_jpg); /* derive Huffman and other lookup-tables */
197
198 if(!running_slideshow)
199 {
200 rb->snprintf(print, sizeof(print), "image %dx%d",
201 p_jpg->x_size, p_jpg->y_size);
202 rb->lcd_puts(0, 2, print);
203 rb->lcd_update();
204 }
205
206 info->x_size = p_jpg->x_size;
207 info->y_size = p_jpg->y_size;
208 *buf_size = buf_images_size;
209 return PLUGIN_OK;
210}
211
212int get_image(struct image_info *info, int ds)
213{
214 int w, h; /* used to center output */
215 int size; /* decompressed image size */
216 long time; /* measured ticks */
217 int status;
218 struct jpeg* p_jpg = &jpg;
219 struct t_disp* p_disp = &disp[ds]; /* short cut */
220
221 info->width = p_jpg->x_size / ds;
222 info->height = p_jpg->y_size / ds;
223 info->data = p_disp;
224
225 if (p_disp->bitmap[0] != NULL)
226 {
227 /* we still have it */
228 return PLUGIN_OK;
229 }
230
231 /* assign image buffer */
232
233 /* physical size needed for decoding */
234 size = img_mem(ds);
235 if (buf_images_size <= size)
236 { /* have to discard the current */
237 int i;
238 for (i=1; i<=8; i++)
239 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
240 buf_images = buf_root; /* start again from the beginning of the buffer */
241 buf_images_size = root_size;
242 }
243
244#ifdef HAVE_LCD_COLOR
245 if (p_jpg->blocks > 1) /* colour jpeg */
246 {
247 int i;
248
249 for (i = 1; i < 3; i++)
250 {
251 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
252 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
253 p_disp->bitmap[i] = buf_images;
254 buf_images += size;
255 buf_images_size -= size;
256 }
257 p_disp->csub_x = p_jpg->subsample_x[1];
258 p_disp->csub_y = p_jpg->subsample_y[1];
259 }
260 else
261 {
262 p_disp->csub_x = p_disp->csub_y = 0;
263 p_disp->bitmap[1] = p_disp->bitmap[2] = buf_images;
264 }
265#endif
266 /* size may be less when decoded (if height is not block aligned) */
267 size = (p_jpg->x_phys/ds) * (p_jpg->y_size/ds);
268 p_disp->bitmap[0] = buf_images;
269 buf_images += size;
270 buf_images_size -= size;
271
272 if(!running_slideshow)
273 {
274 rb->snprintf(print, sizeof(print), "decoding %d*%d",
275 p_jpg->x_size/ds, p_jpg->y_size/ds);
276 rb->lcd_puts(0, 3, print);
277 rb->lcd_update();
278 }
279
280 /* update image properties */
281 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
282
283 /* the actual decoding */
284 time = *rb->current_tick;
285#ifdef HAVE_ADJUSTABLE_CPU_FREQ
286 rb->cpu_boost(true);
287 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
288 rb->cpu_boost(false);
289#else
290 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
291#endif
292 if (status)
293 {
294 rb->splashf(HZ, "decode error %d", status);
295 return PLUGIN_ERROR;
296 }
297 time = *rb->current_tick - time;
298
299 if(!running_slideshow)
300 {
301 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
302 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
303 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
304 rb->lcd_update();
305 }
306
307 return PLUGIN_OK;
308}
diff --git a/apps/plugins/jpeg/jpeg.make b/apps/plugins/imageviewer/jpeg/jpeg.make
index 15168dc4fb..caf37fc74c 100644
--- a/apps/plugins/jpeg/jpeg.make
+++ b/apps/plugins/imageviewer/jpeg/jpeg.make
@@ -7,8 +7,8 @@
7# $Id$ 7# $Id$
8# 8#
9 9
10JPEGSRCDIR := $(APPSDIR)/plugins/jpeg 10JPEGSRCDIR := $(IMGVSRCDIR)/jpeg
11JPEGBUILDDIR := $(BUILDDIR)/apps/plugins/jpeg 11JPEGBUILDDIR := $(IMGVBUILDDIR)/jpeg
12 12
13ROCKS += $(JPEGBUILDDIR)/jpeg.rock 13ROCKS += $(JPEGBUILDDIR)/jpeg.rock
14 14
diff --git a/apps/plugins/jpeg/jpeg_decoder.c b/apps/plugins/imageviewer/jpeg/jpeg_decoder.c
index c90bff87a4..c90bff87a4 100644
--- a/apps/plugins/jpeg/jpeg_decoder.c
+++ b/apps/plugins/imageviewer/jpeg/jpeg_decoder.c
diff --git a/apps/plugins/jpeg/jpeg_decoder.h b/apps/plugins/imageviewer/jpeg/jpeg_decoder.h
index b86bdaf001..b86bdaf001 100644
--- a/apps/plugins/jpeg/jpeg_decoder.h
+++ b/apps/plugins/imageviewer/jpeg/jpeg_decoder.h
diff --git a/apps/plugins/imageviewer/jpeg/jpeg_ui.c b/apps/plugins/imageviewer/jpeg/jpeg_ui.c
new file mode 100644
index 0000000000..e7f57c699f
--- /dev/null
+++ b/apps/plugins/imageviewer/jpeg/jpeg_ui.c
@@ -0,0 +1,5 @@
1#define JPEG_VIEWER
2#define MENU_TITLE "Jpeg Menu"
3#define UNSCALED_IS_AVAILABLE 0
4
5#include "../imageviewer.c"
diff --git a/apps/plugins/jpeg/yuv2rgb.c b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
index 2395f232b2..2395f232b2 100644
--- a/apps/plugins/jpeg/yuv2rgb.c
+++ b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
diff --git a/apps/plugins/jpeg/yuv2rgb.h b/apps/plugins/imageviewer/jpeg/yuv2rgb.h
index d10a944f38..d10a944f38 100644
--- a/apps/plugins/jpeg/yuv2rgb.h
+++ b/apps/plugins/imageviewer/jpeg/yuv2rgb.h
diff --git a/apps/plugins/png/SOURCES b/apps/plugins/imageviewer/png/SOURCES
index 94805a5623..19ca69d927 100644
--- a/apps/plugins/png/SOURCES
+++ b/apps/plugins/imageviewer/png/SOURCES
@@ -4,3 +4,4 @@ inffast.c
4inflate.c 4inflate.c
5inftrees.c 5inftrees.c
6png.c 6png.c
7png_ui.c
diff --git a/apps/plugins/png/adler32.c b/apps/plugins/imageviewer/png/adler32.c
index 007ba26277..007ba26277 100644
--- a/apps/plugins/png/adler32.c
+++ b/apps/plugins/imageviewer/png/adler32.c
diff --git a/apps/plugins/png/crc32_png.c b/apps/plugins/imageviewer/png/crc32_png.c
index a76f49d35c..a76f49d35c 100644
--- a/apps/plugins/png/crc32_png.c
+++ b/apps/plugins/imageviewer/png/crc32_png.c
diff --git a/apps/plugins/png/crc32_png.h b/apps/plugins/imageviewer/png/crc32_png.h
index 8053b6117c..8053b6117c 100644
--- a/apps/plugins/png/crc32_png.h
+++ b/apps/plugins/imageviewer/png/crc32_png.h
diff --git a/apps/plugins/png/inffast.c b/apps/plugins/imageviewer/png/inffast.c
index bf96323ab2..bf96323ab2 100644
--- a/apps/plugins/png/inffast.c
+++ b/apps/plugins/imageviewer/png/inffast.c
diff --git a/apps/plugins/png/inffast.h b/apps/plugins/imageviewer/png/inffast.h
index 1e88d2d97b..1e88d2d97b 100644
--- a/apps/plugins/png/inffast.h
+++ b/apps/plugins/imageviewer/png/inffast.h
diff --git a/apps/plugins/png/inffixed.h b/apps/plugins/imageviewer/png/inffixed.h
index 75ed4b5978..75ed4b5978 100644
--- a/apps/plugins/png/inffixed.h
+++ b/apps/plugins/imageviewer/png/inffixed.h
diff --git a/apps/plugins/png/inflate.c b/apps/plugins/imageviewer/png/inflate.c
index 2cf6f972a4..beec74044b 100644
--- a/apps/plugins/png/inflate.c
+++ b/apps/plugins/imageviewer/png/inflate.c
@@ -555,8 +555,6 @@ unsigned out;
555 will return Z_BUF_ERROR if it has not reached the end of the stream. 555 will return Z_BUF_ERROR if it has not reached the end of the stream.
556 */ 556 */
557 557
558extern void cb_progress(int current, int total);
559
560int ZEXPORT inflate(strm, flush) 558int ZEXPORT inflate(strm, flush)
561z_streamp strm; 559z_streamp strm;
562int flush; 560int flush;
@@ -1132,7 +1130,7 @@ int flush;
1132 return Z_STREAM_ERROR; 1130 return Z_STREAM_ERROR;
1133 } 1131 }
1134 //DEBUGF("%d / %d\n", strm->total_in, strm->avail_in); 1132 //DEBUGF("%d / %d\n", strm->total_in, strm->avail_in);
1135 if (rb->button_get(false) == PNG_MENU) 1133 if (rb->button_get(false) == IMGVIEW_MENU)
1136 return PLUGIN_ABORT; 1134 return PLUGIN_ABORT;
1137 else cb_progress(insize - strm->avail_in, insize); 1135 else cb_progress(insize - strm->avail_in, insize);
1138 } 1136 }
diff --git a/apps/plugins/png/inflate.h b/apps/plugins/imageviewer/png/inflate.h
index d35c1bc041..d35c1bc041 100644
--- a/apps/plugins/png/inflate.h
+++ b/apps/plugins/imageviewer/png/inflate.h
diff --git a/apps/plugins/png/inftrees.c b/apps/plugins/imageviewer/png/inftrees.c
index 8a9c13ff03..8a9c13ff03 100644
--- a/apps/plugins/png/inftrees.c
+++ b/apps/plugins/imageviewer/png/inftrees.c
diff --git a/apps/plugins/png/inftrees.h b/apps/plugins/imageviewer/png/inftrees.h
index b1104c87e7..b1104c87e7 100644
--- a/apps/plugins/png/inftrees.h
+++ b/apps/plugins/imageviewer/png/inftrees.h
diff --git a/apps/plugins/png/png.c b/apps/plugins/imageviewer/png/png.c
index 3f826001c9..5cf6f4d471 100644
--- a/apps/plugins/png/png.c
+++ b/apps/plugins/imageviewer/png/png.c
@@ -54,16 +54,10 @@ You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
54 54
55#include "plugin.h" 55#include "plugin.h"
56#include "lcd.h" 56#include "lcd.h"
57#include <lib/playback_control.h>
58#include <lib/helper.h>
59#include <lib/configfile.h>
60#include <lib/grey.h>
61#include <lib/pluginlib_bmp.h> 57#include <lib/pluginlib_bmp.h>
62#include "zlib.h" 58#include "zlib.h"
63#include "png.h" 59#include "png.h"
64 60
65PLUGIN_HEADER
66
67/* ////////////////////////////////////////////////////////////////////////// */ 61/* ////////////////////////////////////////////////////////////////////////// */
68/* LodeFlate & LodeZlib Setting structs */ 62/* LodeFlate & LodeZlib Setting structs */
69/* ////////////////////////////////////////////////////////////////////////// */ 63/* ////////////////////////////////////////////////////////////////////////// */
@@ -140,26 +134,10 @@ typedef struct LodePNG_Decoder
140 LodePNG_InfoPng infoPng; /*info of the PNG image obtained after decoding*/ 134 LodePNG_InfoPng infoPng; /*info of the PNG image obtained after decoding*/
141 long error; 135 long error;
142 char error_msg[128]; 136 char error_msg[128];
143 int x,y;
144 int width,height;
145} LodePNG_Decoder; 137} LodePNG_Decoder;
146 138
147#define VERSION_STRING "20080927" 139#define VERSION_STRING "20080927"
148 140
149/* Min memory allowing us to use the plugin buffer
150 * and thus not stopping the music
151 * *Very* rough estimation:
152 * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
153 * + 30k code size = 70 000
154 * + 50k min for png = 130 000
155 */
156#define MIN_MEM 130000
157
158/* Headings */
159#define DIR_PREV 1
160#define DIR_NEXT -1
161#define DIR_NONE 0
162
163/* decompressed image in the possible sizes (1,2,4,8), wasting the other */ 141/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
164static fb_data *disp[9]; 142static fb_data *disp[9];
165/* up to here currently used by image(s) */ 143/* up to here currently used by image(s) */
@@ -180,62 +158,7 @@ static size_t converted_image_size;
180static unsigned char *decoded_image; /* the decoded image */ 158static unsigned char *decoded_image; /* the decoded image */
181static size_t decoded_image_size; 159static size_t decoded_image_size;
182 160
183static fb_data *resized_image; /* the decoded image */ 161static LodePNG_Decoder _decoder;
184
185static struct tree_context *tree;
186
187/* the current full file name */
188static char np_file[MAX_PATH];
189static int curfile = 0, direction = DIR_NONE, entries = 0;
190
191static LodePNG_Decoder decoder;
192
193/* list of the png files */
194static char **file_pt;
195#if PLUGIN_BUFFER_SIZE >= MIN_MEM
196/* are we using the plugin buffer or the audio buffer? */
197static bool plug_buf = true;
198#endif
199
200/* Persistent configuration */
201#define PNG_CONFIGFILE "png.cfg"
202#define PNG_SETTINGS_MINVERSION 1
203#define PNG_SETTINGS_VERSION 1
204
205/* Slideshow times */
206#define SS_MIN_TIMEOUT 1
207#define SS_MAX_TIMEOUT 20
208#define SS_DEFAULT_TIMEOUT 5
209
210struct png_settings
211{
212 int ss_timeout;
213};
214
215static struct png_settings png_settings =
216 {
217 SS_DEFAULT_TIMEOUT
218 };
219static struct png_settings old_settings;
220
221static struct configdata png_config[] =
222 {
223 { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT,
224 { .int_p = &png_settings.ss_timeout }, "Slideshow Time", NULL
225 },
226 };
227
228#if LCD_DEPTH > 1
229static fb_data* old_backdrop;
230#endif
231
232static int slideshow_enabled = false; /* run slideshow */
233static int running_slideshow = false; /* loading image because of slideshw */
234#ifndef SIMULATOR
235static int immediate_ata_off = false; /* power down disk after loading */
236#endif
237
238static unsigned ds, ds_min, ds_max; /* downscaling and limits */
239 162
240/* 163/*
241The two functions below (LodePNG_decompress and LodePNG_compress) directly call the 164The two functions below (LodePNG_decompress and LodePNG_compress) directly call the
@@ -1263,7 +1186,7 @@ if (size == 0 || in == 0) { decoder->error = 48; return; } /*the given data is e
1263 if (!decoder->error) 1186 if (!decoder->error)
1264 { 1187 {
1265 unsigned char *scanlines = idat + idat_size; 1188 unsigned char *scanlines = idat + idat_size;
1266 size_t scanlines_size = (size_t)memory_max - idat_size + 1; 1189 size_t scanlines_size = (size_t)memory_max - idat_size;
1267 long time = *rb->current_tick; 1190 long time = *rb->current_tick;
1268 decoder->error = LodePNG_decompress(scanlines, &scanlines_size, idat, idat_size, decoder->error_msg); /*decompress with the Zlib decompressor*/ 1191 decoder->error = LodePNG_decompress(scanlines, &scanlines_size, idat, idat_size, decoder->error_msg); /*decompress with the Zlib decompressor*/
1269 if (pf_progress) pf_progress(100, 100); 1192 if (pf_progress) pf_progress(100, 100);
@@ -1273,7 +1196,7 @@ if (size == 0 || in == 0) { decoder->error = 48; return; } /*the given data is e
1273 { 1196 {
1274 decoded_image_size = (decoder->infoPng.height * decoder->infoPng.width * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8; 1197 decoded_image_size = (decoder->infoPng.height * decoder->infoPng.width * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8;
1275 if (decoded_image_size > memory_size) { decoder->error = OUT_OF_MEMORY; return; } 1198 if (decoded_image_size > memory_size) { decoder->error = OUT_OF_MEMORY; return; }
1276 decoded_image = memory_max - decoded_image_size + 1; 1199 decoded_image = memory_max - decoded_image_size;
1277 if (scanlines + scanlines_size >= decoded_image) { decoder->error = OUT_OF_MEMORY; return; } 1200 if (scanlines + scanlines_size >= decoded_image) { decoder->error = OUT_OF_MEMORY; return; }
1278 memset(decoded_image, 0, decoded_image_size * sizeof(unsigned char)); 1201 memset(decoded_image, 0, decoded_image_size * sizeof(unsigned char));
1279 if (!running_slideshow) 1202 if (!running_slideshow)
@@ -1373,7 +1296,7 @@ static const unsigned char *png_error_messages[PNG_ERROR_MAX-PNG_ERROR_MIN+1] =
1373 "invalid pHYs chunk size", /*74*/ 1296 "invalid pHYs chunk size", /*74*/
1374}; 1297};
1375 1298
1376bool png_ext(const char ext[]) 1299bool img_ext(const char *ext)
1377{ 1300{
1378 if (!ext) 1301 if (!ext)
1379 return false; 1302 return false;
@@ -1383,436 +1306,36 @@ bool png_ext(const char ext[])
1383 return false; 1306 return false;
1384} 1307}
1385 1308
1386/*Read directory contents for scrolling. */ 1309void draw_image_rect(struct image_info *info,
1387void get_pic_list(void) 1310 int x, int y, int width, int height)
1388{
1389 int i;
1390 struct entry *dircache;
1391 char *pname;
1392 tree = rb->tree_get_context();
1393 dircache = tree->dircache;
1394
1395 file_pt = (char **) memory;
1396
1397 /* Remove path and leave only the name.*/
1398 pname = rb->strrchr(np_file,'/');
1399 pname++;
1400
1401 for (i = 0; i < tree->filesindir; i++)
1402 {
1403 if (!(dircache[i].attr & ATTR_DIRECTORY)
1404 && png_ext(rb->strrchr(dircache[i].name, '.')))
1405 {
1406 file_pt[entries] = dircache[i].name;
1407 /* Set Selected File. */
1408 if (!rb->strcmp(file_pt[entries], pname))
1409 curfile = entries;
1410 entries++;
1411 }
1412 }
1413
1414 memory += (entries * sizeof(char**));
1415 memory_size -= (entries * sizeof(char**));
1416}
1417
1418int change_filename(int direct)
1419{
1420 bool file_erased = (file_pt[curfile] == NULL);
1421 direction = direct;
1422
1423 curfile += (direct == DIR_PREV? entries - 1: 1);
1424 if (curfile >= entries)
1425 curfile -= entries;
1426
1427 if (file_erased)
1428 {
1429 /* remove 'erased' file names from list. */
1430 int count, i;
1431 for (count = i = 0; i < entries; i++)
1432 {
1433 if (curfile == i)
1434 curfile = count;
1435 if (file_pt[i] != NULL)
1436 file_pt[count++] = file_pt[i];
1437 }
1438 entries = count;
1439 }
1440
1441 if (entries == 0)
1442 {
1443 rb->splash(HZ, "No supported files");
1444 return PLUGIN_ERROR;
1445 }
1446
1447 if (rb->strlen(tree->currdir) > 1)
1448 {
1449 rb->strcpy(np_file, tree->currdir);
1450 rb->strcat(np_file, "/");
1451 }
1452 else
1453 rb->strcpy(np_file, tree->currdir);
1454
1455 rb->strcat(np_file, file_pt[curfile]);
1456
1457 return PLUGIN_OTHER;
1458}
1459
1460/* switch off overlay, for handling SYS_ events */
1461void cleanup(void *parameter)
1462{ 1311{
1463 (void)parameter; 1312 fb_data **pdisp = (fb_data**)info->data;
1313 rb->lcd_bitmap_part(*pdisp, info->x + x, info->y + y, info->width,
1314 x + MAX(0, (LCD_WIDTH-info->width)/2),
1315 y + MAX(0, (LCD_HEIGHT-info->height)/2),
1316 width, height);
1464} 1317}
1465 1318
1466#define VSCROLL (LCD_HEIGHT/8) 1319int img_mem(int ds)
1467#define HSCROLL (LCD_WIDTH/10)
1468
1469#define ZOOM_IN 100 /* return codes for below function */
1470#define ZOOM_OUT 101
1471
1472int show_menu(void) /* return 1 to quit */
1473{
1474#if LCD_DEPTH > 1
1475 rb->lcd_set_backdrop(old_backdrop);
1476#ifdef HAVE_LCD_COLOR
1477 rb->lcd_set_foreground(rb->global_settings->fg_color);
1478 rb->lcd_set_background(rb->global_settings->bg_color);
1479#else
1480 rb->lcd_set_foreground(LCD_BLACK);
1481 rb->lcd_set_background(LCD_WHITE);
1482#endif
1483#endif
1484 int result;
1485
1486 enum menu_id
1487 {
1488 MIID_RETURN = 0,
1489 MIID_TOGGLE_SS_MODE,
1490 MIID_CHANGE_SS_MODE,
1491#if PLUGIN_BUFFER_SIZE >= MIN_MEM
1492 MIID_SHOW_PLAYBACK_MENU,
1493#endif
1494 MIID_QUIT,
1495 };
1496
1497 MENUITEM_STRINGLIST(menu, "Png Menu", NULL,
1498 "Return", "Toggle Slideshow Mode",
1499 "Change Slideshow Time",
1500#if PLUGIN_BUFFER_SIZE >= MIN_MEM
1501 "Show Playback Menu",
1502#endif
1503 "Quit");
1504
1505 static const struct opt_items slideshow[2] = {
1506 { "Disable", -1 },
1507 { "Enable", -1 },
1508 };
1509
1510 result=rb->do_menu(&menu, NULL, NULL, false);
1511
1512 switch (result)
1513 {
1514 case MIID_RETURN:
1515 break;
1516 case MIID_TOGGLE_SS_MODE:
1517 rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
1518 slideshow , 2, NULL);
1519 break;
1520 case MIID_CHANGE_SS_MODE:
1521 rb->set_int("Slideshow Time", "s", UNIT_SEC,
1522 &png_settings.ss_timeout, NULL, 1,
1523 SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
1524 break;
1525#if PLUGIN_BUFFER_SIZE >= MIN_MEM
1526 case MIID_SHOW_PLAYBACK_MENU:
1527 if (plug_buf)
1528 {
1529 playback_control(NULL);
1530 }
1531 else
1532 {
1533 rb->splash(HZ, "Cannot restart playback");
1534 }
1535 break;
1536#endif
1537 case MIID_QUIT:
1538 return 1;
1539 break;
1540 }
1541
1542#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
1543 /* change ata spindown time based on slideshow time setting */
1544 immediate_ata_off = false;
1545 rb->storage_spindown(rb->global_settings->disk_spindown);
1546
1547 if (slideshow_enabled)
1548 {
1549 if (png_settings.ss_timeout < 10)
1550 {
1551 /* slideshow times < 10s keep disk spinning */
1552 rb->storage_spindown(0);
1553 }
1554 else if (!rb->mp3_is_playing())
1555 {
1556 /* slideshow times > 10s and not playing: ata_off after load */
1557 immediate_ata_off = true;
1558 }
1559 }
1560#endif
1561#if LCD_DEPTH > 1
1562 rb->lcd_set_backdrop(NULL);
1563 rb->lcd_set_foreground(LCD_WHITE);
1564 rb->lcd_set_background(LCD_BLACK);
1565#endif
1566 rb->lcd_clear_display();
1567 return 0;
1568}
1569
1570void draw_image(struct LodePNG_Decoder* decoder)
1571{
1572 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->width,
1573 MAX(0, (LCD_WIDTH - decoder->width) / 2),
1574 MAX(0, (LCD_HEIGHT - decoder->height) / 2),
1575 decoder->width - decoder->x,
1576 decoder->height - decoder->y);
1577}
1578
1579/* Pan the viewing window right - move image to the left and fill in
1580 the right-hand side */
1581static void pan_view_right(struct LodePNG_Decoder* decoder)
1582{
1583 int move;
1584
1585 move = MIN(HSCROLL, decoder->width - decoder->x - LCD_WIDTH);
1586 if (move > 0)
1587 {
1588 decoder->x += move;
1589 draw_image(decoder);
1590 rb->lcd_update();
1591 }
1592}
1593
1594/* Pan the viewing window left - move image to the right and fill in
1595 the left-hand side */
1596static void pan_view_left(struct LodePNG_Decoder* decoder)
1597{
1598 int move;
1599
1600 move = MIN(HSCROLL, decoder->x);
1601 if (move > 0)
1602 {
1603 decoder->x -= move;
1604 draw_image(decoder);
1605 rb->lcd_update();
1606 }
1607}
1608
1609
1610/* Pan the viewing window up - move image down and fill in
1611 the top */
1612static void pan_view_up(struct LodePNG_Decoder* decoder)
1613{
1614 int move;
1615
1616 move = MIN(VSCROLL, decoder->y);
1617 if (move > 0)
1618 {
1619 decoder->y -= move;
1620 draw_image(decoder);
1621 rb->lcd_update();
1622 }
1623}
1624
1625/* Pan the viewing window down - move image up and fill in
1626 the bottom */
1627static void pan_view_down(struct LodePNG_Decoder* decoder)
1628{
1629 int move;
1630
1631 move = MIN(VSCROLL, decoder->height - decoder->y - LCD_HEIGHT);
1632 if (move > 0)
1633 {
1634 decoder->y += move;
1635 draw_image(decoder);
1636 rb->lcd_update();
1637 }
1638}
1639
1640/* interactively scroll around the image */
1641int scroll_bmp(struct LodePNG_Decoder* decoder)
1642{
1643 int button;
1644 int lastbutton = 0;
1645
1646 while (true)
1647 {
1648 if (slideshow_enabled)
1649 button = rb->button_get_w_tmo(png_settings.ss_timeout * HZ);
1650 else
1651 button = rb->button_get(true);
1652
1653 running_slideshow = false;
1654
1655 switch (button)
1656 {
1657 case PNG_LEFT:
1658 if (entries > 1 && decoder->width <= LCD_WIDTH
1659 && decoder->height <= LCD_HEIGHT)
1660 return change_filename(DIR_PREV);
1661 case PNG_LEFT | BUTTON_REPEAT:
1662 pan_view_left(decoder);
1663 break;
1664
1665 case PNG_RIGHT:
1666 if (entries > 1 && decoder->width <= LCD_WIDTH
1667 && decoder->height <= LCD_HEIGHT)
1668 return change_filename(DIR_NEXT);
1669 case PNG_RIGHT | BUTTON_REPEAT:
1670 pan_view_right(decoder);
1671 break;
1672
1673 case PNG_UP:
1674 case PNG_UP | BUTTON_REPEAT:
1675 pan_view_up(decoder);
1676 break;
1677
1678 case PNG_DOWN:
1679 case PNG_DOWN | BUTTON_REPEAT:
1680 pan_view_down(decoder);
1681 break;
1682
1683 case BUTTON_NONE:
1684 if (!slideshow_enabled)
1685 break;
1686 running_slideshow = true;
1687 if (entries > 1)
1688 return change_filename(DIR_NEXT);
1689 break;
1690
1691#ifdef PNG_SLIDE_SHOW
1692 case PNG_SLIDE_SHOW:
1693 slideshow_enabled = !slideshow_enabled;
1694 running_slideshow = slideshow_enabled;
1695 break;
1696#endif
1697
1698#ifdef PNG_NEXT_REPEAT
1699 case PNG_NEXT_REPEAT:
1700#endif
1701 case PNG_NEXT:
1702 if (entries > 1)
1703 return change_filename(DIR_NEXT);
1704 break;
1705
1706#ifdef PNG_PREVIOUS_REPEAT
1707 case PNG_PREVIOUS_REPEAT:
1708#endif
1709 case PNG_PREVIOUS:
1710 if (entries > 1)
1711 return change_filename(DIR_PREV);
1712 break;
1713
1714 case PNG_ZOOM_IN:
1715#ifdef PNG_ZOOM_PRE
1716 if (lastbutton != PNG_ZOOM_PRE)
1717 break;
1718#endif
1719 return ZOOM_IN;
1720 break;
1721
1722 case PNG_ZOOM_OUT:
1723#ifdef PNG_ZOOM_PRE
1724 if (lastbutton != PNG_ZOOM_PRE)
1725 break;
1726#endif
1727 return ZOOM_OUT;
1728 break;
1729
1730#ifdef PNG_RC_MENU
1731 case PNG_RC_MENU:
1732#endif
1733 case PNG_MENU:
1734
1735 if (show_menu() == 1)
1736 return PLUGIN_OK;
1737
1738 draw_image(decoder);
1739 rb->lcd_update();
1740
1741 break;
1742 default:
1743 if (rb->default_event_handler_ex(button, cleanup, NULL)
1744 == SYS_USB_CONNECTED)
1745 return PLUGIN_USB_CONNECTED;
1746 break;
1747
1748 } /* switch */
1749
1750 if (button != BUTTON_NONE)
1751 lastbutton = button;
1752 } /* while (true) */
1753}
1754
1755/* callback updating a progress meter while PNG decoding */
1756void cb_progress(int current, int total)
1757{
1758
1759 if (current & 1) rb->yield(); /* be nice to the other threads */
1760 if (!running_slideshow)
1761 {
1762 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
1763 0, LCD_HEIGHT-8, LCD_WIDTH, 8,
1764 total, 0, current, HORIZONTAL);
1765 rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
1766 }
1767 else
1768 {
1769 /* in slideshow mode, keep gui interference to a minimum */
1770 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
1771 0, LCD_HEIGHT-4, LCD_WIDTH, 4,
1772 total, 0, current, HORIZONTAL);
1773 rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
1774 }
1775}
1776
1777int pngmem(struct LodePNG_Decoder* decoder, int ds)
1778{ 1320{
1321 LodePNG_Decoder *decoder = &_decoder;
1779 return (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds) * FB_DATA_SZ; 1322 return (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds) * FB_DATA_SZ;
1780} 1323}
1781 1324
1782/* how far can we zoom in without running out of memory */ 1325int load_image(char *filename, struct image_info *info,
1783int min_downscale(struct LodePNG_Decoder* decoder, int bufsize) 1326 unsigned char *buf, ssize_t *buf_size)
1784{
1785 int downscale = 8;
1786
1787 if (pngmem(decoder, 8) > bufsize)
1788 return 0; /* error, too large, even 1:8 doesn't fit */
1789
1790 while (downscale > 1 && pngmem(decoder, downscale/2) <= bufsize)
1791 downscale /= 2;
1792
1793 return downscale;
1794}
1795
1796/* how far can we zoom out, to fit image into the LCD */
1797unsigned max_downscale(struct LodePNG_Decoder* decoder)
1798{
1799 unsigned downscale = 1;
1800
1801 while (downscale < 8 && (decoder->infoPng.width/downscale > LCD_WIDTH
1802 || decoder->infoPng.height/downscale > LCD_HEIGHT))
1803 {
1804 downscale *= 2;
1805 }
1806
1807 return downscale;
1808}
1809
1810/* load image from filename. */
1811int load_image(char* filename, struct LodePNG_Decoder* decoder)
1812{ 1327{
1813 int fd; 1328 int fd;
1814 long time = 0; /* measured ticks */ 1329 long time = 0; /* measured ticks */
1815 int w, h; /* used to center output */ 1330 int w, h; /* used to center output */
1331 LodePNG_Decoder *decoder = &_decoder;
1332
1333 memset(&disp, 0, sizeof(disp));
1334 LodePNG_Decoder_init(decoder);
1335
1336 memory = buf;
1337 memory_size = *buf_size;
1338 memory_max = memory + memory_size;
1816 1339
1817 fd = rb->open(filename, O_RDONLY); 1340 fd = rb->open(filename, O_RDONLY);
1818 if (fd < 0) 1341 if (fd < 0)
@@ -1833,12 +1356,6 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
1833 if (image_size > memory_size) { 1356 if (image_size > memory_size) {
1834 decoder->error = FILE_TOO_LARGE; 1357 decoder->error = FILE_TOO_LARGE;
1835 rb->close(fd); 1358 rb->close(fd);
1836#ifndef SIMULATOR
1837 if (running_slideshow && immediate_ata_off) {
1838 /* running slideshow and time is long enough: power down disk */
1839 rb->storage_sleep();
1840 }
1841#endif
1842 1359
1843 } else { 1360 } else {
1844 if (!running_slideshow) { 1361 if (!running_slideshow) {
@@ -1847,7 +1364,7 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
1847 rb->lcd_update(); 1364 rb->lcd_update();
1848 } 1365 }
1849 1366
1850 image = memory_max - image_size + 1; 1367 image = memory_max - image_size;
1851 rb->read(fd, image, image_size); 1368 rb->read(fd, image, image_size);
1852 rb->close(fd); 1369 rb->close(fd);
1853 1370
@@ -1856,7 +1373,7 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
1856 rb->lcd_puts(0, 2, print); 1373 rb->lcd_puts(0, 2, print);
1857 rb->lcd_update(); 1374 rb->lcd_update();
1858 } 1375 }
1859#ifndef SIMULATOR 1376#ifdef DISK_SPINDOWN
1860 else if (immediate_ata_off) { 1377 else if (immediate_ata_off) {
1861 /* running slideshow and time is long enough: power down disk */ 1378 /* running slideshow and time is long enough: power down disk */
1862 rb->storage_sleep(); 1379 rb->storage_sleep();
@@ -1939,21 +1456,27 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
1939 else 1456 else
1940 return PLUGIN_ERROR; 1457 return PLUGIN_ERROR;
1941 } 1458 }
1459
1460 disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
1461 info->x_size = decoder->infoPng.width;
1462 info->y_size = decoder->infoPng.height;
1463 *buf_size = memory_max - (unsigned char*)disp_buf;
1942 return PLUGIN_OK; 1464 return PLUGIN_OK;
1943} 1465}
1944 1466
1945/* return decoded or cached image */ 1467int get_image(struct image_info *info, int ds)
1946fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
1947{ 1468{
1948 fb_data * p_disp = disp[ds]; /* short cut */ 1469 fb_data **p_disp = &disp[ds]; /* short cut */
1470 LodePNG_Decoder *decoder = &_decoder;
1949 1471
1950 decoder->width = decoder->infoPng.width / ds; 1472 info->width = decoder->infoPng.width / ds;
1951 decoder->height = decoder->infoPng.height / ds; 1473 info->height = decoder->infoPng.height / ds;
1474 info->data = p_disp;
1952 1475
1953 if (p_disp != NULL) 1476 if (*p_disp != NULL)
1954 { 1477 {
1955 DEBUGF("Found an image in cache\n"); 1478 /* we still have it */
1956 return p_disp; /* we still have it */ 1479 return PLUGIN_OK;
1957 } 1480 }
1958 1481
1959 /* assign image buffer */ 1482 /* assign image buffer */
@@ -1961,13 +1484,13 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
1961 if (!running_slideshow) 1484 if (!running_slideshow)
1962 { 1485 {
1963 rb->snprintf(print, sizeof(print), "resizing %d*%d", 1486 rb->snprintf(print, sizeof(print), "resizing %d*%d",
1964 decoder->width, decoder->height); 1487 info->width, info->height);
1965 rb->lcd_puts(0, 3, print); 1488 rb->lcd_puts(0, 3, print);
1966 rb->lcd_update(); 1489 rb->lcd_update();
1967 } 1490 }
1968 struct bitmap bmp_src, bmp_dst; 1491 struct bitmap bmp_src, bmp_dst;
1969 1492
1970 int size = decoder->width * decoder->height; 1493 int size = info->width * info->height;
1971 1494
1972 if ((unsigned char *)(disp_buf + size) >= memory_max) { 1495 if ((unsigned char *)(disp_buf + size) >= memory_max) {
1973 /* have to discard the current */ 1496 /* have to discard the current */
@@ -1978,16 +1501,16 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
1978 disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3); 1501 disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
1979 } 1502 }
1980 1503
1981 disp[ds] = disp_buf; 1504 *p_disp = disp_buf;
1982 disp_buf = (fb_data *)((intptr_t)(disp[ds] + size + 3) & ~3); 1505 disp_buf = (fb_data *)((intptr_t)(disp_buf + size + 3) & ~3);
1983 1506
1984 bmp_src.width = decoder->infoPng.width; 1507 bmp_src.width = decoder->infoPng.width;
1985 bmp_src.height = decoder->infoPng.height; 1508 bmp_src.height = decoder->infoPng.height;
1986 bmp_src.data = (unsigned char *)converted_image; 1509 bmp_src.data = (unsigned char *)converted_image;
1987 1510
1988 bmp_dst.width = decoder->width; 1511 bmp_dst.width = info->width;
1989 bmp_dst.height = decoder->height; 1512 bmp_dst.height = info->height;
1990 bmp_dst.data = (unsigned char *)disp[ds]; 1513 bmp_dst.data = (unsigned char *)*p_disp;
1991#ifdef HAVE_ADJUSTABLE_CPU_FREQ 1514#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1992 rb->cpu_boost(true); 1515 rb->cpu_boost(true);
1993 smooth_resize_bitmap(&bmp_src, &bmp_dst); 1516 smooth_resize_bitmap(&bmp_src, &bmp_dst);
@@ -1996,276 +1519,8 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
1996 smooth_resize_bitmap(&bmp_src, &bmp_dst); 1519 smooth_resize_bitmap(&bmp_src, &bmp_dst);
1997#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ 1520#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
1998 } else { 1521 } else {
1999 disp[ds] = converted_image; 1522 *p_disp = converted_image;
2000 return converted_image;
2001 }
2002
2003 return disp[ds];
2004}
2005
2006/* set the view to the given center point, limit if necessary */
2007void set_view (struct LodePNG_Decoder* decoder, int cx, int cy)
2008{
2009 int x, y;
2010
2011 /* plain center to available width/height */
2012 x = cx - MIN(LCD_WIDTH, decoder->width) / 2;
2013 y = cy - MIN(LCD_HEIGHT, decoder->height) / 2;
2014
2015 /* limit against upper image size */
2016 x = MIN(decoder->width - LCD_WIDTH, x);
2017 y = MIN(decoder->height - LCD_HEIGHT, y);
2018
2019 /* limit against negative side */
2020 x = MAX(0, x);
2021 y = MAX(0, y);
2022
2023 decoder->x = x; /* set the values */
2024 decoder->y = y;
2025}
2026
2027/* calculate the view center based on the bitmap position */
2028void get_view(struct LodePNG_Decoder* decoder, int* p_cx, int* p_cy)
2029{
2030 *p_cx = decoder->x + MIN(LCD_WIDTH, decoder->width) / 2;
2031 *p_cy = decoder->y + MIN(LCD_HEIGHT, decoder->height) / 2;
2032}
2033
2034/* load, decode, display the image */
2035int load_and_show(char* filename)
2036{
2037 int status;
2038 int cx=0, cy=0; /* view center */
2039
2040#if LCD_DEPTH > 1
2041 rb->lcd_set_foreground(LCD_WHITE);
2042 rb->lcd_set_background(LCD_BLACK);
2043 rb->lcd_set_backdrop(NULL);
2044#endif
2045 rb->lcd_clear_display();
2046
2047 memset(&disp, 0, sizeof(disp));
2048 LodePNG_Decoder_init(&decoder);
2049
2050 if (rb->button_get(false) == PNG_MENU)
2051 status = PLUGIN_ABORT;
2052 else
2053 status = load_image(filename, &decoder);
2054
2055 if (status == PLUGIN_OUTOFMEM)
2056 {
2057#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2058 if (plug_buf)
2059 {
2060 rb->lcd_setfont(FONT_SYSFIXED);
2061 rb->lcd_clear_display();
2062 rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
2063 rb->lcd_puts(0,0,print);
2064 rb->lcd_puts(0,1,"Not enough plugin memory!");
2065 rb->lcd_puts(0,2,"Zoom In: Stop playback.");
2066 if (entries>1)
2067 rb->lcd_puts(0,3,"Left/Right: Skip File.");
2068 rb->lcd_puts(0,4,"Show Menu: Quit.");
2069 rb->lcd_update();
2070 rb->lcd_setfont(FONT_UI);
2071
2072 rb->button_clear_queue();
2073
2074 while (1)
2075 {
2076 int button = rb->button_get(true);
2077 switch (button)
2078 {
2079 case PNG_ZOOM_IN:
2080 plug_buf = false;
2081 memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
2082 memory_max = memory + memory_size - 1;
2083 /*try again this file, now using the audio buffer */
2084 return PLUGIN_OTHER;
2085#ifdef PNG_RC_MENU
2086 case PNG_RC_MENU:
2087#endif
2088 case PNG_MENU:
2089 return PLUGIN_OK;
2090
2091 case PNG_LEFT:
2092 if (entries>1)
2093 {
2094 rb->lcd_clear_display();
2095 return change_filename(DIR_PREV);
2096 }
2097 break;
2098
2099 case PNG_RIGHT:
2100 if (entries>1)
2101 {
2102 rb->lcd_clear_display();
2103 return change_filename(DIR_NEXT);
2104 }
2105 break;
2106 default:
2107 if (rb->default_event_handler_ex(button, cleanup, NULL)
2108 == SYS_USB_CONNECTED)
2109 return PLUGIN_USB_CONNECTED;
2110
2111 }
2112 }
2113 }
2114 else
2115#endif
2116 {
2117 rb->splash(HZ, "Out of Memory");
2118 file_pt[curfile] = NULL;
2119 return change_filename(direction);
2120 }
2121 }
2122 else if (status == PLUGIN_ERROR)
2123 {
2124 file_pt[curfile] = NULL;
2125 return change_filename(direction);
2126 }
2127 else if (status == PLUGIN_ABORT) {
2128 rb->splash(HZ, "aborted");
2129 return PLUGIN_OK;
2130 } 1523 }
2131 1524
2132 disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3); 1525 return PLUGIN_OK;
2133 ds_max = max_downscale(&decoder); /* check display constraint */
2134 ds_min = min_downscale(&decoder, memory_max - (unsigned char*)disp_buf); /* check memory constraint */
2135 if (ds_min == 0) {
2136 /* Can not resize the image */
2137 ds_min = ds_max = 1;
2138 } else if (ds_max < ds_min) {
2139 ds_max = ds_min;
2140 }
2141
2142 ds = ds_max; /* initialize setting */
2143 cx = decoder.infoPng.width/ds/2; /* center the view */
2144 cy = decoder.infoPng.height/ds/2;
2145
2146 do {
2147 resized_image = get_image(&decoder, ds); /* decode or fetch from cache */
2148
2149 set_view(&decoder, cx, cy);
2150
2151 if (!running_slideshow)
2152 {
2153 rb->snprintf(print, sizeof(print), "showing %dx%d",
2154 decoder.width, decoder.height);
2155 rb->lcd_puts(0, 3, print);
2156 rb->lcd_update();
2157 }
2158
2159 rb->lcd_clear_display();
2160 draw_image(&decoder);
2161 rb->lcd_update();
2162
2163 /* drawing is now finished, play around with scrolling
2164 * until you press OFF or connect USB
2165 */
2166 while (1)
2167 {
2168 status = scroll_bmp(&decoder);
2169 if (status == ZOOM_IN)
2170 {
2171 if (ds > 1)
2172 {
2173 /* as 1/1 is always available, jump ds to 1 if ds is ds_min. */
2174 int zoom = (ds == ds_min)? ds_min: 2;
2175 ds /= zoom; /* reduce downscaling to zoom in */
2176 get_view(&decoder, &cx, &cy);
2177 cx *= zoom; /* prepare the position in the new image */
2178 cy *= zoom;
2179 }
2180 else
2181 continue;
2182 }
2183
2184 if (status == ZOOM_OUT)
2185 {
2186 if (ds < ds_max)
2187 {
2188 /* if ds is 1 and ds_min is greater than 1, jump ds to ds_min. */
2189 int zoom = (ds < ds_min)? ds_min: 2;
2190 ds *= zoom; /* increase downscaling to zoom out */
2191 get_view(&decoder, &cx, &cy);
2192 cx /= zoom; /* prepare the position in the new image */
2193 cy /= zoom;
2194 }
2195 else
2196 continue;
2197 }
2198 break;
2199 }
2200 rb->lcd_clear_display();
2201 }
2202 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
2203 && status != PLUGIN_OTHER);
2204
2205 return status;
2206}
2207
2208/******************** Plugin entry point *********************/
2209
2210enum plugin_status plugin_start(const void* parameter)
2211{
2212 int condition;
2213#if LCD_DEPTH > 1
2214 old_backdrop = rb->lcd_get_backdrop();
2215#endif
2216
2217 if (!parameter) return PLUGIN_ERROR;
2218
2219#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2220 memory = rb->plugin_get_buffer((size_t *)&memory_size);
2221#else
2222 memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
2223#endif
2224
2225 rb->strcpy(np_file, parameter);
2226 get_pic_list();
2227
2228 if (!entries) return PLUGIN_ERROR;
2229
2230#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
2231 if (!rb->audio_status()) {
2232 plug_buf = false;
2233 memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
2234 }
2235#endif
2236
2237 memory_max = memory + memory_size - 1;
2238
2239 /* should be ok to just load settings since the plugin itself has
2240 just been loaded from disk and the drive should be spinning */
2241 configfile_load(PNG_CONFIGFILE, png_config,
2242 ARRAYLEN(png_config), PNG_SETTINGS_MINVERSION);
2243 old_settings = png_settings;
2244
2245 /* Turn off backlight timeout */
2246 backlight_force_on(); /* backlight control in lib/helper.c */
2247
2248 do
2249 {
2250 condition = load_and_show(np_file);
2251 } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
2252 && condition != PLUGIN_ERROR);
2253
2254 if (rb->memcmp(&png_settings, &old_settings, sizeof (png_settings)))
2255 {
2256 /* Just in case drive has to spin, keep it from looking locked */
2257 rb->splash(0, "Saving Settings");
2258 configfile_save(PNG_CONFIGFILE, png_config,
2259 ARRAYLEN(png_config), PNG_SETTINGS_VERSION);
2260 }
2261
2262#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
2263 /* set back ata spindown time in case we changed it */
2264 rb->storage_spindown(rb->global_settings->disk_spindown);
2265#endif
2266
2267 /* Turn on backlight timeout (revert to settings) */
2268 backlight_use_settings(); /* backlight control in lib/helper.c */
2269
2270 return condition;
2271} 1526}
diff --git a/apps/plugins/imageviewer/png/png.h b/apps/plugins/imageviewer/png/png.h
new file mode 100644
index 0000000000..e351d9a8aa
--- /dev/null
+++ b/apps/plugins/imageviewer/png/png.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$id $
9 *
10 * Copyright (C) 2009 by Christophe Gouiran <bechris13250 -at- gmail -dot- com>
11 *
12 * Based on lodepng, a lightweight png decoder/encoder
13 * (c) 2005-2008 Lode Vandevenne
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "../imageviewer.h"
26
27#define OUT_OF_MEMORY 9900
28#define FILE_TOO_LARGE 9910
29
diff --git a/apps/plugins/png/png.make b/apps/plugins/imageviewer/png/png.make
index 8f4ef39e72..b2000faecf 100644
--- a/apps/plugins/png/png.make
+++ b/apps/plugins/imageviewer/png/png.make
@@ -7,8 +7,8 @@
7# $Id$ 7# $Id$
8# 8#
9 9
10PNGSRCDIR := $(APPSDIR)/plugins/png 10PNGSRCDIR := $(IMGVSRCDIR)/png
11PNGBUILDDIR := $(BUILDDIR)/apps/plugins/png 11PNGBUILDDIR := $(IMGVBUILDDIR)/png
12 12
13ROCKS += $(PNGBUILDDIR)/png.rock 13ROCKS += $(PNGBUILDDIR)/png.rock
14 14
diff --git a/apps/plugins/imageviewer/png/png_ui.c b/apps/plugins/imageviewer/png/png_ui.c
new file mode 100644
index 0000000000..5dbf526ba1
--- /dev/null
+++ b/apps/plugins/imageviewer/png/png_ui.c
@@ -0,0 +1,5 @@
1#define PNG_VIEWER
2#define MENU_TITLE "Png Menu"
3#define UNSCALED_IS_AVAILABLE 1
4
5#include "../imageviewer.c"
diff --git a/apps/plugins/png/zconf.h b/apps/plugins/imageviewer/png/zconf.h
index 03a9431c8b..03a9431c8b 100644
--- a/apps/plugins/png/zconf.h
+++ b/apps/plugins/imageviewer/png/zconf.h
diff --git a/apps/plugins/png/zlib.h b/apps/plugins/imageviewer/png/zlib.h
index 23e6dcd8f5..23e6dcd8f5 100644
--- a/apps/plugins/png/zlib.h
+++ b/apps/plugins/imageviewer/png/zlib.h
diff --git a/apps/plugins/png/zutil.h b/apps/plugins/imageviewer/png/zutil.h
index b7d5eff81b..b7d5eff81b 100644
--- a/apps/plugins/png/zutil.h
+++ b/apps/plugins/imageviewer/png/zutil.h
diff --git a/apps/plugins/jpeg/jpeg.h b/apps/plugins/jpeg/jpeg.h
deleted file mode 100644
index 552d26ed1a..0000000000
--- a/apps/plugins/jpeg/jpeg.h
+++ /dev/null
@@ -1,340 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* JPEG image viewer
11* (This is a real mess if it has to be coded in one single C file)
12*
13* File scrolling addition (C) 2005 Alexander Spyridakis
14* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
15* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
16* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
17*
18* This program is free software; you can redistribute it and/or
19* modify it under the terms of the GNU General Public License
20* as published by the Free Software Foundation; either version 2
21* of the License, or (at your option) any later version.
22*
23* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24* KIND, either express or implied.
25*
26****************************************************************************/
27
28#ifndef _JPEG_JPEG_H
29#define _JPEG_JPEG_H
30
31#include "plugin.h"
32
33/* variable button definitions */
34#if CONFIG_KEYPAD == RECORDER_PAD
35#define JPEG_ZOOM_IN BUTTON_PLAY
36#define JPEG_ZOOM_OUT BUTTON_ON
37#define JPEG_UP BUTTON_UP
38#define JPEG_DOWN BUTTON_DOWN
39#define JPEG_LEFT BUTTON_LEFT
40#define JPEG_RIGHT BUTTON_RIGHT
41#define JPEG_NEXT BUTTON_F3
42#define JPEG_PREVIOUS BUTTON_F2
43#define JPEG_MENU BUTTON_OFF
44
45#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
46#define JPEG_ZOOM_IN BUTTON_SELECT
47#define JPEG_ZOOM_OUT BUTTON_ON
48#define JPEG_UP BUTTON_UP
49#define JPEG_DOWN BUTTON_DOWN
50#define JPEG_LEFT BUTTON_LEFT
51#define JPEG_RIGHT BUTTON_RIGHT
52#define JPEG_NEXT BUTTON_F3
53#define JPEG_PREVIOUS BUTTON_F2
54#define JPEG_MENU BUTTON_OFF
55
56#elif CONFIG_KEYPAD == ONDIO_PAD
57#define JPEG_ZOOM_PRE BUTTON_MENU
58#define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
59#define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
60#define JPEG_UP BUTTON_UP
61#define JPEG_DOWN BUTTON_DOWN
62#define JPEG_LEFT BUTTON_LEFT
63#define JPEG_RIGHT BUTTON_RIGHT
64#define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
65#define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
66#define JPEG_MENU BUTTON_OFF
67
68#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
69 (CONFIG_KEYPAD == IRIVER_H300_PAD)
70#define JPEG_ZOOM_IN BUTTON_SELECT
71#define JPEG_ZOOM_OUT BUTTON_MODE
72#define JPEG_UP BUTTON_UP
73#define JPEG_DOWN BUTTON_DOWN
74#define JPEG_LEFT BUTTON_LEFT
75#define JPEG_RIGHT BUTTON_RIGHT
76#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
77#define JPEG_NEXT BUTTON_ON
78#define JPEG_PREVIOUS BUTTON_REC
79#else
80#define JPEG_NEXT BUTTON_REC
81#define JPEG_PREVIOUS BUTTON_ON
82#endif
83#define JPEG_MENU BUTTON_OFF
84#define JPEG_RC_MENU BUTTON_RC_STOP
85
86#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
87 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
88#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
89#define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
90#define JPEG_UP BUTTON_MENU
91#define JPEG_DOWN BUTTON_PLAY
92#define JPEG_LEFT BUTTON_LEFT
93#define JPEG_RIGHT BUTTON_RIGHT
94#define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
95#define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
96#define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
97
98#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
99#define JPEG_ZOOM_PRE BUTTON_SELECT
100#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
101#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
102#define JPEG_UP BUTTON_UP
103#define JPEG_DOWN BUTTON_DOWN
104#define JPEG_LEFT BUTTON_LEFT
105#define JPEG_RIGHT BUTTON_RIGHT
106#define JPEG_MENU BUTTON_POWER
107#define JPEG_NEXT BUTTON_PLAY
108#define JPEG_PREVIOUS BUTTON_REC
109
110#elif CONFIG_KEYPAD == GIGABEAT_PAD
111#define JPEG_ZOOM_IN BUTTON_VOL_UP
112#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
113#define JPEG_UP BUTTON_UP
114#define JPEG_DOWN BUTTON_DOWN
115#define JPEG_LEFT BUTTON_LEFT
116#define JPEG_RIGHT BUTTON_RIGHT
117#define JPEG_MENU BUTTON_MENU
118#define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
119#define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
120
121#elif CONFIG_KEYPAD == SANSA_E200_PAD
122#define JPEG_ZOOM_PRE BUTTON_SELECT
123#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
124#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
125#define JPEG_UP BUTTON_UP
126#define JPEG_DOWN BUTTON_DOWN
127#define JPEG_LEFT BUTTON_LEFT
128#define JPEG_RIGHT BUTTON_RIGHT
129#define JPEG_MENU BUTTON_POWER
130#define JPEG_SLIDE_SHOW BUTTON_REC
131#define JPEG_NEXT BUTTON_SCROLL_FWD
132#define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
133#define JPEG_PREVIOUS BUTTON_SCROLL_BACK
134#define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
135
136#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
137#define JPEG_ZOOM_PRE BUTTON_SELECT
138#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
139#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
140#define JPEG_UP BUTTON_UP
141#define JPEG_DOWN BUTTON_DOWN
142#define JPEG_LEFT BUTTON_LEFT
143#define JPEG_RIGHT BUTTON_RIGHT
144#define JPEG_MENU (BUTTON_HOME|BUTTON_REPEAT)
145#define JPEG_NEXT BUTTON_SCROLL_FWD
146#define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
147#define JPEG_PREVIOUS BUTTON_SCROLL_BACK
148#define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
149
150#elif CONFIG_KEYPAD == SANSA_C200_PAD
151#define JPEG_ZOOM_PRE BUTTON_SELECT
152#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
153#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
154#define JPEG_UP BUTTON_UP
155#define JPEG_DOWN BUTTON_DOWN
156#define JPEG_LEFT BUTTON_LEFT
157#define JPEG_RIGHT BUTTON_RIGHT
158#define JPEG_MENU BUTTON_POWER
159#define JPEG_SLIDE_SHOW BUTTON_REC
160#define JPEG_NEXT BUTTON_VOL_UP
161#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
162#define JPEG_PREVIOUS BUTTON_VOL_DOWN
163#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
164
165#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
166#define JPEG_ZOOM_PRE BUTTON_SELECT
167#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
168#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
169#define JPEG_UP BUTTON_UP
170#define JPEG_DOWN BUTTON_DOWN
171#define JPEG_LEFT BUTTON_LEFT
172#define JPEG_RIGHT BUTTON_RIGHT
173#define JPEG_MENU BUTTON_POWER
174#define JPEG_SLIDE_SHOW BUTTON_HOME
175#define JPEG_NEXT BUTTON_VOL_UP
176#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
177#define JPEG_PREVIOUS BUTTON_VOL_DOWN
178#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
179
180#elif CONFIG_KEYPAD == SANSA_M200_PAD
181#define JPEG_ZOOM_PRE BUTTON_SELECT
182#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
183#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
184#define JPEG_UP BUTTON_UP
185#define JPEG_DOWN BUTTON_DOWN
186#define JPEG_LEFT BUTTON_LEFT
187#define JPEG_RIGHT BUTTON_RIGHT
188#define JPEG_MENU BUTTON_POWER
189#define JPEG_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
190#define JPEG_NEXT BUTTON_VOL_UP
191#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
192#define JPEG_PREVIOUS BUTTON_VOL_DOWN
193#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
194
195#elif CONFIG_KEYPAD == IRIVER_H10_PAD
196#define JPEG_ZOOM_PRE BUTTON_PLAY
197#define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
198#define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
199#define JPEG_UP BUTTON_SCROLL_UP
200#define JPEG_DOWN BUTTON_SCROLL_DOWN
201#define JPEG_LEFT BUTTON_LEFT
202#define JPEG_RIGHT BUTTON_RIGHT
203#define JPEG_MENU BUTTON_POWER
204#define JPEG_NEXT BUTTON_FF
205#define JPEG_PREVIOUS BUTTON_REW
206
207#elif CONFIG_KEYPAD == MROBE500_PAD
208#define JPEG_MENU BUTTON_POWER
209
210#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
211#define JPEG_ZOOM_IN BUTTON_VOL_UP
212#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
213#define JPEG_UP BUTTON_UP
214#define JPEG_DOWN BUTTON_DOWN
215#define JPEG_LEFT BUTTON_LEFT
216#define JPEG_RIGHT BUTTON_RIGHT
217#define JPEG_MENU BUTTON_MENU
218#define JPEG_NEXT BUTTON_NEXT
219#define JPEG_PREVIOUS BUTTON_PREV
220
221#elif CONFIG_KEYPAD == MROBE100_PAD
222#define JPEG_ZOOM_IN BUTTON_SELECT
223#define JPEG_ZOOM_OUT BUTTON_PLAY
224#define JPEG_UP BUTTON_UP
225#define JPEG_DOWN BUTTON_DOWN
226#define JPEG_LEFT BUTTON_LEFT
227#define JPEG_RIGHT BUTTON_RIGHT
228#define JPEG_MENU BUTTON_MENU
229#define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
230#define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
231
232#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
233#define JPEG_ZOOM_PRE BUTTON_RC_PLAY
234#define JPEG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
235#define JPEG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
236#define JPEG_UP BUTTON_RC_VOL_UP
237#define JPEG_DOWN BUTTON_RC_VOL_DOWN
238#define JPEG_LEFT BUTTON_RC_REW
239#define JPEG_RIGHT BUTTON_RC_FF
240#define JPEG_MENU BUTTON_RC_REC
241#define JPEG_NEXT BUTTON_RC_MODE
242#define JPEG_PREVIOUS BUTTON_RC_MENU
243
244#elif CONFIG_KEYPAD == COWON_D2_PAD
245
246#elif CONFIG_KEYPAD == IAUDIO67_PAD
247#define JPEG_ZOOM_IN BUTTON_VOLUP
248#define JPEG_ZOOM_OUT BUTTON_VOLDOWN
249#define JPEG_UP BUTTON_STOP
250#define JPEG_DOWN BUTTON_PLAY
251#define JPEG_LEFT BUTTON_LEFT
252#define JPEG_RIGHT BUTTON_RIGHT
253#define JPEG_MENU BUTTON_MENU
254#define JPEG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
255#define JPEG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
256
257#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
258
259#define JPEG_ZOOM_IN BUTTON_PLAY
260#define JPEG_ZOOM_OUT BUTTON_CUSTOM
261#define JPEG_UP BUTTON_UP
262#define JPEG_DOWN BUTTON_DOWN
263#define JPEG_LEFT BUTTON_LEFT
264#define JPEG_RIGHT BUTTON_RIGHT
265#define JPEG_MENU BUTTON_MENU
266#define JPEG_NEXT BUTTON_SELECT
267#define JPEG_PREVIOUS BUTTON_BACK
268
269#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
270#define JPEG_ZOOM_IN BUTTON_VOL_UP
271#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
272#define JPEG_UP BUTTON_UP
273#define JPEG_DOWN BUTTON_DOWN
274#define JPEG_LEFT BUTTON_LEFT
275#define JPEG_RIGHT BUTTON_RIGHT
276#define JPEG_MENU BUTTON_MENU
277#define JPEG_NEXT BUTTON_VIEW
278#define JPEG_PREVIOUS BUTTON_PLAYLIST
279
280#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
281#define JPEG_ZOOM_IN BUTTON_VOL_UP
282#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
283#define JPEG_UP BUTTON_UP
284#define JPEG_DOWN BUTTON_DOWN
285#define JPEG_LEFT BUTTON_PREV
286#define JPEG_RIGHT BUTTON_NEXT
287#define JPEG_MENU BUTTON_MENU
288#define JPEG_NEXT BUTTON_RIGHT
289#define JPEG_PREVIOUS BUTTON_LEFT
290
291#elif CONFIG_KEYPAD == ONDAVX747_PAD
292#elif CONFIG_KEYPAD == ONDAVX777_PAD
293
294#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
295#define JPEG_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
296#define JPEG_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
297#define JPEG_UP BUTTON_UP
298#define JPEG_DOWN BUTTON_DOWN
299#define JPEG_LEFT BUTTON_LEFT
300#define JPEG_RIGHT BUTTON_RIGHT
301#define JPEG_MENU BUTTON_PLAY
302#define JPEG_NEXT BUTTON_FFWD
303#define JPEG_PREVIOUS BUTTON_REW
304
305#else
306#error No keymap defined!
307#endif
308
309#ifdef HAVE_TOUCHSCREEN
310#ifndef JPEG_UP
311#define JPEG_UP BUTTON_TOPMIDDLE
312#endif
313#ifndef JPEG_DOWN
314#define JPEG_DOWN BUTTON_BOTTOMMIDDLE
315#endif
316#ifndef JPEG_LEFT
317#define JPEG_LEFT BUTTON_MIDLEFT
318#endif
319#ifndef JPEG_RIGHT
320#define JPEG_RIGHT BUTTON_MIDRIGHT
321#endif
322#ifndef JPEG_ZOOM_IN
323#define JPEG_ZOOM_IN BUTTON_TOPRIGHT
324#endif
325#ifndef JPEG_ZOOM_OUT
326#define JPEG_ZOOM_OUT BUTTON_TOPLEFT
327#endif
328#ifndef JPEG_MENU
329#define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
330#endif
331#ifndef JPEG_NEXT
332#define JPEG_NEXT BUTTON_BOTTOMRIGHT
333#endif
334#ifndef JPEG_PREVIOUS
335#define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
336#endif
337#endif
338
339
340#endif /* _JPEG_JPEG_H */
diff --git a/apps/plugins/png/png.h b/apps/plugins/png/png.h
deleted file mode 100644
index 4699e24e70..0000000000
--- a/apps/plugins/png/png.h
+++ /dev/null
@@ -1,366 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$id $
9 *
10 * Copyright (C) 2009 by Christophe Gouiran <bechris13250 -at- gmail -dot- com>
11 *
12 * Based on lodepng, a lightweight png decoder/encoder
13 * (c) 2005-2008 Lode Vandevenne
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25/*
26LodePNG version 20080927
27
28Copyright (c) 2005-2008 Lode Vandevenne
29
30This software is provided 'as-is', without any express or implied
31warranty. In no event will the authors be held liable for any damages
32arising from the use of this software.
33
34Permission is granted to anyone to use this software for any purpose,
35including commercial applications, and to alter it and redistribute it
36freely, subject to the following restrictions:
37
38 1. The origin of this software must not be misrepresented; you must not
39 claim that you wrote the original software. If you use this software
40 in a product, an acknowledgment in the product documentation would be
41 appreciated but is not required.
42
43 2. Altered source versions must be plainly marked as such, and must not be
44 misrepresented as being the original software.
45
46 3. This notice may not be removed or altered from any source
47 distribution.
48*/
49
50/*
51The manual and changelog can be found in the header file "lodepng.h"
52You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
53*/
54
55/* variable button definitions */
56#if CONFIG_KEYPAD == RECORDER_PAD
57#define PNG_ZOOM_IN BUTTON_PLAY
58#define PNG_ZOOM_OUT BUTTON_ON
59#define PNG_UP BUTTON_UP
60#define PNG_DOWN BUTTON_DOWN
61#define PNG_LEFT BUTTON_LEFT
62#define PNG_RIGHT BUTTON_RIGHT
63#define PNG_NEXT BUTTON_F3
64#define PNG_PREVIOUS BUTTON_F2
65#define PNG_MENU BUTTON_OFF
66
67#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
68#define PNG_ZOOM_IN BUTTON_SELECT
69#define PNG_ZOOM_OUT BUTTON_ON
70#define PNG_UP BUTTON_UP
71#define PNG_DOWN BUTTON_DOWN
72#define PNG_LEFT BUTTON_LEFT
73#define PNG_RIGHT BUTTON_RIGHT
74#define PNG_NEXT BUTTON_F3
75#define PNG_PREVIOUS BUTTON_F2
76#define PNG_MENU BUTTON_OFF
77
78#elif CONFIG_KEYPAD == ONDIO_PAD
79#define PNG_ZOOM_PRE BUTTON_MENU
80#define PNG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
81#define PNG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
82#define PNG_UP BUTTON_UP
83#define PNG_DOWN BUTTON_DOWN
84#define PNG_LEFT BUTTON_LEFT
85#define PNG_RIGHT BUTTON_RIGHT
86#define PNG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
87#define PNG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
88#define PNG_MENU BUTTON_OFF
89
90#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
91 (CONFIG_KEYPAD == IRIVER_H300_PAD)
92#define PNG_ZOOM_IN BUTTON_SELECT
93#define PNG_ZOOM_OUT BUTTON_MODE
94#define PNG_UP BUTTON_UP
95#define PNG_DOWN BUTTON_DOWN
96#define PNG_LEFT BUTTON_LEFT
97#define PNG_RIGHT BUTTON_RIGHT
98#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
99#define PNG_NEXT BUTTON_ON
100#define PNG_PREVIOUS BUTTON_REC
101#else
102#define PNG_NEXT BUTTON_REC
103#define PNG_PREVIOUS BUTTON_ON
104#endif
105#define PNG_MENU BUTTON_OFF
106#define PNG_RC_MENU BUTTON_RC_STOP
107
108#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
109 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
110#define PNG_ZOOM_IN BUTTON_SCROLL_FWD
111#define PNG_ZOOM_OUT BUTTON_SCROLL_BACK
112#define PNG_UP BUTTON_MENU
113#define PNG_DOWN BUTTON_PLAY
114#define PNG_LEFT BUTTON_LEFT
115#define PNG_RIGHT BUTTON_RIGHT
116#define PNG_MENU (BUTTON_SELECT | BUTTON_MENU)
117#define PNG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
118#define PNG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
119
120#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
121#define PNG_ZOOM_PRE BUTTON_SELECT
122#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
123#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
124#define PNG_UP BUTTON_UP
125#define PNG_DOWN BUTTON_DOWN
126#define PNG_LEFT BUTTON_LEFT
127#define PNG_RIGHT BUTTON_RIGHT
128#define PNG_MENU BUTTON_POWER
129#define PNG_NEXT BUTTON_PLAY
130#define PNG_PREVIOUS BUTTON_REC
131
132#elif CONFIG_KEYPAD == GIGABEAT_PAD
133#define PNG_ZOOM_IN BUTTON_VOL_UP
134#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
135#define PNG_UP BUTTON_UP
136#define PNG_DOWN BUTTON_DOWN
137#define PNG_LEFT BUTTON_LEFT
138#define PNG_RIGHT BUTTON_RIGHT
139#define PNG_MENU BUTTON_MENU
140#define PNG_NEXT (BUTTON_A | BUTTON_RIGHT)
141#define PNG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
142
143#elif CONFIG_KEYPAD == SANSA_E200_PAD
144#define PNG_ZOOM_PRE BUTTON_SELECT
145#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
146#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
147#define PNG_UP BUTTON_UP
148#define PNG_DOWN BUTTON_DOWN
149#define PNG_LEFT BUTTON_LEFT
150#define PNG_RIGHT BUTTON_RIGHT
151#define PNG_MENU BUTTON_POWER
152#define PNG_SLIDE_SHOW BUTTON_REC
153#define PNG_NEXT BUTTON_SCROLL_FWD
154#define PNG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
155#define PNG_PREVIOUS BUTTON_SCROLL_BACK
156#define PNG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
157
158#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
159#define PNG_ZOOM_PRE BUTTON_SELECT
160#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
161#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
162#define PNG_UP BUTTON_UP
163#define PNG_DOWN BUTTON_DOWN
164#define PNG_LEFT BUTTON_LEFT
165#define PNG_RIGHT BUTTON_RIGHT
166#define PNG_MENU (BUTTON_HOME|BUTTON_REPEAT)
167#define PNG_NEXT BUTTON_SCROLL_FWD
168#define PNG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
169#define PNG_PREVIOUS BUTTON_SCROLL_BACK
170#define PNG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
171
172#elif CONFIG_KEYPAD == SANSA_C200_PAD
173#define PNG_ZOOM_PRE BUTTON_SELECT
174#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
175#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
176#define PNG_UP BUTTON_UP
177#define PNG_DOWN BUTTON_DOWN
178#define PNG_LEFT BUTTON_LEFT
179#define PNG_RIGHT BUTTON_RIGHT
180#define PNG_MENU BUTTON_POWER
181#define PNG_SLIDE_SHOW BUTTON_REC
182#define PNG_NEXT BUTTON_VOL_UP
183#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
184#define PNG_PREVIOUS BUTTON_VOL_DOWN
185#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
186
187#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
188#define PNG_ZOOM_PRE BUTTON_SELECT
189#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
190#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
191#define PNG_UP BUTTON_UP
192#define PNG_DOWN BUTTON_DOWN
193#define PNG_LEFT BUTTON_LEFT
194#define PNG_RIGHT BUTTON_RIGHT
195#define PNG_MENU BUTTON_POWER
196#define PNG_SLIDE_SHOW BUTTON_HOME
197#define PNG_NEXT BUTTON_VOL_UP
198#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
199#define PNG_PREVIOUS BUTTON_VOL_DOWN
200#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
201
202#elif CONFIG_KEYPAD == SANSA_M200_PAD
203#define PNG_ZOOM_PRE BUTTON_SELECT
204#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
205#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
206#define PNG_UP BUTTON_UP
207#define PNG_DOWN BUTTON_DOWN
208#define PNG_LEFT BUTTON_LEFT
209#define PNG_RIGHT BUTTON_RIGHT
210#define PNG_MENU BUTTON_POWER
211#define PNG_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
212#define PNG_NEXT BUTTON_VOL_UP
213#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
214#define PNG_PREVIOUS BUTTON_VOL_DOWN
215#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
216
217#elif CONFIG_KEYPAD == IRIVER_H10_PAD
218#define PNG_ZOOM_PRE BUTTON_PLAY
219#define PNG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
220#define PNG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
221#define PNG_UP BUTTON_SCROLL_UP
222#define PNG_DOWN BUTTON_SCROLL_DOWN
223#define PNG_LEFT BUTTON_LEFT
224#define PNG_RIGHT BUTTON_RIGHT
225#define PNG_MENU BUTTON_POWER
226#define PNG_NEXT BUTTON_FF
227#define PNG_PREVIOUS BUTTON_REW
228
229#elif CONFIG_KEYPAD == MROBE500_PAD
230
231#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
232#define PNG_ZOOM_IN BUTTON_VOL_UP
233#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
234#define PNG_UP BUTTON_UP
235#define PNG_DOWN BUTTON_DOWN
236#define PNG_LEFT BUTTON_LEFT
237#define PNG_RIGHT BUTTON_RIGHT
238#define PNG_MENU BUTTON_MENU
239#define PNG_NEXT BUTTON_NEXT
240#define PNG_PREVIOUS BUTTON_PREV
241
242#elif CONFIG_KEYPAD == MROBE100_PAD
243#define PNG_ZOOM_IN BUTTON_SELECT
244#define PNG_ZOOM_OUT BUTTON_PLAY
245#define PNG_UP BUTTON_UP
246#define PNG_DOWN BUTTON_DOWN
247#define PNG_LEFT BUTTON_LEFT
248#define PNG_RIGHT BUTTON_RIGHT
249#define PNG_MENU BUTTON_MENU
250#define PNG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
251#define PNG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
252
253#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
254#define PNG_ZOOM_PRE BUTTON_RC_PLAY
255#define PNG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
256#define PNG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
257#define PNG_UP BUTTON_RC_VOL_UP
258#define PNG_DOWN BUTTON_RC_VOL_DOWN
259#define PNG_LEFT BUTTON_RC_REW
260#define PNG_RIGHT BUTTON_RC_FF
261#define PNG_MENU BUTTON_RC_REC
262#define PNG_NEXT BUTTON_RC_MODE
263#define PNG_PREVIOUS BUTTON_RC_MENU
264
265#elif CONFIG_KEYPAD == COWON_D2_PAD
266
267#elif CONFIG_KEYPAD == IAUDIO67_PAD
268#define PNG_ZOOM_IN BUTTON_VOLUP
269#define PNG_ZOOM_OUT BUTTON_VOLDOWN
270#define PNG_UP BUTTON_STOP
271#define PNG_DOWN BUTTON_PLAY
272#define PNG_LEFT BUTTON_LEFT
273#define PNG_RIGHT BUTTON_RIGHT
274#define PNG_MENU BUTTON_MENU
275#define PNG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
276#define PNG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
277
278#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
279
280#define PNG_ZOOM_IN BUTTON_PLAY
281#define PNG_ZOOM_OUT BUTTON_CUSTOM
282#define PNG_UP BUTTON_UP
283#define PNG_DOWN BUTTON_DOWN
284#define PNG_LEFT BUTTON_LEFT
285#define PNG_RIGHT BUTTON_RIGHT
286#define PNG_MENU BUTTON_MENU
287#define PNG_NEXT BUTTON_SELECT
288#define PNG_PREVIOUS BUTTON_BACK
289
290#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
291#define PNG_ZOOM_IN BUTTON_VOL_UP
292#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
293#define PNG_UP BUTTON_UP
294#define PNG_DOWN BUTTON_DOWN
295#define PNG_LEFT BUTTON_LEFT
296#define PNG_RIGHT BUTTON_RIGHT
297#define PNG_MENU BUTTON_MENU
298#define PNG_NEXT BUTTON_VIEW
299#define PNG_PREVIOUS BUTTON_PLAYLIST
300
301#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
302#define PNG_ZOOM_IN BUTTON_VOL_UP
303#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
304#define PNG_UP BUTTON_UP
305#define PNG_DOWN BUTTON_DOWN
306#define PNG_LEFT BUTTON_PREV
307#define PNG_RIGHT BUTTON_NEXT
308#define PNG_MENU BUTTON_MENU
309#define PNG_NEXT BUTTON_RIGHT
310#define PNG_PREVIOUS BUTTON_LEFT
311
312#elif CONFIG_KEYPAD == ONDAVX747_PAD
313#define PNG_MENU BUTTON_POWER
314#elif CONFIG_KEYPAD == ONDAVX777_PAD
315#define PNG_MENU BUTTON_POWER
316
317#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
318#define PNG_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
319#define PNG_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
320#define PNG_UP BUTTON_UP
321#define PNG_DOWN BUTTON_DOWN
322#define PNG_LEFT BUTTON_LEFT
323#define PNG_RIGHT BUTTON_RIGHT
324#define PNG_MENU BUTTON_PLAY
325#define PNG_NEXT BUTTON_FFWD
326#define PNG_PREVIOUS BUTTON_REW
327
328#else
329#error No keymap defined!
330#endif
331
332#ifdef HAVE_TOUCHSCREEN
333#ifndef PNG_UP
334#define PNG_UP BUTTON_TOPMIDDLE
335#endif
336#ifndef PNG_DOWN
337#define PNG_DOWN BUTTON_BOTTOMMIDDLE
338#endif
339#ifndef PNG_LEFT
340#define PNG_LEFT BUTTON_MIDLEFT
341#endif
342#ifndef PNG_RIGHT
343#define PNG_RIGHT BUTTON_MIDRIGHT
344#endif
345#ifndef PNG_ZOOM_IN
346#define PNG_ZOOM_IN BUTTON_TOPRIGHT
347#endif
348#ifndef PNG_ZOOM_OUT
349#define PNG_ZOOM_OUT BUTTON_TOPLEFT
350#endif
351#ifndef PNG_MENU
352#define PNG_MENU (BUTTON_CENTER|BUTTON_REL)
353#endif
354#ifndef PNG_NEXT
355#define PNG_NEXT BUTTON_BOTTOMRIGHT
356#endif
357#ifndef PNG_PREVIOUS
358#define PNG_PREVIOUS BUTTON_BOTTOMLEFT
359#endif
360#endif
361
362#define PLUGIN_OTHER 10 /* State code for output with return. */
363#define PLUGIN_ABORT 11
364#define PLUGIN_OUTOFMEM 12
365#define OUT_OF_MEMORY 9900
366#define FILE_TOO_LARGE 9910