summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-11-21 13:47:56 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-11-21 13:47:56 +0000
commite5b1a7d4237a9006b6c49c9c1c13b292ca4ecf7c (patch)
treef0b9dd1cba0a4ee70afd8b6da64a05286f76c380
parenteef21cb18ae4bc7cdf83830554a848e0c733a73d (diff)
downloadrockbox-e5b1a7d4237a9006b6c49c9c1c13b292ca4ecf7c.tar.gz
rockbox-e5b1a7d4237a9006b6c49c9c1c13b292ca4ecf7c.zip
FS#6321: Universal Image Viewer
This unifies jpeg viewer, png viewer, and bmp viewer to one plugin, image viewer, so that you can navigate through different image formats. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28626 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/CATEGORIES1
-rw-r--r--apps/plugins/imageviewer/SOURCES2
-rw-r--r--apps/plugins/imageviewer/bmp/SOURCES1
-rw-r--r--apps/plugins/imageviewer/bmp/bmp.c47
-rw-r--r--apps/plugins/imageviewer/bmp/bmp.make14
-rw-r--r--apps/plugins/imageviewer/bmp/bmp_ui.c5
-rw-r--r--apps/plugins/imageviewer/image_decoder.c130
-rw-r--r--apps/plugins/imageviewer/image_decoder.h46
-rw-r--r--apps/plugins/imageviewer/imageviewer.c219
-rw-r--r--apps/plugins/imageviewer/imageviewer.h104
-rw-r--r--apps/plugins/imageviewer/imageviewer.make45
-rw-r--r--apps/plugins/imageviewer/jpeg/SOURCES1
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg.c52
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg.make14
-rw-r--r--apps/plugins/imageviewer/jpeg/jpeg_ui.c5
-rw-r--r--apps/plugins/imageviewer/png/SOURCES1
-rw-r--r--apps/plugins/imageviewer/png/png.c55
-rw-r--r--apps/plugins/imageviewer/png/png.make13
-rw-r--r--apps/plugins/imageviewer/png/png_ui.c5
-rw-r--r--apps/plugins/plugin.lds3
-rw-r--r--apps/plugins/viewers.config10
-rwxr-xr-xmanual/plugins/bmpviewer.tex115
-rw-r--r--manual/plugins/imageviewer.tex (renamed from manual/plugins/jpegviewer.tex)34
-rw-r--r--manual/plugins/main.tex12
-rw-r--r--manual/plugins/pngviewer.tex113
-rwxr-xr-xtools/buildzip.pl7
26 files changed, 579 insertions, 475 deletions
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index 1d9aa8aee0..983e52c88a 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -35,6 +35,7 @@ frotz,viewers
35goban,games 35goban,games
36greyscale,demos 36greyscale,demos
37helloworld,demos 37helloworld,demos
38imageviewer,viewers
38invadrox,games 39invadrox,games
39iriver_flash,apps 40iriver_flash,apps
40iriverify,viewers 41iriverify,viewers
diff --git a/apps/plugins/imageviewer/SOURCES b/apps/plugins/imageviewer/SOURCES
new file mode 100644
index 0000000000..610087bf82
--- /dev/null
+++ b/apps/plugins/imageviewer/SOURCES
@@ -0,0 +1,2 @@
1imageviewer.c
2image_decoder.c
diff --git a/apps/plugins/imageviewer/bmp/SOURCES b/apps/plugins/imageviewer/bmp/SOURCES
index a50d245846..29297c9ec2 100644
--- a/apps/plugins/imageviewer/bmp/SOURCES
+++ b/apps/plugins/imageviewer/bmp/SOURCES
@@ -1,2 +1 @@
1bmp_ui.c
2bmp.c bmp.c
diff --git a/apps/plugins/imageviewer/bmp/bmp.c b/apps/plugins/imageviewer/bmp/bmp.c
index 6d33575f98..b7efbb7e2c 100644
--- a/apps/plugins/imageviewer/bmp/bmp.c
+++ b/apps/plugins/imageviewer/bmp/bmp.c
@@ -65,18 +65,13 @@ struct bitmap bmp;
65 65
66/************************* Implementation ***************************/ 66/************************* Implementation ***************************/
67 67
68bool img_ext(const char *ext) 68#if defined(USEGSLIB) && (CONFIG_PLATFORM & PLATFORM_HOSTED)
69{ 69/* hack: fix error "undefined reference to `_grey_info'". */
70 if (!ext) 70GREY_INFO_STRUCT
71 return false; 71#endif /* USEGSLIB */
72 if (!rb->strcasecmp(ext,".bmp"))
73 return true;
74 else
75 return false;
76}
77 72
78void draw_image_rect(struct image_info *info, 73static void draw_image_rect(struct image_info *info,
79 int x, int y, int width, int height) 74 int x, int y, int width, int height)
80{ 75{
81 struct t_disp* pdisp = (struct t_disp*)info->data; 76 struct t_disp* pdisp = (struct t_disp*)info->data;
82#ifdef HAVE_LCD_COLOR 77#ifdef HAVE_LCD_COLOR
@@ -95,7 +90,7 @@ void draw_image_rect(struct image_info *info,
95#endif 90#endif
96} 91}
97 92
98int img_mem(int ds) 93static int img_mem(int ds)
99{ 94{
100#ifndef USEGSLIB 95#ifndef USEGSLIB
101 return (bmp.width/ds) * (bmp.height/ds) * sizeof (fb_data); 96 return (bmp.width/ds) * (bmp.height/ds) * sizeof (fb_data);
@@ -104,8 +99,8 @@ int img_mem(int ds)
104#endif 99#endif
105} 100}
106 101
107int load_image(char *filename, struct image_info *info, 102static int load_image(char *filename, struct image_info *info,
108 unsigned char *buf, ssize_t *buf_size) 103 unsigned char *buf, ssize_t *buf_size)
109{ 104{
110 int w, h; /* used to center output */ 105 int w, h; /* used to center output */
111 long time; /* measured ticks */ 106 long time; /* measured ticks */
@@ -147,7 +142,7 @@ int load_image(char *filename, struct image_info *info,
147 } 142 }
148#endif 143#endif
149#ifdef USE_PLUG_BUF 144#ifdef USE_PLUG_BUF
150 if (!plug_buf) 145 if (!iv->plug_buf)
151#endif 146#endif
152 { 147 {
153 while (size > *buf_size && bmp.width >= 2 && bmp.height >= 2 && ds < 8) 148 while (size > *buf_size && bmp.width >= 2 && bmp.height >= 2 && ds < 8)
@@ -174,7 +169,7 @@ int load_image(char *filename, struct image_info *info,
174 return PLUGIN_OUTOFMEM; 169 return PLUGIN_OUTOFMEM;
175 } 170 }
176 171
177 if (!running_slideshow) 172 if (!iv->running_slideshow)
178 { 173 {
179 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); 174 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1);
180 rb->lcd_putsf(0, 1, "loading %dx%d%s", 175 rb->lcd_putsf(0, 1, "loading %dx%d%s",
@@ -204,7 +199,7 @@ int load_image(char *filename, struct image_info *info,
204 return PLUGIN_ERROR; 199 return PLUGIN_ERROR;
205 } 200 }
206 201
207 if (!running_slideshow) 202 if (!iv->running_slideshow)
208 { 203 {
209 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ); 204 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
210 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */ 205 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
@@ -212,7 +207,7 @@ int load_image(char *filename, struct image_info *info,
212 rb->lcd_update(); 207 rb->lcd_update();
213 } 208 }
214#ifdef DISK_SPINDOWN 209#ifdef DISK_SPINDOWN
215 else if (immediate_ata_off) 210 else if(iv->immediate_ata_off)
216 { 211 {
217 /* running slideshow and time is long enough: power down disk */ 212 /* running slideshow and time is long enough: power down disk */
218 rb->storage_sleep(); 213 rb->storage_sleep();
@@ -223,7 +218,7 @@ int load_image(char *filename, struct image_info *info,
223 buf_images = buf_root = buf + size; 218 buf_images = buf_root = buf + size;
224 buf_images_size = root_size = *buf_size - size; 219 buf_images_size = root_size = *buf_size - size;
225 220
226 if (!running_slideshow) 221 if (!iv->running_slideshow)
227 { 222 {
228 rb->lcd_putsf(0, 2, "image %dx%d", bmp.width, bmp.height); 223 rb->lcd_putsf(0, 2, "image %dx%d", bmp.width, bmp.height);
229 rb->lcd_update(); 224 rb->lcd_update();
@@ -235,7 +230,7 @@ int load_image(char *filename, struct image_info *info,
235 return PLUGIN_OK; 230 return PLUGIN_OK;
236} 231}
237 232
238int get_image(struct image_info *info, int ds) 233static int get_image(struct image_info *info, int ds)
239{ 234{
240 struct t_disp* p_disp = &disp[ds]; /* short cut */ 235 struct t_disp* p_disp = &disp[ds]; /* short cut */
241 236
@@ -270,7 +265,7 @@ int get_image(struct image_info *info, int ds)
270 buf_images += size; 265 buf_images += size;
271 buf_images_size -= size; 266 buf_images_size -= size;
272 267
273 if (!running_slideshow) 268 if (!iv->running_slideshow)
274 { 269 {
275 rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height); 270 rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height);
276 rb->lcd_update(); 271 rb->lcd_update();
@@ -294,3 +289,13 @@ int get_image(struct image_info *info, int ds)
294 289
295 return PLUGIN_OK; 290 return PLUGIN_OK;
296} 291}
292
293const struct image_decoder image_decoder = {
294 true,
295 img_mem,
296 load_image,
297 get_image,
298 draw_image_rect,
299};
300
301IMGDEC_HEADER
diff --git a/apps/plugins/imageviewer/bmp/bmp.make b/apps/plugins/imageviewer/bmp/bmp.make
index 0582ba3eb3..0947dd6166 100644
--- a/apps/plugins/imageviewer/bmp/bmp.make
+++ b/apps/plugins/imageviewer/bmp/bmp.make
@@ -10,12 +10,18 @@
10BMPSRCDIR := $(IMGVSRCDIR)/bmp 10BMPSRCDIR := $(IMGVSRCDIR)/bmp
11BMPBUILDDIR := $(IMGVBUILDDIR)/bmp 11BMPBUILDDIR := $(IMGVBUILDDIR)/bmp
12 12
13ROCKS += $(BMPBUILDDIR)/bmp.rock
14
15BMP_SRC := $(call preprocess, $(BMPSRCDIR)/SOURCES) 13BMP_SRC := $(call preprocess, $(BMPSRCDIR)/SOURCES)
16BMP_OBJ := $(call c2obj, $(BMP_SRC)) 14BMP_OBJ := $(call c2obj, $(BMP_SRC))
17 15
18# add source files to OTHER_SRC to get automatic dependencies
19OTHER_SRC += $(BMP_SRC) 16OTHER_SRC += $(BMP_SRC)
20 17
21$(BMPBUILDDIR)/bmp.rock: $(BMP_OBJ) 18ROCKS += $(BMPBUILDDIR)/bmp.ovl
19
20$(BMPBUILDDIR)/bmp.refmap: $(BMP_OBJ)
21$(BMPBUILDDIR)/bmp.link: $(PLUGIN_LDS) $(BMPBUILDDIR)/bmp.refmap
22$(BMPBUILDDIR)/bmp.ovl: $(BMP_OBJ)
23
24# special pattern rule for compiling image decoder with extra flags
25$(BMPBUILDDIR)/%.o: $(BMPSRCDIR)/%.c $(BMPSRCDIR)/bmp.make
26 $(SILENT)mkdir -p $(dir $@)
27 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(IMGDECFLAGS) -c $< -o $@
diff --git a/apps/plugins/imageviewer/bmp/bmp_ui.c b/apps/plugins/imageviewer/bmp/bmp_ui.c
deleted file mode 100644
index 8ff3e0c880..0000000000
--- a/apps/plugins/imageviewer/bmp/bmp_ui.c
+++ /dev/null
@@ -1,5 +0,0 @@
1#define BMP_VIEWER
2#define MENU_TITLE "BMP Menu"
3#define UNSCALED_IS_AVAILABLE 1
4
5#include "../imageviewer.c"
diff --git a/apps/plugins/imageviewer/image_decoder.c b/apps/plugins/imageviewer/image_decoder.c
new file mode 100644
index 0000000000..b4fa27e425
--- /dev/null
+++ b/apps/plugins/imageviewer/image_decoder.c
@@ -0,0 +1,130 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * load image decoder.
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#include "plugin.h"
23#include "imageviewer.h"
24#include "image_decoder.h"
25
26static const char *decoder_names[MAX_IMAGE_TYPES] = {
27 "bmp",
28 "jpeg",
29 "png",
30};
31
32/* check file type by extention */
33enum image_type get_image_type(const char *name)
34{
35 static const struct {
36 char *ext;
37 enum image_type type;
38 } ext_list[] = {
39 { ".bmp", IMAGE_BMP },
40 { ".jpg", IMAGE_JPEG },
41 { ".jpe", IMAGE_JPEG },
42 { ".jpeg", IMAGE_JPEG },
43 { ".png", IMAGE_PNG },
44 };
45
46 const char *ext = rb->strrchr(name, '.');
47 int i;
48 if (!ext)
49 return IMAGE_UNKNOWN;
50
51 for (i = 0; i < (int)ARRAYLEN(ext_list); i++)
52 {
53 if (!rb->strcasecmp(ext, ext_list[i].ext))
54 return ext_list[i].type;
55 }
56 return IMAGE_UNKNOWN;
57}
58
59static void *decoder_handle = NULL;
60const struct image_decoder *load_decoder(struct loader_info *loader_info)
61{
62 const char *name;
63 char filename[MAX_PATH];
64 struct imgdec_header *hdr;
65 struct lc_header *lc_hdr;
66
67 if (loader_info->type < 0 || loader_info->type >= MAX_IMAGE_TYPES)
68 {
69 rb->splashf(2*HZ, "Unknown type: %d", loader_info->type);
70 goto error;
71 }
72
73 release_decoder();
74
75 name = decoder_names[loader_info->type];
76 rb->snprintf(filename, MAX_PATH, VIEWERS_DIR "/%s.ovl", name);
77
78 /* load decoder to the buffer. */
79 decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size);
80 if (!decoder_handle)
81 {
82 rb->splashf(2*HZ, "Can't open %s", filename);
83 goto error;
84 }
85
86 hdr = rb->lc_get_header(decoder_handle);
87 if (!hdr)
88 {
89 rb->splash(2*HZ, "Can't get header");
90 goto error_close;
91 }
92 lc_hdr = &hdr->lc_hdr;
93
94 if (lc_hdr->magic != PLUGIN_MAGIC || lc_hdr->target_id != TARGET_ID)
95 {
96 rb->splashf(2*HZ, "%s decoder: Incompatible model.", name);
97 goto error_close;
98 }
99
100 if (lc_hdr->api_version != IMGDEC_API_VERSION)
101 {
102 rb->splashf(2*HZ, "%s decoder: Incompatible version.", name);
103 goto error_close;
104 }
105
106 *(hdr->api) = rb;
107 *(hdr->img_api) = loader_info->iv;
108
109 /* set remaining buffer size to loader_info. decoder will
110 * be loaded to the end of the buffer, so fix size only. */
111#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
112 loader_info->size = lc_hdr->load_addr - loader_info->buffer;
113#endif
114
115 return hdr->decoder;
116
117error_close:
118 release_decoder();
119error:
120 return NULL;
121}
122
123void release_decoder(void)
124{
125 if (decoder_handle != NULL)
126 {
127 rb->lc_close(decoder_handle);
128 decoder_handle = NULL;
129 }
130}
diff --git a/apps/plugins/imageviewer/image_decoder.h b/apps/plugins/imageviewer/image_decoder.h
new file mode 100644
index 0000000000..93608b1b9a
--- /dev/null
+++ b/apps/plugins/imageviewer/image_decoder.h
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * load image decoder.
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 _IMAGE_DECODER_H
23#define _IMAGE_DECODER_H
24
25#include "imageviewer.h"
26
27enum image_type {
28 IMAGE_UNKNOWN = -1,
29 IMAGE_BMP = 0,
30 IMAGE_JPEG,
31 IMAGE_PNG,
32 MAX_IMAGE_TYPES
33};
34
35struct loader_info {
36 enum image_type type;
37 const struct imgdec_api *iv;
38 unsigned char* buffer;
39 size_t size;
40};
41
42enum image_type get_image_type(const char *name);
43const struct image_decoder *load_decoder(struct loader_info *loader_info);
44void release_decoder(void);
45
46#endif /* _IMAGE_DECODER_H */
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c
index e3c72ae291..01b9f31be1 100644
--- a/apps/plugins/imageviewer/imageviewer.c
+++ b/apps/plugins/imageviewer/imageviewer.c
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * user intereface of image viewers (jpeg, png, etc.) 10 * user intereface of image viewer
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -19,11 +19,16 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22/*
23 * TODO:
24 * - check magick value in file header to determine image type.
25 */
22#include "plugin.h" 26#include "plugin.h"
23#include <lib/playback_control.h> 27#include <lib/playback_control.h>
24#include <lib/helper.h> 28#include <lib/helper.h>
25#include <lib/configfile.h> 29#include <lib/configfile.h>
26#include "imageviewer.h" 30#include "imageviewer.h"
31#include "image_decoder.h"
27 32
28 33
29 34
@@ -38,16 +43,6 @@ GREY_INFO_STRUCT
38 43
39/******************************* Globals ***********************************/ 44/******************************* Globals ***********************************/
40 45
41bool slideshow_enabled = false; /* run slideshow */
42bool running_slideshow = false; /* loading image because of slideshow */
43#ifdef DISK_SPINDOWN
44bool immediate_ata_off = false; /* power down disk after loading */
45#endif
46#ifdef USE_PLUG_BUF
47/* are we using the plugin buffer or the audio buffer? */
48bool plug_buf = true;
49#endif
50
51/* Persistent configuration */ 46/* Persistent configuration */
52#define IMGVIEW_CONFIGFILE "imageviewer.cfg" 47#define IMGVIEW_CONFIGFILE "imageviewer.cfg"
53#define IMGVIEW_SETTINGS_MINVERSION 1 48#define IMGVIEW_SETTINGS_MINVERSION 1
@@ -63,8 +58,7 @@ bool plug_buf = true;
63#include "jpeg/yuv2rgb.h" 58#include "jpeg/yuv2rgb.h"
64#endif 59#endif
65 60
66/* jpeg use this */ 61static struct imgview_settings settings =
67struct imgview_settings settings =
68{ 62{
69#ifdef HAVE_LCD_COLOR 63#ifdef HAVE_LCD_COLOR
70 COLOURMODE_COLOUR, 64 COLOURMODE_COLOUR,
@@ -86,17 +80,39 @@ static struct configdata config[] =
86 { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL }, 80 { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL },
87}; 81};
88 82
83static void cb_progress(int current, int total);
84
85static struct imgdec_api iv_api = {
86 .settings = &settings,
87 .slideshow_enabled = false,
88 .running_slideshow = false,
89#ifdef DISK_SPINDOWN
90 .immediate_ata_off = false,
91#endif
92#ifdef USE_PLUG_BUF
93 .plug_buf = true,
94#endif
95
96 .cb_progress = cb_progress,
97
98#ifdef USEGSLIB
99 .gray_bitmap_part = myxlcd_ub_(gray_bitmap_part),
100#endif
101};
102
89/**************** begin Application ********************/ 103/**************** begin Application ********************/
90 104
91 105
92/************************* Globals ***************************/ 106/************************* Globals ***************************/
93 107
94#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 108#ifdef HAVE_LCD_COLOR
95static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when 109static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
96 DITHER_DIFFUSION is set */ 110 DITHER_DIFFUSION is set */
97#endif 111#endif
98 112
99/* my memory pool (from the mp3 buffer) */ 113/* buffer to load image decoder */
114static unsigned char* decoder_buf;
115static size_t decoder_buf_size;
100/* the remaining free part of the buffer for loaded+resized images */ 116/* the remaining free part of the buffer for loaded+resized images */
101static unsigned char* buf; 117static unsigned char* buf;
102static size_t buf_size; 118static size_t buf_size;
@@ -106,11 +122,14 @@ static struct image_info image_info;
106 122
107/* the current full file name */ 123/* the current full file name */
108static char np_file[MAX_PATH]; 124static char np_file[MAX_PATH];
109static int curfile = 0, direction = DIR_NEXT, entries = 0; 125static int curfile = -1, direction = DIR_NEXT, entries = 0;
110 126
111/* list of the supported image files */ 127/* list of the supported image files */
112static char **file_pt; 128static char **file_pt;
113 129
130static const struct image_decoder *imgdec = NULL;
131static enum image_type image_type = IMAGE_UNKNOWN;
132
114/************************* Implementation ***************************/ 133/************************* Implementation ***************************/
115 134
116/* Read directory contents for scrolling. */ 135/* Read directory contents for scrolling. */
@@ -130,7 +149,7 @@ static void get_pic_list(void)
130 for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++) 149 for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++)
131 { 150 {
132 if (!(dircache[i].attr & ATTR_DIRECTORY) 151 if (!(dircache[i].attr & ATTR_DIRECTORY)
133 && img_ext(rb->strrchr(dircache[i].name,'.'))) 152 && get_image_type(dircache[i].name) != IMAGE_UNKNOWN)
134 { 153 {
135 file_pt[entries] = dircache[i].name; 154 file_pt[entries] = dircache[i].name;
136 /* Set Selected File. */ 155 /* Set Selected File. */
@@ -187,11 +206,11 @@ static void cleanup(void *parameter)
187#endif 206#endif
188} 207}
189 208
190#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 209#ifdef HAVE_LCD_COLOR
191static bool set_option_grayscale(void) 210static bool set_option_grayscale(void)
192{ 211{
193 bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY; 212 bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY;
194 rb->set_bool("Grayscale", &gray); 213 rb->set_bool("Grayscale (Jpeg)", &gray);
195 settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR; 214 settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
196 return false; 215 return false;
197} 216}
@@ -204,14 +223,14 @@ static bool set_option_dithering(void)
204 [DITHER_DIFFUSION] = { "Diffusion", -1 }, 223 [DITHER_DIFFUSION] = { "Diffusion", -1 },
205 }; 224 };
206 225
207 rb->set_option("Dithering", &settings.jpeg_dither_mode, INT, 226 rb->set_option("Dithering (Jpeg)", &settings.jpeg_dither_mode, INT,
208 dithering, DITHER_NUM_MODES, NULL); 227 dithering, DITHER_NUM_MODES, NULL);
209 return false; 228 return false;
210} 229}
211 230
212MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale", 231MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale (Jpeg)",
213 set_option_grayscale, NULL, NULL, Icon_NOICON); 232 set_option_grayscale, NULL, NULL, Icon_NOICON);
214MENUITEM_FUNCTION(dithering_item, 0, "Dithering", 233MENUITEM_FUNCTION(dithering_item, 0, "Dithering (Jpeg)",
215 set_option_dithering, NULL, NULL, Icon_NOICON); 234 set_option_dithering, NULL, NULL, Icon_NOICON);
216MAKE_MENU(display_menu, "Display Options", NULL, Icon_NOICON, 235MAKE_MENU(display_menu, "Display Options", NULL, Icon_NOICON,
217 &grayscale_item, &dithering_item); 236 &grayscale_item, &dithering_item);
@@ -220,7 +239,7 @@ static void display_options(void)
220{ 239{
221 rb->do_menu(&display_menu, NULL, NULL, false); 240 rb->do_menu(&display_menu, NULL, NULL, false);
222} 241}
223#endif /* defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) */ 242#endif /* HAVE_LCD_COLOR */
224 243
225static int show_menu(void) /* return 1 to quit */ 244static int show_menu(void) /* return 1 to quit */
226{ 245{
@@ -234,19 +253,19 @@ static int show_menu(void) /* return 1 to quit */
234#ifdef USE_PLUG_BUF 253#ifdef USE_PLUG_BUF
235 MIID_SHOW_PLAYBACK_MENU, 254 MIID_SHOW_PLAYBACK_MENU,
236#endif 255#endif
237#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 256#ifdef HAVE_LCD_COLOR
238 MIID_DISPLAY_OPTIONS, 257 MIID_DISPLAY_OPTIONS,
239#endif 258#endif
240 MIID_QUIT, 259 MIID_QUIT,
241 }; 260 };
242 261
243 MENUITEM_STRINGLIST(menu, MENU_TITLE, NULL, 262 MENUITEM_STRINGLIST(menu, "Image Viewer Menu", NULL,
244 "Return", "Toggle Slideshow Mode", 263 "Return", "Toggle Slideshow Mode",
245 "Change Slideshow Time", 264 "Change Slideshow Time",
246#ifdef USE_PLUG_BUF 265#ifdef USE_PLUG_BUF
247 "Show Playback Menu", 266 "Show Playback Menu",
248#endif 267#endif
249#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 268#ifdef HAVE_LCD_COLOR
250 "Display Options", 269 "Display Options",
251#endif 270#endif
252 "Quit"); 271 "Quit");
@@ -263,7 +282,7 @@ static int show_menu(void) /* return 1 to quit */
263 case MIID_RETURN: 282 case MIID_RETURN:
264 break; 283 break;
265 case MIID_TOGGLE_SS_MODE: 284 case MIID_TOGGLE_SS_MODE:
266 rb->set_option("Toggle Slideshow", &slideshow_enabled, BOOL, 285 rb->set_option("Toggle Slideshow", &iv_api.slideshow_enabled, BOOL,
267 slideshow , 2, NULL); 286 slideshow , 2, NULL);
268 break; 287 break;
269 case MIID_CHANGE_SS_MODE: 288 case MIID_CHANGE_SS_MODE:
@@ -274,7 +293,7 @@ static int show_menu(void) /* return 1 to quit */
274 293
275#ifdef USE_PLUG_BUF 294#ifdef USE_PLUG_BUF
276 case MIID_SHOW_PLAYBACK_MENU: 295 case MIID_SHOW_PLAYBACK_MENU:
277 if (plug_buf) 296 if (iv_api.plug_buf)
278 { 297 {
279 playback_control(NULL); 298 playback_control(NULL);
280 } 299 }
@@ -284,7 +303,7 @@ static int show_menu(void) /* return 1 to quit */
284 } 303 }
285 break; 304 break;
286#endif 305#endif
287#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 306#ifdef HAVE_LCD_COLOR
288 case MIID_DISPLAY_OPTIONS: 307 case MIID_DISPLAY_OPTIONS:
289 display_options(); 308 display_options();
290 break; 309 break;
@@ -296,10 +315,10 @@ static int show_menu(void) /* return 1 to quit */
296 315
297#ifdef DISK_SPINDOWN 316#ifdef DISK_SPINDOWN
298 /* change ata spindown time based on slideshow time setting */ 317 /* change ata spindown time based on slideshow time setting */
299 immediate_ata_off = false; 318 iv_api.immediate_ata_off = false;
300 rb->storage_spindown(rb->global_settings->disk_spindown); 319 rb->storage_spindown(rb->global_settings->disk_spindown);
301 320
302 if (slideshow_enabled) 321 if (iv_api.slideshow_enabled)
303 { 322 {
304 if(settings.ss_timeout < 10) 323 if(settings.ss_timeout < 10)
305 { 324 {
@@ -309,7 +328,7 @@ static int show_menu(void) /* return 1 to quit */
309 else if (!rb->mp3_is_playing()) 328 else if (!rb->mp3_is_playing())
310 { 329 {
311 /* slideshow times > 10s and not playing: ata_off after load */ 330 /* slideshow times > 10s and not playing: ata_off after load */
312 immediate_ata_off = true; 331 iv_api.immediate_ata_off = true;
313 } 332 }
314 } 333 }
315#endif 334#endif
@@ -344,7 +363,7 @@ static int ask_and_get_audio_buffer(const char *filename)
344 switch(button) 363 switch(button)
345 { 364 {
346 case IMGVIEW_ZOOM_IN: 365 case IMGVIEW_ZOOM_IN:
347 plug_buf = false; 366 iv_api.plug_buf = false;
348 buf = rb->plugin_get_audio_buffer(&buf_size); 367 buf = rb->plugin_get_audio_buffer(&buf_size);
349 /*try again this file, now using the audio buffer */ 368 /*try again this file, now using the audio buffer */
350 return PLUGIN_OTHER; 369 return PLUGIN_OTHER;
@@ -382,15 +401,15 @@ static int ask_and_get_audio_buffer(const char *filename)
382#endif /* USE_PLUG_BUF */ 401#endif /* USE_PLUG_BUF */
383 402
384/* callback updating a progress meter while image decoding */ 403/* callback updating a progress meter while image decoding */
385void cb_progress(int current, int total) 404static void cb_progress(int current, int total)
386{ 405{
387 rb->yield(); /* be nice to the other threads */ 406 rb->yield(); /* be nice to the other threads */
388#ifndef USEGSLIB 407#ifndef USEGSLIB
389 /* in slideshow mode, keep gui interference to a minimum */ 408 /* in slideshow mode, keep gui interference to a minimum */
390 const int size = (!running_slideshow ? 8 : 4); 409 const int size = (!iv_api.running_slideshow ? 8 : 4);
391#else 410#else
392 const int size = 8; 411 const int size = 8;
393 if(!running_slideshow) 412 if(!iv_api.running_slideshow)
394#endif 413#endif
395 { 414 {
396 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], 415 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
@@ -414,7 +433,8 @@ static void pan_view_right(struct image_info *info)
414 { 433 {
415 mylcd_ub_scroll_left(move); /* scroll left */ 434 mylcd_ub_scroll_left(move); /* scroll left */
416 info->x += move; 435 info->x += move;
417 draw_image_rect(info, LCD_WIDTH - move, 0, move, info->height-info->y); 436 imgdec->draw_image_rect(info, LCD_WIDTH - move, 0,
437 move, info->height-info->y);
418 mylcd_ub_update(); 438 mylcd_ub_update();
419 } 439 }
420} 440}
@@ -430,7 +450,7 @@ static void pan_view_left(struct image_info *info)
430 { 450 {
431 mylcd_ub_scroll_right(move); /* scroll right */ 451 mylcd_ub_scroll_right(move); /* scroll right */
432 info->x -= move; 452 info->x -= move;
433 draw_image_rect(info, 0, 0, move, info->height-info->y); 453 imgdec->draw_image_rect(info, 0, 0, move, info->height-info->y);
434 mylcd_ub_update(); 454 mylcd_ub_update();
435 } 455 }
436} 456}
@@ -446,15 +466,16 @@ static void pan_view_up(struct image_info *info)
446 { 466 {
447 mylcd_ub_scroll_down(move); /* scroll down */ 467 mylcd_ub_scroll_down(move); /* scroll down */
448 info->y -= move; 468 info->y -= move;
449#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 469#ifdef HAVE_LCD_COLOR
450 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 470 if (image_type == IMAGE_JPEG
471 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
451 { 472 {
452 /* Draw over the band at the top of the last update 473 /* Draw over the band at the top of the last update
453 caused by lack of error history on line zero. */ 474 caused by lack of error history on line zero. */
454 move = MIN(move + 1, info->y + info->height); 475 move = MIN(move + 1, info->y + info->height);
455 } 476 }
456#endif 477#endif
457 draw_image_rect(info, 0, 0, info->width-info->x, move); 478 imgdec->draw_image_rect(info, 0, 0, info->width-info->x, move);
458 mylcd_ub_update(); 479 mylcd_ub_update();
459 } 480 }
460} 481}
@@ -470,8 +491,9 @@ static void pan_view_down(struct image_info *info)
470 { 491 {
471 mylcd_ub_scroll_up(move); /* scroll up */ 492 mylcd_ub_scroll_up(move); /* scroll up */
472 info->y += move; 493 info->y += move;
473#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 494#ifdef HAVE_LCD_COLOR
474 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 495 if (image_type == IMAGE_JPEG
496 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
475 { 497 {
476 /* Save the line that was on the last line of the display 498 /* Save the line that was on the last line of the display
477 and draw one extra line above then recover the line with 499 and draw one extra line above then recover the line with
@@ -484,10 +506,12 @@ static void pan_view_down(struct image_info *info)
484 } 506 }
485#endif 507#endif
486 508
487 draw_image_rect(info, 0, LCD_HEIGHT - move, info->width-info->x, move); 509 imgdec->draw_image_rect(info, 0, LCD_HEIGHT - move,
510 info->width-info->x, move);
488 511
489#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 512#ifdef HAVE_LCD_COLOR
490 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 513 if (image_type == IMAGE_JPEG
514 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
491 { 515 {
492 /* Cover the first row drawn with previous image data. */ 516 /* Cover the first row drawn with previous image data. */
493 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 517 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
@@ -507,12 +531,12 @@ static int scroll_bmp(struct image_info *info)
507 531
508 while (true) 532 while (true)
509 { 533 {
510 if (slideshow_enabled) 534 if (iv_api.slideshow_enabled)
511 button = rb->button_get_w_tmo(settings.ss_timeout * HZ); 535 button = rb->button_get_w_tmo(settings.ss_timeout * HZ);
512 else 536 else
513 button = rb->button_get(true); 537 button = rb->button_get(true);
514 538
515 running_slideshow = false; 539 iv_api.running_slideshow = false;
516 540
517 switch(button) 541 switch(button)
518 { 542 {
@@ -543,16 +567,16 @@ static int scroll_bmp(struct image_info *info)
543 break; 567 break;
544 568
545 case BUTTON_NONE: 569 case BUTTON_NONE:
546 if (slideshow_enabled && entries > 1) 570 if (iv_api.slideshow_enabled && entries > 1)
547 { 571 {
548 running_slideshow = true; 572 iv_api.running_slideshow = true;
549 return change_filename(DIR_NEXT); 573 return change_filename(DIR_NEXT);
550 } 574 }
551 break; 575 break;
552 576
553#ifdef IMGVIEW_SLIDE_SHOW 577#ifdef IMGVIEW_SLIDE_SHOW
554 case IMGVIEW_SLIDE_SHOW: 578 case IMGVIEW_SLIDE_SHOW:
555 slideshow_enabled = !slideshow_enabled; 579 iv_api.slideshow_enabled = !iv_api.slideshow_enabled;
556 break; 580 break;
557#endif 581#endif
558 582
@@ -605,7 +629,7 @@ static int scroll_bmp(struct image_info *info)
605#ifdef USEGSLIB 629#ifdef USEGSLIB
606 grey_show(true); /* switch on greyscale overlay */ 630 grey_show(true); /* switch on greyscale overlay */
607#else 631#else
608 draw_image_rect(info, 0, 0, 632 imgdec->draw_image_rect(info, 0, 0,
609 info->width-info->x, info->height-info->y); 633 info->width-info->x, info->height-info->y);
610 mylcd_ub_update(); 634 mylcd_ub_update();
611#endif 635#endif
@@ -637,10 +661,10 @@ static int min_downscale(int bufsize)
637{ 661{
638 int downscale = 8; 662 int downscale = 8;
639 663
640 if (img_mem(8) > bufsize) 664 if (imgdec->img_mem(8) > bufsize)
641 return 0; /* error, too large, even 1:8 doesn't fit */ 665 return 0; /* error, too large, even 1:8 doesn't fit */
642 666
643 while (downscale > 1 && img_mem(downscale/2) <= bufsize) 667 while (downscale > 1 && imgdec->img_mem(downscale/2) <= bufsize)
644 downscale /= 2; 668 downscale /= 2;
645 669
646 return downscale; 670 return downscale;
@@ -697,18 +721,39 @@ static int load_and_show(char* filename, struct image_info *info)
697 721
698 rb->lcd_clear_display(); 722 rb->lcd_clear_display();
699 723
724 status = get_image_type(filename);
725 if (image_type != status) /* type of image is changed, load decoder. */
726 {
727 struct loader_info loader_info = {
728 status, &iv_api, decoder_buf, decoder_buf_size,
729 };
730 image_type = status;
731 imgdec = load_decoder(&loader_info);
732 if (imgdec == NULL)
733 {
734 /* something is wrong */
735 return PLUGIN_ERROR;
736 }
737#ifdef USE_PLUG_BUF
738 if(iv_api.plug_buf)
739 {
740 buf = loader_info.buffer;
741 buf_size = loader_info.size;
742 }
743#endif
744 }
700 rb->memset(info, 0, sizeof(*info)); 745 rb->memset(info, 0, sizeof(*info));
701 remaining = buf_size; 746 remaining = buf_size;
702 747
703 if (rb->button_get(false) == IMGVIEW_MENU) 748 if (rb->button_get(false) == IMGVIEW_MENU)
704 status = PLUGIN_ABORT; 749 status = PLUGIN_ABORT;
705 else 750 else
706 status = load_image(filename, info, buf, &remaining); 751 status = imgdec->load_image(filename, info, buf, &remaining);
707 752
708 if (status == PLUGIN_OUTOFMEM) 753 if (status == PLUGIN_OUTOFMEM)
709 { 754 {
710#ifdef USE_PLUG_BUF 755#ifdef USE_PLUG_BUF
711 if(plug_buf) 756 if(iv_api.plug_buf)
712 { 757 {
713 return ask_and_get_audio_buffer(filename); 758 return ask_and_get_audio_buffer(filename);
714 } 759 }
@@ -734,13 +779,14 @@ static int load_and_show(char* filename, struct image_info *info)
734 ds_min = min_downscale(remaining); /* check memory constraint */ 779 ds_min = min_downscale(remaining); /* check memory constraint */
735 if (ds_min == 0) 780 if (ds_min == 0)
736 { 781 {
737#if UNSCALED_IS_AVAILABLE 782 if (imgdec->unscaled_avail)
738 /* Can not resize the image but original one is available, so use it. */ 783 {
739 ds_min = ds_max = 1; 784 /* Can not resize the image but original one is available, so use it. */
740#else 785 ds_min = ds_max = 1;
741 /* not enough memory to decode image. */ 786 }
787 else
742#ifdef USE_PLUG_BUF 788#ifdef USE_PLUG_BUF
743 if(plug_buf) 789 if (iv_api.plug_buf)
744 { 790 {
745 return ask_and_get_audio_buffer(filename); 791 return ask_and_get_audio_buffer(filename);
746 } 792 }
@@ -751,7 +797,6 @@ static int load_and_show(char* filename, struct image_info *info)
751 file_pt[curfile] = NULL; 797 file_pt[curfile] = NULL;
752 return change_filename(direction); 798 return change_filename(direction);
753 } 799 }
754#endif
755 } 800 }
756 else if (ds_max < ds_min) 801 else if (ds_max < ds_min)
757 ds_max = ds_min; 802 ds_max = ds_min;
@@ -762,7 +807,7 @@ static int load_and_show(char* filename, struct image_info *info)
762 807
763 do /* loop the image prepare and decoding when zoomed */ 808 do /* loop the image prepare and decoding when zoomed */
764 { 809 {
765 status = get_image(info, ds); /* decode or fetch from cache */ 810 status = imgdec->get_image(info, ds); /* decode or fetch from cache */
766 if (status == PLUGIN_ERROR) 811 if (status == PLUGIN_ERROR)
767 { 812 {
768 file_pt[curfile] = NULL; 813 file_pt[curfile] = NULL;
@@ -771,14 +816,14 @@ static int load_and_show(char* filename, struct image_info *info)
771 816
772 set_view(info, cx, cy); 817 set_view(info, cx, cy);
773 818
774 if(!running_slideshow) 819 if(!iv_api.running_slideshow)
775 { 820 {
776 rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height); 821 rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height);
777 rb->lcd_update(); 822 rb->lcd_update();
778 } 823 }
779 824
780 mylcd_ub_clear_display(); 825 mylcd_ub_clear_display();
781 draw_image_rect(info, 0, 0, 826 imgdec->draw_image_rect(info, 0, 0,
782 info->width-info->x, info->height-info->y); 827 info->width-info->x, info->height-info->y);
783 mylcd_ub_update(); 828 mylcd_ub_update();
784 829
@@ -794,18 +839,10 @@ static int load_and_show(char* filename, struct image_info *info)
794 status = scroll_bmp(info); 839 status = scroll_bmp(info);
795 if (status == ZOOM_IN) 840 if (status == ZOOM_IN)
796 { 841 {
797#if UNSCALED_IS_AVAILABLE 842 if (ds > ds_min || (imgdec->unscaled_avail && ds > 1))
798 if (ds > 1)
799#else
800 if (ds > ds_min)
801#endif
802 { 843 {
803#if UNSCALED_IS_AVAILABLE
804 /* if 1/1 is always available, jump ds from ds_min to 1. */ 844 /* if 1/1 is always available, jump ds from ds_min to 1. */
805 int zoom = (ds == ds_min)? ds_min: 2; 845 int zoom = (ds == ds_min)? ds_min: 2;
806#else
807 const int zoom = 2;
808#endif
809 ds /= zoom; /* reduce downscaling to zoom in */ 846 ds /= zoom; /* reduce downscaling to zoom in */
810 get_view(info, &cx, &cy); 847 get_view(info, &cx, &cy);
811 cx *= zoom; /* prepare the position in the new image */ 848 cx *= zoom; /* prepare the position in the new image */
@@ -819,12 +856,8 @@ static int load_and_show(char* filename, struct image_info *info)
819 { 856 {
820 if (ds < ds_max) 857 if (ds < ds_max)
821 { 858 {
822#if UNSCALED_IS_AVAILABLE
823 /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */ 859 /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */
824 int zoom = (ds < ds_min)? ds_min: 2; 860 int zoom = (ds < ds_min)? ds_min: 2;
825#else
826 const int zoom = 2;
827#endif
828 ds *= zoom; /* increase downscaling to zoom out */ 861 ds *= zoom; /* increase downscaling to zoom out */
829 get_view(info, &cx, &cy); 862 get_view(info, &cx, &cy);
830 cx /= zoom; /* prepare the position in the new image */ 863 cx /= zoom; /* prepare the position in the new image */
@@ -859,25 +892,24 @@ enum plugin_status plugin_start(const void* parameter)
859 892
860 if(!parameter) return PLUGIN_ERROR; 893 if(!parameter) return PLUGIN_ERROR;
861 894
895 rb->strcpy(np_file, parameter);
896 if (get_image_type(np_file) == IMAGE_UNKNOWN)
897 {
898 rb->splash(HZ*2, "Unsupported file");
899 return PLUGIN_ERROR;
900 }
901
862#ifdef USE_PLUG_BUF 902#ifdef USE_PLUG_BUF
863 buf = rb->plugin_get_buffer(&buf_size); 903 buf = rb->plugin_get_buffer(&buf_size);
864#else 904#else
905 decoder_buf = rb->plugin_get_buffer(&decoder_buf_size);
865 buf = rb->plugin_get_audio_buffer(&buf_size); 906 buf = rb->plugin_get_audio_buffer(&buf_size);
866#endif 907#endif
867 908
868 rb->strcpy(np_file, parameter);
869 get_pic_list(); 909 get_pic_list();
870 910
871 if(!entries) return PLUGIN_ERROR; 911 if(!entries) return PLUGIN_ERROR;
872 912
873#ifdef USE_PLUG_BUF
874 if(!rb->audio_status())
875 {
876 plug_buf = false;
877 buf = rb->plugin_get_audio_buffer(&buf_size);
878 }
879#endif
880
881#ifdef USEGSLIB 913#ifdef USEGSLIB
882 if (!grey_init(buf, buf_size, GREY_ON_COP, 914 if (!grey_init(buf, buf_size, GREY_ON_COP,
883 LCD_WIDTH, LCD_HEIGHT, &greysize)) 915 LCD_WIDTH, LCD_HEIGHT, &greysize))
@@ -889,6 +921,16 @@ enum plugin_status plugin_start(const void* parameter)
889 buf_size -= greysize; 921 buf_size -= greysize;
890#endif 922#endif
891 923
924#ifdef USE_PLUG_BUF
925 decoder_buf = buf;
926 decoder_buf_size = buf_size;
927 if(!rb->audio_status())
928 {
929 iv_api.plug_buf = false;
930 buf = rb->plugin_get_audio_buffer(&buf_size);
931 }
932#endif
933
892 /* should be ok to just load settings since the plugin itself has 934 /* should be ok to just load settings since the plugin itself has
893 just been loaded from disk and the drive should be spinning */ 935 just been loaded from disk and the drive should be spinning */
894 configfile_load(IMGVIEW_CONFIGFILE, config, 936 configfile_load(IMGVIEW_CONFIGFILE, config,
@@ -908,6 +950,7 @@ enum plugin_status plugin_start(const void* parameter)
908 { 950 {
909 condition = load_and_show(np_file, &image_info); 951 condition = load_and_show(np_file, &image_info);
910 } while (condition >= PLUGIN_OTHER); 952 } while (condition >= PLUGIN_OTHER);
953 release_decoder();
911 954
912 if (rb->memcmp(&settings, &old_settings, sizeof (settings))) 955 if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
913 { 956 {
diff --git a/apps/plugins/imageviewer/imageviewer.h b/apps/plugins/imageviewer/imageviewer.h
index da2bbfe45c..8e838def08 100644
--- a/apps/plugins/imageviewer/imageviewer.h
+++ b/apps/plugins/imageviewer/imageviewer.h
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * user intereface of image viewers (jpeg, png, etc.) 10 * user intereface of image viewer.
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -19,8 +19,8 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#ifndef _IMGVIEW_IMGVIEW_H 22#ifndef _IMAGE_VIEWER_H
23#define _IMGVIEW_IMGVIEW_H 23#define _IMAGE_VIEWER_H
24 24
25#include "plugin.h" 25#include "plugin.h"
26 26
@@ -384,6 +384,13 @@
384 384
385#include <lib/mylcd.h> 385#include <lib/mylcd.h>
386 386
387#if defined(USEGSLIB) && defined(IMGDEC)
388#undef mylcd_ub_
389#undef myxlcd_ub_
390#define mylcd_ub_(fn) iv->fn
391#define myxlcd_ub_(fn) iv->fn
392#endif
393
387/* Min memory allowing us to use the plugin buffer 394/* Min memory allowing us to use the plugin buffer
388 * and thus not stopping the music 395 * and thus not stopping the music
389 * *Very* rough estimation: 396 * *Very* rough estimation:
@@ -413,7 +420,6 @@ enum {
413/* Settings. jpeg needs these */ 420/* Settings. jpeg needs these */
414struct imgview_settings 421struct imgview_settings
415{ 422{
416 /* include all settings for varias decoders as using same setting file. */
417#ifdef HAVE_LCD_COLOR 423#ifdef HAVE_LCD_COLOR
418 int jpeg_colour_mode; 424 int jpeg_colour_mode;
419 int jpeg_dither_mode; 425 int jpeg_dither_mode;
@@ -421,7 +427,7 @@ struct imgview_settings
421 int ss_timeout; 427 int ss_timeout;
422}; 428};
423 429
424/* structure passed to decoder. */ 430/* structure passed to image decoder. */
425struct image_info { 431struct image_info {
426 int x_size, y_size; /* set size of loaded image in load_image(). */ 432 int x_size, y_size; /* set size of loaded image in load_image(). */
427 int width, height; /* set size of resized image in get_image(). */ 433 int width, height; /* set size of resized image in get_image(). */
@@ -429,34 +435,78 @@ struct image_info {
429 void *data; /* use freely in decoder. not touched in ui. */ 435 void *data; /* use freely in decoder. not touched in ui. */
430}; 436};
431 437
432/* callback updating a progress meter while image decoding */ 438struct imgdec_api {
433extern void cb_progress(int current, int total); 439 const struct imgview_settings *settings;
434 440 bool slideshow_enabled; /* run slideshow */
435extern struct imgview_settings settings; 441 bool running_slideshow; /* loading image because of slideshw */
436extern bool slideshow_enabled;
437extern bool running_slideshow;
438#ifdef DISK_SPINDOWN 442#ifdef DISK_SPINDOWN
439extern bool immediate_ata_off; 443 bool immediate_ata_off; /* power down disk after loading */
440#endif 444#endif
441#ifdef USE_PLUG_BUF 445#ifdef USE_PLUG_BUF
442extern bool plug_buf; 446 bool plug_buf; /* are we using the plugin buffer or the audio buffer? */
443#endif 447#endif
444 448
449 /* callback updating a progress meter while image decoding */
450 void (*cb_progress)(int current, int total);
451
452#ifdef USEGSLIB
453 void (*gray_bitmap_part)(const unsigned char *src, int src_x, int src_y,
454 int stride, int x, int y, int width, int height);
455#endif
456};
457
445/* functions need to be implemented in each image decoders. */ 458/* functions need to be implemented in each image decoders. */
446/* return true if ext is supported by the decoder. */ 459struct image_decoder {
447extern bool img_ext(const char *ext); 460 /* if unscaled image can be always displayed when there isn't enough memory
448/* return needed size of buffer to store downscaled image by ds */ 461 * for resized image. e.g. when using native format to store image. */
449extern int img_mem(int ds); 462 const bool unscaled_avail;
450/* load image from filename. set width and height of info properly. also, set 463
451 * buf_size to remaining size of buf after load image. it is used to caluclate 464 /* return needed size of buffer to store downscaled image by ds */
452 * min downscale. */ 465 int (*img_mem)(int ds);
453extern int load_image(char *filename, struct image_info *info, 466 /* load image from filename. set width and height of info properly. also, set
467 * buf_size to remaining size of buf after load image. it is used to caluclate
468 * min downscale. */
469 int (*load_image)(char *filename, struct image_info *info,
454 unsigned char *buf, ssize_t *buf_size); 470 unsigned char *buf, ssize_t *buf_size);
455/* downscale loaded image by ds. note that buf to store reszied image is not 471 /* downscale loaded image by ds. note that buf to store reszied image is not
456 * provided. return PLUGIN_ERROR for error. ui will skip to next image. */ 472 * provided. return PLUGIN_ERROR for error. ui will skip to next image. */
457extern int get_image(struct image_info *info, int ds); 473 int (*get_image)(struct image_info *info, int ds);
458/* draw part of image */ 474 /* draw part of image */
459extern void draw_image_rect(struct image_info *info, 475 void (*draw_image_rect)(struct image_info *info,
460 int x, int y, int width, int height); 476 int x, int y, int width, int height);
477};
478
479#define IMGDEC_API_VERSION (PLUGIN_API_VERSION << 4 | 0)
480
481/* image decoder header */
482struct imgdec_header {
483 struct lc_header lc_hdr; /* must be the first */
484 const struct image_decoder *decoder;
485 const struct plugin_api **api;
486 const struct imgdec_api **img_api;
487};
488
489#ifdef IMGDEC
490extern const struct imgdec_api *iv;
491extern const struct image_decoder image_decoder;
492
493#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
494#define IMGDEC_HEADER \
495 const struct plugin_api *rb DATA_ATTR; \
496 const struct imgdec_api *iv DATA_ATTR; \
497 const struct imgdec_header __header \
498 __attribute__ ((section (".header")))= { \
499 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \
500 plugin_start_addr, plugin_end_addr }, &image_decoder, &rb, &iv };
501#else /* PLATFORM_HOSTED */
502#define IMGDEC_HEADER \
503 const struct plugin_api *rb DATA_ATTR; \
504 const struct imgdec_api *iv DATA_ATTR; \
505 const struct imgdec_header __header \
506 __attribute__((visibility("default"))) = { \
507 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \
508 NULL, NULL }, &image_decoder, &rb, &iv };
509#endif /* CONFIG_PLATFORM */
510#endif
461 511
462#endif /* _IMGVIEW_IMGVIEW_H */ 512#endif /* _IMAGE_VIEWER_H */
diff --git a/apps/plugins/imageviewer/imageviewer.make b/apps/plugins/imageviewer/imageviewer.make
index 76af8d24e5..d06bbfd571 100644
--- a/apps/plugins/imageviewer/imageviewer.make
+++ b/apps/plugins/imageviewer/imageviewer.make
@@ -10,7 +10,50 @@
10IMGVSRCDIR := $(APPSDIR)/plugins/imageviewer 10IMGVSRCDIR := $(APPSDIR)/plugins/imageviewer
11IMGVBUILDDIR := $(BUILDDIR)/apps/plugins/imageviewer 11IMGVBUILDDIR := $(BUILDDIR)/apps/plugins/imageviewer
12 12
13# include actual viewer's make file 13ROCKS += $(IMGVBUILDDIR)/imageviewer.rock
14
15IMGV_SRC := $(call preprocess, $(IMGVSRCDIR)/SOURCES)
16IMGV_OBJ := $(call c2obj, $(IMGV_SRC))
17
18# add source files to OTHER_SRC to get automatic dependencies
19OTHER_SRC += $(IMGV_SRC)
20
21$(IMGVBUILDDIR)/imageviewer.rock: $(IMGV_OBJ)
22
23IMGDECFLAGS = $(PLUGINFLAGS) -DIMGDEC
24
25# include decoder's make from each subdir
14IMGVSUBDIRS := $(call preprocess, $(IMGVSRCDIR)/SUBDIRS) 26IMGVSUBDIRS := $(call preprocess, $(IMGVSRCDIR)/SUBDIRS)
15$(foreach dir,$(IMGVSUBDIRS),$(eval include $(dir)/$(notdir $(dir)).make)) 27$(foreach dir,$(IMGVSUBDIRS),$(eval include $(dir)/$(notdir $(dir)).make))
16 28
29IMGDECLDFLAGS = -T$(PLUGINLINK_LDS) -Wl,--gc-sections -Wl,-Map,$(IMGVBUILDDIR)/$*.refmap
30
31ifndef APP_TYPE
32 IMGDEC_OUTLDS = $(IMGVBUILDDIR)/%.link
33 IMGDEC_OVLFLAGS = -T$(IMGVBUILDDIR)/$*.link -Wl,--gc-sections -Wl,-Map,$(IMGVBUILDDIR)/$*.map
34else
35 IMGDEC_OVLFLAGS = $(PLUGINLDFLAGS)
36endif
37
38$(IMGVBUILDDIR)/%.ovl: $(IMGDEC_OUTLDS)
39 $(call PRINTS,LD $(@F))$(CC) $(IMGDECFLAGS) -o $(IMGVBUILDDIR)/$*.elf \
40 $(filter-out $(PLUGIN_CRT0),$(filter %.o, $^)) \
41 $(filter %.a, $+) \
42 -lgcc $(IMGDEC_OVLFLAGS)
43ifdef APP_TYPE
44 $(SILENT)cp $(IMGVBUILDDIR)/$*.elf $@
45else
46 $(SILENT)$(OC) -O binary $(IMGVBUILDDIR)/$*.elf $@
47endif
48
49# rule to create reference map for image decoder
50$(IMGVBUILDDIR)/%.refmap: $(APPSDIR)/plugin.h $(IMGVSRCDIR)/imageviewer.h $(PLUGINLINK_LDS) $(PLUGINLIB) $(PLUGINBITMAPLIB)
51 $(call PRINTS,LD $(@F))$(CC) $(IMGDECFLAGS) -o /dev/null \
52 $(filter %.o, $^) \
53 $(filter %.a, $+) \
54 -lgcc $(IMGDECLDFLAGS)
55
56$(IMGVBUILDDIR)/%.link: $(PLUGIN_LDS) $(IMGVBUILDDIR)/%.refmap
57 $(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DIMGVDECODER_OFFSET=$(shell \
58 $(TOOLSDIR)/ovl_offset.pl $(IMGVBUILDDIR)/$*.refmap))
59
diff --git a/apps/plugins/imageviewer/jpeg/SOURCES b/apps/plugins/imageviewer/jpeg/SOURCES
index 8e80722a5a..c3524001e2 100644
--- a/apps/plugins/imageviewer/jpeg/SOURCES
+++ b/apps/plugins/imageviewer/jpeg/SOURCES
@@ -1,4 +1,3 @@
1jpeg_ui.c
2jpeg.c 1jpeg.c
3jpeg_decoder.c 2jpeg_decoder.c
4#ifdef HAVE_LCD_COLOR 3#ifdef HAVE_LCD_COLOR
diff --git a/apps/plugins/imageviewer/jpeg/jpeg.c b/apps/plugins/imageviewer/jpeg/jpeg.c
index 5f69cc7f51..511a7054e1 100644
--- a/apps/plugins/imageviewer/jpeg/jpeg.c
+++ b/apps/plugins/imageviewer/jpeg/jpeg.c
@@ -69,20 +69,8 @@ static struct jpeg jpg; /* too large for stack */
69 69
70/************************* Implementation ***************************/ 70/************************* Implementation ***************************/
71 71
72bool img_ext(const char *ext) 72static void draw_image_rect(struct image_info *info,
73{ 73 int x, int y, int width, int height)
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{ 74{
87 struct t_disp* pdisp = (struct t_disp*)info->data; 75 struct t_disp* pdisp = (struct t_disp*)info->data;
88#ifdef HAVE_LCD_COLOR 76#ifdef HAVE_LCD_COLOR
@@ -92,7 +80,7 @@ void draw_image_rect(struct image_info *info,
92 x + MAX(0, (LCD_WIDTH - info->width) / 2), 80 x + MAX(0, (LCD_WIDTH - info->width) / 2),
93 y + MAX(0, (LCD_HEIGHT - info->height) / 2), 81 y + MAX(0, (LCD_HEIGHT - info->height) / 2),
94 width, height, 82 width, height,
95 settings.jpeg_colour_mode, settings.jpeg_dither_mode); 83 iv->settings->jpeg_colour_mode, iv->settings->jpeg_dither_mode);
96#else 84#else
97 mylcd_ub_gray_bitmap_part( 85 mylcd_ub_gray_bitmap_part(
98 pdisp->bitmap[0], info->x + x, info->y + y, pdisp->stride, 86 pdisp->bitmap[0], info->x + x, info->y + y, pdisp->stride,
@@ -102,7 +90,7 @@ void draw_image_rect(struct image_info *info,
102#endif 90#endif
103} 91}
104 92
105int img_mem(int ds) 93static int img_mem(int ds)
106{ 94{
107 int size; 95 int size;
108 struct jpeg *p_jpg = &jpg; 96 struct jpeg *p_jpg = &jpg;
@@ -121,8 +109,8 @@ int img_mem(int ds)
121 return size; 109 return size;
122} 110}
123 111
124int load_image(char *filename, struct image_info *info, 112static int load_image(char *filename, struct image_info *info,
125 unsigned char *buf, ssize_t *buf_size) 113 unsigned char *buf, ssize_t *buf_size)
126{ 114{
127 int fd; 115 int fd;
128 int filesize; 116 int filesize;
@@ -154,7 +142,7 @@ int load_image(char *filename, struct image_info *info,
154 return PLUGIN_OUTOFMEM; 142 return PLUGIN_OUTOFMEM;
155 } 143 }
156 144
157 if(!running_slideshow) 145 if(!iv->running_slideshow)
158 { 146 {
159 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); 147 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1);
160 rb->lcd_putsf(0, 1, "loading %d bytes", filesize); 148 rb->lcd_putsf(0, 1, "loading %d bytes", filesize);
@@ -164,13 +152,13 @@ int load_image(char *filename, struct image_info *info,
164 rb->read(fd, buf_jpeg, filesize); 152 rb->read(fd, buf_jpeg, filesize);
165 rb->close(fd); 153 rb->close(fd);
166 154
167 if(!running_slideshow) 155 if(!iv->running_slideshow)
168 { 156 {
169 rb->lcd_puts(0, 2, "decoding markers"); 157 rb->lcd_puts(0, 2, "decoding markers");
170 rb->lcd_update(); 158 rb->lcd_update();
171 } 159 }
172#ifdef DISK_SPINDOWN 160#ifdef DISK_SPINDOWN
173 else if(immediate_ata_off) 161 else if(iv->immediate_ata_off)
174 { 162 {
175 /* running slideshow and time is long enough: power down disk */ 163 /* running slideshow and time is long enough: power down disk */
176 rb->storage_sleep(); 164 rb->storage_sleep();
@@ -190,7 +178,7 @@ int load_image(char *filename, struct image_info *info,
190 default_huff_tbl(p_jpg); /* use default */ 178 default_huff_tbl(p_jpg); /* use default */
191 build_lut(p_jpg); /* derive Huffman and other lookup-tables */ 179 build_lut(p_jpg); /* derive Huffman and other lookup-tables */
192 180
193 if(!running_slideshow) 181 if(!iv->running_slideshow)
194 { 182 {
195 rb->lcd_putsf(0, 2, "image %dx%d", p_jpg->x_size, p_jpg->y_size); 183 rb->lcd_putsf(0, 2, "image %dx%d", p_jpg->x_size, p_jpg->y_size);
196 rb->lcd_update(); 184 rb->lcd_update();
@@ -202,7 +190,7 @@ int load_image(char *filename, struct image_info *info,
202 return PLUGIN_OK; 190 return PLUGIN_OK;
203} 191}
204 192
205int get_image(struct image_info *info, int ds) 193static int get_image(struct image_info *info, int ds)
206{ 194{
207 int w, h; /* used to center output */ 195 int w, h; /* used to center output */
208 int size; /* decompressed image size */ 196 int size; /* decompressed image size */
@@ -262,7 +250,7 @@ int get_image(struct image_info *info, int ds)
262 buf_images += size; 250 buf_images += size;
263 buf_images_size -= size; 251 buf_images_size -= size;
264 252
265 if(!running_slideshow) 253 if(!iv->running_slideshow)
266 { 254 {
267 rb->lcd_putsf(0, 3, "decoding %d*%d", info->width, info->height); 255 rb->lcd_putsf(0, 3, "decoding %d*%d", info->width, info->height);
268 rb->lcd_update(); 256 rb->lcd_update();
@@ -275,10 +263,10 @@ int get_image(struct image_info *info, int ds)
275 time = *rb->current_tick; 263 time = *rb->current_tick;
276#ifdef HAVE_ADJUSTABLE_CPU_FREQ 264#ifdef HAVE_ADJUSTABLE_CPU_FREQ
277 rb->cpu_boost(true); 265 rb->cpu_boost(true);
278 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress); 266 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, iv->cb_progress);
279 rb->cpu_boost(false); 267 rb->cpu_boost(false);
280#else 268#else
281 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress); 269 status = jpeg_decode(p_jpg, p_disp->bitmap, ds, iv->cb_progress);
282#endif 270#endif
283 if (status) 271 if (status)
284 { 272 {
@@ -287,7 +275,7 @@ int get_image(struct image_info *info, int ds)
287 } 275 }
288 time = *rb->current_tick - time; 276 time = *rb->current_tick - time;
289 277
290 if(!running_slideshow) 278 if(!iv->running_slideshow)
291 { 279 {
292 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ); 280 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
293 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */ 281 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
@@ -297,3 +285,13 @@ int get_image(struct image_info *info, int ds)
297 285
298 return PLUGIN_OK; 286 return PLUGIN_OK;
299} 287}
288
289const struct image_decoder image_decoder = {
290 false,
291 img_mem,
292 load_image,
293 get_image,
294 draw_image_rect,
295};
296
297IMGDEC_HEADER
diff --git a/apps/plugins/imageviewer/jpeg/jpeg.make b/apps/plugins/imageviewer/jpeg/jpeg.make
index caf37fc74c..dd7addca56 100644
--- a/apps/plugins/imageviewer/jpeg/jpeg.make
+++ b/apps/plugins/imageviewer/jpeg/jpeg.make
@@ -10,12 +10,18 @@
10JPEGSRCDIR := $(IMGVSRCDIR)/jpeg 10JPEGSRCDIR := $(IMGVSRCDIR)/jpeg
11JPEGBUILDDIR := $(IMGVBUILDDIR)/jpeg 11JPEGBUILDDIR := $(IMGVBUILDDIR)/jpeg
12 12
13ROCKS += $(JPEGBUILDDIR)/jpeg.rock
14
15JPEG_SRC := $(call preprocess, $(JPEGSRCDIR)/SOURCES) 13JPEG_SRC := $(call preprocess, $(JPEGSRCDIR)/SOURCES)
16JPEG_OBJ := $(call c2obj, $(JPEG_SRC)) 14JPEG_OBJ := $(call c2obj, $(JPEG_SRC))
17 15
18# add source files to OTHER_SRC to get automatic dependencies
19OTHER_SRC += $(JPEG_SRC) 16OTHER_SRC += $(JPEG_SRC)
20 17
21$(JPEGBUILDDIR)/jpeg.rock: $(JPEG_OBJ) 18ROCKS += $(JPEGBUILDDIR)/jpeg.ovl
19
20$(JPEGBUILDDIR)/jpeg.refmap: $(JPEG_OBJ)
21$(JPEGBUILDDIR)/jpeg.link: $(PLUGIN_LDS) $(JPEGBUILDDIR)/jpeg.refmap
22$(JPEGBUILDDIR)/jpeg.ovl: $(JPEG_OBJ)
23
24# special pattern rule for compiling image decoder with extra flags
25$(JPEGBUILDDIR)/%.o: $(JPEGSRCDIR)/%.c $(JPEGSRCDIR)/jpeg.make
26 $(SILENT)mkdir -p $(dir $@)
27 $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(IMGDECFLAGS) -c $< -o $@
diff --git a/apps/plugins/imageviewer/jpeg/jpeg_ui.c b/apps/plugins/imageviewer/jpeg/jpeg_ui.c
deleted file mode 100644
index e7f57c699f..0000000000
--- a/apps/plugins/imageviewer/jpeg/jpeg_ui.c
+++ /dev/null
@@ -1,5 +0,0 @@
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/imageviewer/png/SOURCES b/apps/plugins/imageviewer/png/SOURCES
index 8c278b02b9..978150db78 100644
--- a/apps/plugins/imageviewer/png/SOURCES
+++ b/apps/plugins/imageviewer/png/SOURCES
@@ -3,4 +3,3 @@ tinflate.c
3tinfzlib.c 3tinfzlib.c
4png_decoder.c 4png_decoder.c
5png.c 5png.c
6png_ui.c
diff --git a/apps/plugins/imageviewer/png/png.c b/apps/plugins/imageviewer/png/png.c
index 956cad37d8..10404b7c30 100644
--- a/apps/plugins/imageviewer/png/png.c
+++ b/apps/plugins/imageviewer/png/png.c
@@ -50,18 +50,13 @@ static unsigned char *disp_buf;
50#define resize_bitmap grey_resize_bitmap 50#define resize_bitmap grey_resize_bitmap
51#endif 51#endif
52 52
53bool img_ext(const char *ext) 53#if defined(USEGSLIB) && (CONFIG_PLATFORM & PLATFORM_HOSTED)
54{ 54/* hack: fix error "undefined reference to `_grey_info'". */
55 if (!ext) 55GREY_INFO_STRUCT
56 return false; 56#endif /* USEGSLIB */
57 if (!rb->strcasecmp(ext,".png"))
58 return true;
59 else
60 return false;
61}
62 57
63void draw_image_rect(struct image_info *info, 58static void draw_image_rect(struct image_info *info,
64 int x, int y, int width, int height) 59 int x, int y, int width, int height)
65{ 60{
66 unsigned char **pdisp = (unsigned char **)info->data; 61 unsigned char **pdisp = (unsigned char **)info->data;
67 62
@@ -80,7 +75,7 @@ void draw_image_rect(struct image_info *info,
80#endif 75#endif
81} 76}
82 77
83int img_mem(int ds) 78static int img_mem(int ds)
84{ 79{
85 LodePNG_Decoder *p_decoder = &decoder; 80 LodePNG_Decoder *p_decoder = &decoder;
86 81
@@ -93,8 +88,8 @@ int img_mem(int ds)
93#endif 88#endif
94} 89}
95 90
96int load_image(char *filename, struct image_info *info, 91static int load_image(char *filename, struct image_info *info,
97 unsigned char *buf, ssize_t *buf_size) 92 unsigned char *buf, ssize_t *buf_size)
98{ 93{
99 int fd; 94 int fd;
100 long time = 0; /* measured ticks */ 95 long time = 0; /* measured ticks */
@@ -122,7 +117,7 @@ int load_image(char *filename, struct image_info *info,
122 117
123 DEBUGF("reading file '%s'\n", filename); 118 DEBUGF("reading file '%s'\n", filename);
124 119
125 if (!running_slideshow) { 120 if (!iv->running_slideshow) {
126 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); 121 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1);
127 rb->lcd_update(); 122 rb->lcd_update();
128 } 123 }
@@ -132,7 +127,7 @@ int load_image(char *filename, struct image_info *info,
132 rb->close(fd); 127 rb->close(fd);
133 128
134 } else { 129 } else {
135 if (!running_slideshow) { 130 if (!iv->running_slideshow) {
136 rb->lcd_putsf(0, 1, "loading %zu bytes", file_size); 131 rb->lcd_putsf(0, 1, "loading %zu bytes", file_size);
137 rb->lcd_update(); 132 rb->lcd_update();
138 } 133 }
@@ -142,12 +137,12 @@ int load_image(char *filename, struct image_info *info,
142 rb->read(fd, image, file_size); 137 rb->read(fd, image, file_size);
143 rb->close(fd); 138 rb->close(fd);
144 139
145 if (!running_slideshow) { 140 if (!iv->running_slideshow) {
146 rb->lcd_puts(0, 2, "decoding image"); 141 rb->lcd_puts(0, 2, "decoding image");
147 rb->lcd_update(); 142 rb->lcd_update();
148 } 143 }
149#ifdef DISK_SPINDOWN 144#ifdef DISK_SPINDOWN
150 else if (immediate_ata_off) { 145 else if (iv->immediate_ata_off) {
151 /* running slideshow and time is long enough: power down disk */ 146 /* running slideshow and time is long enough: power down disk */
152 rb->storage_sleep(); 147 rb->storage_sleep();
153 } 148 }
@@ -167,7 +162,7 @@ int load_image(char *filename, struct image_info *info,
167 162
168 if (!p_decoder->error) { 163 if (!p_decoder->error) {
169 164
170 if (!running_slideshow) { 165 if (!iv->running_slideshow) {
171 rb->lcd_putsf(0, 2, "image %dx%d", 166 rb->lcd_putsf(0, 2, "image %dx%d",
172 p_decoder->infoPng.width, 167 p_decoder->infoPng.width,
173 p_decoder->infoPng.height); 168 p_decoder->infoPng.height);
@@ -181,16 +176,16 @@ int load_image(char *filename, struct image_info *info,
181 time = *rb->current_tick; 176 time = *rb->current_tick;
182#ifdef HAVE_ADJUSTABLE_CPU_FREQ 177#ifdef HAVE_ADJUSTABLE_CPU_FREQ
183 rb->cpu_boost(true); 178 rb->cpu_boost(true);
184 LodePNG_decode(p_decoder, image, file_size, cb_progress); 179 LodePNG_decode(p_decoder, image, file_size, iv->cb_progress);
185 rb->cpu_boost(false); 180 rb->cpu_boost(false);
186#else 181#else
187 LodePNG_decode(p_decoder, image, file_size, cb_progress); 182 LodePNG_decode(p_decoder, image, file_size, iv->cb_progress);
188#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ 183#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
189 time = *rb->current_tick - time; 184 time = *rb->current_tick - time;
190 } 185 }
191 } 186 }
192 187
193 if (!running_slideshow && !p_decoder->error) 188 if (!iv->running_slideshow && !p_decoder->error)
194 { 189 {
195 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ); 190 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
196 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */ 191 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
@@ -200,7 +195,7 @@ int load_image(char *filename, struct image_info *info,
200 195
201 if (p_decoder->error) { 196 if (p_decoder->error) {
202#ifdef USE_PLUG_BUF 197#ifdef USE_PLUG_BUF
203 if (plug_buf && (p_decoder->error == FILE_TOO_LARGE || 198 if (iv->plug_buf && (p_decoder->error == FILE_TOO_LARGE ||
204 p_decoder->error == OUT_OF_MEMORY || 199 p_decoder->error == OUT_OF_MEMORY ||
205 p_decoder->error == TINF_DATA_ERROR)) 200 p_decoder->error == TINF_DATA_ERROR))
206 return PLUGIN_OUTOFMEM; 201 return PLUGIN_OUTOFMEM;
@@ -244,7 +239,7 @@ int load_image(char *filename, struct image_info *info,
244 return PLUGIN_OK; 239 return PLUGIN_OK;
245} 240}
246 241
247int get_image(struct image_info *info, int ds) 242static int get_image(struct image_info *info, int ds)
248{ 243{
249 unsigned char **p_disp = &disp[ds]; /* short cut */ 244 unsigned char **p_disp = &disp[ds]; /* short cut */
250 LodePNG_Decoder *p_decoder = &decoder; 245 LodePNG_Decoder *p_decoder = &decoder;
@@ -261,7 +256,7 @@ int get_image(struct image_info *info, int ds)
261 256
262 /* assign image buffer */ 257 /* assign image buffer */
263 if (ds > 1) { 258 if (ds > 1) {
264 if (!running_slideshow) 259 if (!iv->running_slideshow)
265 { 260 {
266 rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height); 261 rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height);
267 rb->lcd_update(); 262 rb->lcd_update();
@@ -303,3 +298,13 @@ int get_image(struct image_info *info, int ds)
303 298
304 return PLUGIN_OK; 299 return PLUGIN_OK;
305} 300}
301
302const struct image_decoder image_decoder = {
303 true,
304 img_mem,
305 load_image,
306 get_image,
307 draw_image_rect,
308};
309
310IMGDEC_HEADER
diff --git a/apps/plugins/imageviewer/png/png.make b/apps/plugins/imageviewer/png/png.make
index 0a7106d2a9..dee89acb71 100644
--- a/apps/plugins/imageviewer/png/png.make
+++ b/apps/plugins/imageviewer/png/png.make
@@ -10,18 +10,19 @@
10PNGSRCDIR := $(IMGVSRCDIR)/png 10PNGSRCDIR := $(IMGVSRCDIR)/png
11PNGBUILDDIR := $(IMGVBUILDDIR)/png 11PNGBUILDDIR := $(IMGVBUILDDIR)/png
12 12
13ROCKS += $(PNGBUILDDIR)/png.rock
14
15PNG_SRC := $(call preprocess, $(PNGSRCDIR)/SOURCES) 13PNG_SRC := $(call preprocess, $(PNGSRCDIR)/SOURCES)
16PNG_OBJ := $(call c2obj, $(PNG_SRC)) 14PNG_OBJ := $(call c2obj, $(PNG_SRC))
17 15
18# add source files to OTHER_SRC to get automatic dependencies
19OTHER_SRC += $(PNG_SRC) 16OTHER_SRC += $(PNG_SRC)
20 17
21# Use -O3 for png plugin : it gives a bigger file but very good performances 18ROCKS += $(PNGBUILDDIR)/png.ovl
22PNGFLAGS = $(PLUGINFLAGS) -Os
23 19
24$(PNGBUILDDIR)/png.rock: $(PNG_OBJ) 20$(PNGBUILDDIR)/png.refmap: $(PNG_OBJ)
21$(PNGBUILDDIR)/png.link: $(PNG_OBJ) $(PNGBUILDDIR)/png.refmap
22$(PNGBUILDDIR)/png.ovl: $(PNG_OBJ)
23
24# Use -O3 for png plugin : it gives a bigger file but very good performances
25PNGFLAGS = $(IMGDECFLAGS) -Os
25 26
26# Compile PNG plugin with extra flags (adapted from ZXBox) 27# Compile PNG plugin with extra flags (adapted from ZXBox)
27$(PNGBUILDDIR)/%.o: $(PNGSRCDIR)/%.c $(PNGSRCDIR)/png.make 28$(PNGBUILDDIR)/%.o: $(PNGSRCDIR)/%.c $(PNGSRCDIR)/png.make
diff --git a/apps/plugins/imageviewer/png/png_ui.c b/apps/plugins/imageviewer/png/png_ui.c
deleted file mode 100644
index 5dbf526ba1..0000000000
--- a/apps/plugins/imageviewer/png/png_ui.c
+++ /dev/null
@@ -1,5 +0,0 @@
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/plugin.lds b/apps/plugins/plugin.lds
index 2f11bd1235..f4bd64df35 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -181,6 +181,9 @@ OUTPUT_FORMAT(elf32-littlemips)
181#elif defined OVERLAY_OFFSET 181#elif defined OVERLAY_OFFSET
182#define THIS_LENGTH (DRAMSIZE - OVERLAY_OFFSET) 182#define THIS_LENGTH (DRAMSIZE - OVERLAY_OFFSET)
183#define THIS_ORIGIN (DRAMORIG + OVERLAY_OFFSET) 183#define THIS_ORIGIN (DRAMORIG + OVERLAY_OFFSET)
184#elif defined IMGVDECODER_OFFSET
185#define THIS_LENGTH (PLUGIN_LENGTH - IMGVDECODER_OFFSET)
186#define THIS_ORIGIN (PLUGIN_ORIGIN + IMGVDECODER_OFFSET)
184#else /* plugin */ 187#else /* plugin */
185#define THIS_LENGTH PLUGIN_LENGTH 188#define THIS_LENGTH PLUGIN_LENGTH
186#define THIS_ORIGIN PLUGIN_ORIGIN 189#define THIS_ORIGIN PLUGIN_ORIGIN
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index aa8b51b478..e0ebdbb496 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -13,11 +13,11 @@ ch8,viewers/chip8,0
13txt,viewers/text_viewer,1 13txt,viewers/text_viewer,1
14nfo,viewers/text_viewer,1 14nfo,viewers/text_viewer,1
15txt,apps/text_editor,2 15txt,apps/text_editor,2
16bmp,viewers/bmp,2 16bmp,viewers/imageviewer,2
17jpg,viewers/jpeg,2 17jpg,viewers/imageviewer,2
18jpe,viewers/jpeg,2 18jpe,viewers/imageviewer,2
19jpeg,viewers/jpeg,2 19jpeg,viewers/imageviewer,2
20png,viewers/png,2 20png,viewers/imageviewer,2
21ucl,viewers/rockbox_flash,3 21ucl,viewers/rockbox_flash,3
22rvf,viewers/video,4 22rvf,viewers/video,4
23mp3,viewers/vbrfix,5 23mp3,viewers/vbrfix,5
diff --git a/manual/plugins/bmpviewer.tex b/manual/plugins/bmpviewer.tex
deleted file mode 100755
index 44fd5e98f8..0000000000
--- a/manual/plugins/bmpviewer.tex
+++ /dev/null
@@ -1,115 +0,0 @@
1% $Id$ %
2\subsection{BMP viewer}
3This plugin opens \fname{.bmp} files from the \setting{File Browser} to display them\nopt{lcd_color}{ using Rockbox's greyscale library}.
4\opt{swcodec}{
5\par
6\note{
7When an audio file is playing the size of the image is limited as
8the decoding process needs to share memory with audio tracks. To be able to
9view a bigger file you may need to stop playback.}
10}
11\nopt{large_plugin_buffer}{%
12\note{This plugin will cause playback to stop.}%
13}%
14
15\begin{btnmap}
16 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD%
17 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD%
18 ,MROBE100_PAD,PBELL_VIBE500_PAD}
19 {\ButtonUp\ / \ButtonDown}%
20 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonMenu\ / \ButtonPlay}%
21 \opt{IRIVER_H10_PAD}{\ButtonScrollUp\ / \ButtonScrollDown} %
22 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD%
23 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD%
24 ,MROBE100_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IRIVER_H10_PAD,PBELL_VIBE500_PAD}
25 {/ \ButtonLeft\ / \ButtonRight}
26 \opt{COWON_D2_PAD}{}
27 \opt{HAVEREMOTEKEYMAP}{& }
28 & Move around in zoomed in image\\
29 \opt{RECORDER_PAD}{\ButtonPlay}
30 \opt{ONDIO_PAD,COWON_D2_PAD}{\ButtonMenu}
31 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD,SANSA_E200_PAD%
32 ,SANSA_FUZE_PAD,SANSA_C200_PAD,MROBE100_PAD}{\ButtonSelect}
33 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollFwd}
34 \opt{IRIVER_H10_PAD}{\ButtonPlay}
35 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolUp}
36 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonUp}
37 \opt{HAVEREMOTEKEYMAP}{& }
38 & Zoom in\\
39 \opt{RECORDER_PAD}{\ButtonOn}
40 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonDown}
41 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonMode}
42 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollBack}
43 \opt{IAUDIO_X5_PAD,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD}{Long \ButtonSelect}
44 \opt{IRIVER_H10_PAD}{Long \ButtonPlay}
45 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolDown}
46 \opt{MROBE100_PAD}{\ButtonPlay}
47 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonDown}
48 \opt{HAVEREMOTEKEYMAP}{& }
49 & Zoom out\\
50 \opt{RECORDER_PAD}{\ButtonFThree}
51 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonRight}
52 \opt{IRIVER_H100_PAD}{\ButtonOn}
53 \opt{IRIVER_H300_PAD}{\ButtonRec}
54 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonRight}
55 \opt{IAUDIO_X5_PAD}{\ButtonPlay}
56 \opt{IRIVER_H10_PAD}{\ButtonFF}
57 \opt{SANSA_E200_PAD,SANSA_FUZE_PAD}{\ButtonScrollFwd}
58 \opt{SANSA_C200_PAD}{\ButtonVolUp}
59 \opt{GIGABEAT_PAD}{\ButtonA+\ButtonRight}
60 \opt{GIGABEAT_S_PAD}{\ButtonNext}
61 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonRight}
62 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonRight}
63 \opt{HAVEREMOTEKEYMAP}{& }
64 & Next bmp in directory\\
65 \opt{RECORDER_PAD}{\ButtonFTwo}
66 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonLeft}
67 \opt{IRIVER_H100_PAD,IAUDIO_X5_PAD}{\ButtonRec}
68 \opt{IRIVER_H300_PAD}{\ButtonOn}
69 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonLeft}
70 \opt{IRIVER_H10_PAD}{\ButtonRew}
71 \opt{SANSA_E200_PAD,SANSA_FUZE_PAD}{\ButtonScrollBack}
72 \opt{SANSA_C200_PAD}{\ButtonVolDown}
73 \opt{GIGABEAT_PAD}{\ButtonA+\ButtonLeft}
74 \opt{GIGABEAT_S_PAD}{\ButtonPrev}
75 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonLeft}
76 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonLeft}
77 \opt{HAVEREMOTEKEYMAP}{& }
78 & Previous bmp in directory\\
79 \opt{SANSA_E200_PAD,SANSA_C200_PAD}{%currently only defined for the sansa pads
80 \ButtonRec
81 \opt{HAVEREMOTEKEYMAP}{& }
82 & Toggle slide show mode\\
83 }
84 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonOff}
85 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonMenu}
86 \opt{IAUDIO_X5_PAD,IRIVER_H10_PAD,SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower}
87 \opt{SANSA_FUZE_PAD}{Long \ButtonHome}
88 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}{\ButtonMenu}
89 \opt{COWON_D2_PAD}{\ButtonPower}
90 \opt{HAVEREMOTEKEYMAP}{&
91 \opt{IRIVER_RC_H100_PAD}{\ButtonRCStop}
92 }
93 & Show menu / Abort \\
94 \opt{IPOD_4G_PAD,IPOD_3G_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}{
95 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonPlay}
96 \opt{GIGABEAT_PAD,MROBE100_PAD}{\ButtonPower}
97 \opt{GIGABEAT_S_PAD}{\ButtonBack}
98 \opt{PBELL_VIBE500_PAD}{\ButtonCancel}
99 \opt{HAVEREMOTEKEYMAP}{& }
100 & Quit the viewer \\
101 }
102\end{btnmap}
103
104The menu has the following entries.
105\begin{description}
106\item[Return.] Returns you to the image
107\item[Toggle Slideshow Mode.] Enables or disables the slideshow mode.
108\item[Change Slideshow Timeout.] You can set the timeout for the slideshow
109 between 1 second and 20 seconds.
110\opt{large_plugin_buffer}{
111\item[Show Playback Menu.] From the playback menu you can control the
112playback of the currently loaded playlist and change the volume of your \dap.
113}
114\item[Quit.] Quits the viewer and returns to the \setting{File Browser}.
115\end{description}
diff --git a/manual/plugins/jpegviewer.tex b/manual/plugins/imageviewer.tex
index 82e3881427..28ef62e3a6 100644
--- a/manual/plugins/jpegviewer.tex
+++ b/manual/plugins/imageviewer.tex
@@ -1,7 +1,18 @@
1% $Id$ % 1% $Id$ %
2\subsection{JPEG viewer} 2\subsection{Image Viewer}
3This plugin opens \fname{.jpeg} files from the \setting{File Browser} to display them\nopt{lcd_color}{ using Rockbox's greyscale library}. 3This plugin opens image files from the \setting{File Browser} to display them\nopt{lcd_color}{ using Rockbox's greyscale library}. Supported formats are as follows.
4\opt{swcodec}{ 4
5\begin{table}
6 \begin{rbtabular}{.60\textwidth}{llX}%
7 {\textbf{Format}& \textbf{File-extension(s)}}%
8 {}{}
9 BMP & \fname{.bmp} \\
10 JPEG & \fname{.jpg, .jpe, .jpeg} \\
11 PNG & \fname{.png} \\
12 \end{rbtabular}
13\end{table}
14
15\opt{large_plugin_buffer}{
5\par 16\par
6\note{ 17\note{
7When an audio file is playing the size of the image is limited as 18When an audio file is playing the size of the image is limited as
@@ -23,17 +34,18 @@ view a bigger file you may need to stop playback.}
23 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD% 34 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD%
24 ,MROBE100_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IRIVER_H10_PAD,PBELL_VIBE500_PAD} 35 ,MROBE100_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IRIVER_H10_PAD,PBELL_VIBE500_PAD}
25 {/ \ButtonLeft\ / \ButtonRight} 36 {/ \ButtonLeft\ / \ButtonRight}
26 \opt{COWON_D2_PAD}{} 37 \opt{touchscreen}{\TouchTopMiddle{} / \TouchBottomMiddle{}/ \TouchMidLeft{} / \TouchMidRight}
27 \opt{HAVEREMOTEKEYMAP}{& } 38 \opt{HAVEREMOTEKEYMAP}{& }
28 & Move around in zoomed in image\\ 39 & Move around in zoomed in image\\
29 \opt{RECORDER_PAD}{\ButtonPlay} 40 \opt{RECORDER_PAD}{\ButtonPlay}
30 \opt{ONDIO_PAD,COWON_D2_PAD}{\ButtonMenu} 41 \opt{ONDIO_PAD}{\ButtonMenu}
31 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD,SANSA_E200_PAD% 42 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD,SANSA_E200_PAD%
32 ,SANSA_FUZE_PAD,SANSA_C200_PAD,MROBE100_PAD}{\ButtonSelect} 43 ,SANSA_FUZE_PAD,SANSA_C200_PAD,MROBE100_PAD}{\ButtonSelect}
33 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollFwd} 44 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollFwd}
34 \opt{IRIVER_H10_PAD}{\ButtonPlay} 45 \opt{IRIVER_H10_PAD}{\ButtonPlay}
35 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolUp} 46 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolUp}
36 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonUp} 47 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonUp}
48 \opt{touchscreen}{\TouchTopRight}
37 \opt{HAVEREMOTEKEYMAP}{& } 49 \opt{HAVEREMOTEKEYMAP}{& }
38 & Zoom in\\ 50 & Zoom in\\
39 \opt{RECORDER_PAD}{\ButtonOn} 51 \opt{RECORDER_PAD}{\ButtonOn}
@@ -45,6 +57,7 @@ view a bigger file you may need to stop playback.}
45 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolDown} 57 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolDown}
46 \opt{MROBE100_PAD}{\ButtonPlay} 58 \opt{MROBE100_PAD}{\ButtonPlay}
47 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonDown} 59 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonDown}
60 \opt{touchscreen}{\TouchTopLeft}
48 \opt{HAVEREMOTEKEYMAP}{& } 61 \opt{HAVEREMOTEKEYMAP}{& }
49 & Zoom out\\ 62 & Zoom out\\
50 \opt{RECORDER_PAD}{\ButtonFThree} 63 \opt{RECORDER_PAD}{\ButtonFThree}
@@ -60,8 +73,9 @@ view a bigger file you may need to stop playback.}
60 \opt{GIGABEAT_S_PAD}{\ButtonNext} 73 \opt{GIGABEAT_S_PAD}{\ButtonNext}
61 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonRight} 74 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonRight}
62 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonRight} 75 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonRight}
76 \opt{touchscreen}{\TouchBottomRight}
63 \opt{HAVEREMOTEKEYMAP}{& } 77 \opt{HAVEREMOTEKEYMAP}{& }
64 & Next jpeg in directory\\ 78 & Next image in directory\\
65 \opt{RECORDER_PAD}{\ButtonFTwo} 79 \opt{RECORDER_PAD}{\ButtonFTwo}
66 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonLeft} 80 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonLeft}
67 \opt{IRIVER_H100_PAD,IAUDIO_X5_PAD}{\ButtonRec} 81 \opt{IRIVER_H100_PAD,IAUDIO_X5_PAD}{\ButtonRec}
@@ -74,8 +88,9 @@ view a bigger file you may need to stop playback.}
74 \opt{GIGABEAT_S_PAD}{\ButtonPrev} 88 \opt{GIGABEAT_S_PAD}{\ButtonPrev}
75 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonLeft} 89 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonLeft}
76 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonLeft} 90 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonLeft}
91 \opt{touchscreen}{\TouchBottomLeft}
77 \opt{HAVEREMOTEKEYMAP}{& } 92 \opt{HAVEREMOTEKEYMAP}{& }
78 & Previous jpeg in directory\\ 93 & Previous image in directory\\
79 \opt{SANSA_E200_PAD,SANSA_C200_PAD}{%currently only defined for the sansa pads 94 \opt{SANSA_E200_PAD,SANSA_C200_PAD}{%currently only defined for the sansa pads
80 \ButtonRec 95 \ButtonRec
81 \opt{HAVEREMOTEKEYMAP}{& } 96 \opt{HAVEREMOTEKEYMAP}{& }
@@ -86,7 +101,7 @@ view a bigger file you may need to stop playback.}
86 \opt{IAUDIO_X5_PAD,IRIVER_H10_PAD,SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower} 101 \opt{IAUDIO_X5_PAD,IRIVER_H10_PAD,SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower}
87 \opt{SANSA_FUZE_PAD}{Long \ButtonHome} 102 \opt{SANSA_FUZE_PAD}{Long \ButtonHome}
88 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}{\ButtonMenu} 103 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}{\ButtonMenu}
89 \opt{COWON_D2_PAD}{\ButtonPower} 104 \opt{touchscreen}{\TouchCenter}
90 \opt{HAVEREMOTEKEYMAP}{& 105 \opt{HAVEREMOTEKEYMAP}{&
91 \opt{IRIVER_RC_H100_PAD}{\ButtonRCStop} 106 \opt{IRIVER_RC_H100_PAD}{\ButtonRCStop}
92 } 107 }
@@ -114,7 +129,8 @@ playback of the currently loaded playlist and change the volume of your \dap.
114\opt{lcd_color}{ 129\opt{lcd_color}{
115\item[Display Options.] From this menu you can force the viewer to render the 130\item[Display Options.] From this menu you can force the viewer to render the
116image in greyscale using the \setting{Greyscale} option or set the method of 131image in greyscale using the \setting{Greyscale} option or set the method of
117dithering used in the \setting{Dithering} submenu. 132dithering used in the \setting{Dithering} submenu. These settings only take affect
133for JPEG images.
118} 134}
119\item[Quit.] Quits the viewer and returns to the \setting{File Browser}. 135\item[Quit.] Quits the viewer and returns to the \setting{File Browser}.
120\end{description} 136\end{description}
diff --git a/manual/plugins/main.tex b/manual/plugins/main.tex
index a40c81d630..b847c15b51 100644
--- a/manual/plugins/main.tex
+++ b/manual/plugins/main.tex
@@ -137,11 +137,10 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).}
137 \begin{rbtabular}{.92\textwidth}{Xlc}% 137 \begin{rbtabular}{.92\textwidth}{Xlc}%
138 {\textbf{Viewer Plugin}& \textbf{Associated filetype(s)} & \textbf{Context Menu only}}% 138 {\textbf{Viewer Plugin}& \textbf{Associated filetype(s)} & \textbf{Context Menu only}}%
139 {}{} 139 {}{}
140 BMP Viewer & \fname{.bmp} & \\
141 Shortcuts & \fname{.link} & \\ 140 Shortcuts & \fname{.link} & \\
142 Chip-8 Emulator & \fname{.ch8} & \\ 141 Chip-8 Emulator & \fname{.ch8} & \\
143 Frotz & \fname{.z1 - .z8} & \\ 142 Frotz & \fname{.z1 - .z8} & \\
144 JPEG Viewer & \fname{.jpg, .jpeg} & \\ 143 Image Viewer & \fname{.bmp, .jpg, .jpeg, .png} & \\
145 Lua scripting language& \fname{.lua} & \\ 144 Lua scripting language& \fname{.lua} & \\
146 \opt{swcodec}{\nopt{lowmem}{ 145 \opt{swcodec}{\nopt{lowmem}{
147 Midiplay & \fname{.mid, .midi} & \\ 146 Midiplay & \fname{.mid, .midi} & \\
@@ -152,9 +151,6 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).}
152 Movie Player & \fname{.rvf} & \\ 151 Movie Player & \fname{.rvf} & \\
153 } 152 }
154 } 153 }
155 \opt{lcd_bitmap}{
156 PNG viewer & \fname{.png} & \\
157 }
158 \opt{lcd_color}{ 154 \opt{lcd_color}{
159 PPM viewer & \fname{.ppm} & \\ 155 PPM viewer & \fname{.ppm} & \\
160 } 156 }
@@ -177,13 +173,11 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).}
177 173
178{\input{plugins/shortcuts.tex}} 174{\input{plugins/shortcuts.tex}}
179 175
180\opt{lcd_bitmap}{\input{plugins/bmpviewer.tex}}
181
182\opt{lcd_bitmap}{\input{plugins/chip8emulator.tex}} 176\opt{lcd_bitmap}{\input{plugins/chip8emulator.tex}}
183 177
184\opt{lcd_bitmap}{\input{plugins/frotz.tex}} 178\opt{lcd_bitmap}{\input{plugins/frotz.tex}}
185 179
186\opt{lcd_bitmap}{\input{plugins/jpegviewer.tex}} 180\opt{lcd_bitmap}{\input{plugins/imageviewer.tex}}
187 181
188\opt{large_plugin_buffer}{\input{plugins/lua.tex}} 182\opt{large_plugin_buffer}{\input{plugins/lua.tex}}
189 183
@@ -193,8 +187,6 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).}
193 187
194\opt{lcd_bitmap}{\opt{swcodec}{\nopt{lowmem}{\input{plugins/mpegplayer.tex}}}} 188\opt{lcd_bitmap}{\opt{swcodec}{\nopt{lowmem}{\input{plugins/mpegplayer.tex}}}}
195 189
196\opt{lcd_bitmap}{\input{plugins/pngviewer.tex}}
197
198\opt{lcd_color}{\input{plugins/ppmviewer.tex}} 190\opt{lcd_color}{\input{plugins/ppmviewer.tex}}
199 191
200\opt{archosrecorder,archosfmrecorder,ondio}{\input{plugins/rockbox_flash.tex}} 192\opt{archosrecorder,archosfmrecorder,ondio}{\input{plugins/rockbox_flash.tex}}
diff --git a/manual/plugins/pngviewer.tex b/manual/plugins/pngviewer.tex
deleted file mode 100644
index 3dfb6d047a..0000000000
--- a/manual/plugins/pngviewer.tex
+++ /dev/null
@@ -1,113 +0,0 @@
1% $Id$ %
2\subsection{PNG viewer}
3This plugin opens \fname{.png} files from the \setting{File Browser} to
4display them.
5\opt{swcodec}{
6 \note{When an audio file is playing the size of the image is limited as
7 the decoding process needs to share memory with audio tracks. To be able to
8 view a bigger file you may need to stop playback.\\}
9}
10\nopt{large_plugin_buffer}{%
11\note{This plugin will cause playback to stop.}%
12}%
13
14\begin{btnmap}
15 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD%
16 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD%
17 ,MROBE100_PAD,PBELL_VIBE500_PAD}
18 {\ButtonUp\ / \ButtonDown}%
19 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonMenu\ / \ButtonPlay}%
20 \opt{IRIVER_H10_PAD}{\ButtonScrollUp\ / \ButtonScrollDown} %
21 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD%
22 ,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD%
23 ,MROBE100_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IRIVER_H10_PAD,PBELL_VIBE500_PAD}
24 {/ \ButtonLeft\ / \ButtonRight}
25 \opt{HAVEREMOTEKEYMAP}{& }
26 & Move around in zoomed in image\\
27 \opt{RECORDER_PAD}{\ButtonPlay}
28 \opt{ONDIO_PAD}{\ButtonMenu}
29 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD,SANSA_E200_PAD%
30 ,SANSA_FUZE_PAD,SANSA_C200_PAD,MROBE100_PAD}{\ButtonSelect}
31 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollFwd}
32 \opt{IRIVER_H10_PAD}{\ButtonPlay}
33 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolUp}
34 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonUp}
35 \opt{HAVEREMOTEKEYMAP}{& }
36 & Zoom in\\
37 \opt{RECORDER_PAD}{\ButtonOn}
38 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonDown}
39 \opt{IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonMode}
40 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonScrollBack}
41 \opt{IAUDIO_X5_PAD,SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD}{Long \ButtonSelect}
42 \opt{IRIVER_H10_PAD}{Long \ButtonPlay}
43 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD}{\ButtonVolDown}
44 \opt{MROBE100_PAD}{\ButtonPlay}
45 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonDown}
46 \opt{HAVEREMOTEKEYMAP}{& }
47 & Zoom out\\
48 \opt{RECORDER_PAD}{\ButtonFThree}
49 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonRight}
50 \opt{IRIVER_H100_PAD}{\ButtonOn}
51 \opt{IRIVER_H300_PAD}{\ButtonRec}
52 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonRight}
53 \opt{IAUDIO_X5_PAD}{\ButtonPlay}
54 \opt{IRIVER_H10_PAD}{\ButtonFF}
55 \opt{SANSA_E200_PAD,SANSA_FUZE_PAD}{\ButtonScrollFwd}
56 \opt{SANSA_C200_PAD}{\ButtonVolUp}
57 \opt{GIGABEAT_PAD}{\ButtonA+\ButtonRight}
58 \opt{GIGABEAT_S_PAD}{\ButtonNext}
59 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonRight}
60 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonRight}
61 \opt{HAVEREMOTEKEYMAP}{& }
62 & Next png in directory\\
63 \opt{RECORDER_PAD}{\ButtonFTwo}
64 \opt{ONDIO_PAD}{\ButtonMenu+\ButtonLeft}
65 \opt{IRIVER_H100_PAD,IAUDIO_X5_PAD}{\ButtonRec}
66 \opt{IRIVER_H300_PAD}{\ButtonOn}
67 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonLeft}
68 \opt{IRIVER_H10_PAD}{\ButtonRew}
69 \opt{SANSA_E200_PAD,SANSA_FUZE_PAD}{\ButtonScrollBack}
70 \opt{SANSA_C200_PAD}{\ButtonVolDown}
71 \opt{GIGABEAT_PAD}{\ButtonA+\ButtonLeft}
72 \opt{GIGABEAT_S_PAD}{\ButtonPrev}
73 \opt{MROBE100_PAD}{\ButtonDisplay+\ButtonLeft}
74 \opt{PBELL_VIBE500_PAD}{\ButtonRec+\ButtonLeft}
75 \opt{HAVEREMOTEKEYMAP}{& }
76 & Previous png in directory\\
77 \opt{SANSA_E200_PAD,SANSA_C200_PAD}{%currently only defined for the sansa pads
78 \ButtonRec
79 \opt{HAVEREMOTEKEYMAP}{& }
80 & Toggle slide show mode\\
81 }
82 \opt{RECORDER_PAD,ONDIO_PAD,IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonOff}
83 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonMenu}
84 \opt{IAUDIO_X5_PAD,IRIVER_H10_PAD,SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower}
85 \opt{SANSA_FUZE_PAD}{Long \ButtonHome}
86 \opt{GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}{\ButtonMenu}
87 \opt{HAVEREMOTEKEYMAP}{&
88 \opt{IRIVER_RC_H100_PAD}{\ButtonRCStop}
89 }
90 & Show menu / Abort while decoding \\
91 \opt{IPOD_4G_PAD,IPOD_3G_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD%
92 ,PBELL_VIBE500_PAD}{%
93 \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonSelect+\ButtonPlay}
94 \opt{GIGABEAT_PAD,MROBE100_PAD}{\ButtonPower}
95 \opt{GIGABEAT_S_PAD}{\ButtonBack}
96 \opt{PBELL_VIBE500_PAD}{\ButtonCancel}
97 \opt{HAVEREMOTEKEYMAP}{& }
98 & Quit the viewer \\
99 }
100\end{btnmap}
101
102The menu has the following entries.
103\begin{description}
104\item[Return.] Returns you to the image
105\item[Toggle Slideshow Mode.] Enables or disables the slideshow mode.
106\item[Change Slideshow Timeout.] You can set the timeout for the slideshow
107 between 1 second and 20 seconds.
108\opt{large_plugin_buffer}{
109\item[Show Playback Menu.] From the playback menu you can control the
110playback of the currently loaded playlist and change the volume of your \dap.
111}
112\item[Quit.] Quits the viewer and returns to the \setting{File Browser}.
113\end{description}
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index 62413acd30..a3c0172773 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -470,8 +470,11 @@ STOP
470 470
471 find(find_copyfile(qr/\.(rock|ovl|lua)/, abs_path("$temp_dir/rocks/")), 'apps/plugins'); 471 find(find_copyfile(qr/\.(rock|ovl|lua)/, abs_path("$temp_dir/rocks/")), 'apps/plugins');
472 472
473 open VIEWERS, "$ROOT/apps/plugins/viewers.config" or 473 # exclude entries for the image file types not supported by the imageviewer for the target.
474 die "can't open viewers.config"; 474 my $viewers = "$ROOT/apps/plugins/viewers.config";
475 my $c="cat $viewers | gcc $cppdef -I. -I$firmdir/export -E -P -include config.h -";
476
477 open VIEWERS, "$c|" or die "can't open viewers.config";
475 my @viewers = <VIEWERS>; 478 my @viewers = <VIEWERS>;
476 close VIEWERS; 479 close VIEWERS;
477 480