summaryrefslogtreecommitdiffstats
path: root/apps
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 /apps
parent135d983433e741cf9658ff5d7457bdf37ef48ce0 (diff)
downloadrockbox-5bd08237499dfc66309ba2a5a4dac75018e794ac.tar.gz
rockbox-5bd08237499dfc66309ba2a5a4dac75018e794ac.tar.bz2
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
Diffstat (limited to 'apps')
-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
#endif
chessbox
fractals
-jpeg
+imageviewer
sudoku
reversi
goban
@@ -29,9 +29,6 @@ goban
#if (CONFIG_CPU != SH7034)
frotz
#endif
-#ifdef HAVE_LCD_COLOR
-png
-#endif
#ifndef OLYMPUS_MROBE_500
zxbox
#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 @@
+jpeg
+#ifdef HAVE_LCD_COLOR
+png
+#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 @@
/***************************************************************************
-* __________ __ ___.
-* Open \______ \ ____ ____ | | _\_ |__ _______ ___
-* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
-* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
-* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
-* \/ \/ \/ \/ \/
-* $Id$
-*
-* JPEG image viewer
-* (This is a real mess if it has to be coded in one single C file)
-*
-* File scrolling addition (C) 2005 Alexander Spyridakis
-* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
-* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
-* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-* KIND, either express or implied.
-*
-****************************************************************************/
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * user intereface of image viewers (jpeg, png, etc.)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
#include "plugin.h"
#include <lib/playback_control.h>
#include <lib/helper.h>
#include <lib/configfile.h>
-
-#include <lib/grey.h>
-#include <lib/xlcd.h>
-
-#include "jpeg.h"
-#include "jpeg_decoder.h"
+#include "imageviewer.h"
PLUGIN_HEADER
-#ifdef HAVE_LCD_COLOR
-#include "yuv2rgb.h"
-#endif
-
-/* different graphics libraries */
-#if LCD_DEPTH < 8
-#define USEGSLIB
+#ifdef USEGSLIB
GREY_INFO_STRUCT
-#define MYLCD(fn) grey_ub_ ## fn
-#define MYLCD_UPDATE()
-#define MYXLCD(fn) grey_ub_ ## fn
-#else
-#define MYLCD(fn) rb->lcd_ ## fn
-#define MYLCD_UPDATE() rb->lcd_update();
-#define MYXLCD(fn) xlcd_ ## fn
#endif
-/* Min memory allowing us to use the plugin buffer
- * and thus not stopping the music
- * *Very* rough estimation:
- * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
- * + 20k code size = 60 000
- * + 50k min for jpeg = 120 000
- */
-#define MIN_MEM 120000
-
/* Headings */
#define DIR_PREV 1
#define DIR_NEXT -1
#define DIR_NONE 0
-#define PLUGIN_OTHER 10 /* State code for output with return. */
-#define PLUGIN_ABORT 11
-#define PLUGIN_OUTOFMEM 12
-
/******************************* Globals ***********************************/
-static int slideshow_enabled = false; /* run slideshow */
-static int running_slideshow = false; /* loading image because of slideshw */
-#ifndef SIMULATOR
-static int immediate_ata_off = false; /* power down disk after loading */
+bool slideshow_enabled = false; /* run slideshow */
+bool running_slideshow = false; /* loading image because of slideshw */
+#ifdef DISK_SPINDOWN
+bool immediate_ata_off = false; /* power down disk after loading */
#endif
-
-#ifdef HAVE_LCD_COLOR
-fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
- DITHER_DIFFUSION is set */
+#if PLUGIN_BUFFER_SIZE >= MIN_MEM
+/* are we using the plugin buffer or the audio buffer? */
+bool plug_buf = true;
#endif
-
/* Persistent configuration */
-#define JPEG_CONFIGFILE "jpeg.cfg"
-#define JPEG_SETTINGS_MINVERSION 1
-#define JPEG_SETTINGS_VERSION 2
+#define IMGVIEW_CONFIGFILE "imageviewer.cfg"
+#define IMGVIEW_SETTINGS_MINVERSION 1
+#define IMGVIEW_SETTINGS_VERSION 2
/* Slideshow times */
-#define SS_MIN_TIMEOUT 1
-#define SS_MAX_TIMEOUT 20
-#define SS_DEFAULT_TIMEOUT 5
+#define SS_MIN_TIMEOUT 1
+#define SS_MAX_TIMEOUT 20
+#define SS_DEFAULT_TIMEOUT 5
-struct jpeg_settings
-{
#ifdef HAVE_LCD_COLOR
- int colour_mode;
- int dither_mode;
+/* needed for value of settings */
+#include "jpeg/yuv2rgb.h"
#endif
- int ss_timeout;
-};
-static struct jpeg_settings jpeg_settings =
+/* jpeg use this */
+struct imgview_settings settings =
{
#ifdef HAVE_LCD_COLOR
COLOURMODE_COLOUR,
@@ -114,18 +72,18 @@ static struct jpeg_settings jpeg_settings =
#endif
SS_DEFAULT_TIMEOUT
};
-static struct jpeg_settings old_settings;
+static struct imgview_settings old_settings;
-static struct configdata jpeg_config[] =
+static struct configdata config[] =
{
#ifdef HAVE_LCD_COLOR
- { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &jpeg_settings.colour_mode },
+ { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &settings.jpeg_colour_mode },
"Colour Mode", (char *[]){ "Colour", "Grayscale" } },
- { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &jpeg_settings.dither_mode },
+ { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &settings.jpeg_dither_mode },
"Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" } },
#endif
{ TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT,
- { .int_p = &jpeg_settings.ss_timeout }, "Slideshow Time", NULL },
+ { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL },
};
#if LCD_DEPTH > 1
@@ -135,43 +93,21 @@ static fb_data* old_backdrop;
/**************** begin Application ********************/
-/************************* Types ***************************/
-
-struct t_disp
-{
-#ifdef HAVE_LCD_COLOR
- unsigned char* bitmap[3]; /* Y, Cr, Cb */
- int csub_x, csub_y;
-#else
- unsigned char* bitmap[1]; /* Y only */
-#endif
- int width;
- int height;
- int stride;
- int x, y;
-};
-
/************************* Globals ***************************/
-/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
-static struct t_disp disp[9];
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
+static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
+ DITHER_DIFFUSION is set */
+#endif
/* my memory pool (from the mp3 buffer) */
static char print[32]; /* use a common snprintf() buffer */
-/* the remaining free part of the buffer for compressed+uncompressed images */
+/* the remaining free part of the buffer for loaded+resized images */
static unsigned char* buf;
static ssize_t buf_size;
-/* the root of the images, hereafter are decompresed ones */
-static unsigned char* buf_root;
-static int root_size;
-
-/* up to here currently used by image(s) */
-static unsigned char* buf_images;
-static ssize_t buf_images_size;
-
static int ds, ds_min, ds_max; /* downscaling and limits */
-static struct jpeg jpg; /* too large for stack */
+static struct image_info image_info;
static struct tree_context *tree;
@@ -179,30 +115,13 @@ static struct tree_context *tree;
static char np_file[MAX_PATH];
static int curfile = 0, direction = DIR_NONE, entries = 0;
-/* list of the jpeg files */
+/* list of the supported image files */
static char **file_pt;
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
-/* are we using the plugin buffer or the audio buffer? */
-static bool plug_buf = true;
-#endif
-
/************************* Implementation ***************************/
-bool jpg_ext(const char ext[])
-{
- if(!ext)
- return false;
- if(!rb->strcasecmp(ext,".jpg") ||
- !rb->strcasecmp(ext,".jpe") ||
- !rb->strcasecmp(ext,".jpeg"))
- return true;
- else
- return false;
-}
-
/*Read directory contents for scrolling. */
-void get_pic_list(void)
+static void get_pic_list(void)
{
int i;
struct entry *dircache;
@@ -219,7 +138,7 @@ void get_pic_list(void)
for (i = 0; i < tree->filesindir; i++)
{
if (!(dircache[i].attr & ATTR_DIRECTORY)
- && jpg_ext(rb->strrchr(dircache[i].name,'.')))
+ && img_ext(rb->strrchr(dircache[i].name,'.')))
{
file_pt[entries] = dircache[i].name;
/* Set Selected File. */
@@ -233,7 +152,7 @@ void get_pic_list(void)
buf_size -= (entries * sizeof(char**));
}
-int change_filename(int direct)
+static int change_filename(int direct)
{
bool file_erased = (file_pt[curfile] == NULL);
direction = direct;
@@ -276,7 +195,7 @@ int change_filename(int direct)
}
/* switch off overlay, for handling SYS_ events */
-void cleanup(void *parameter)
+static void cleanup(void *parameter)
{
(void)parameter;
#ifdef USEGSLIB
@@ -290,16 +209,16 @@ void cleanup(void *parameter)
#define ZOOM_IN 100 /* return codes for below function */
#define ZOOM_OUT 101
-#ifdef HAVE_LCD_COLOR
-bool set_option_grayscale(void)
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
+static bool set_option_grayscale(void)
{
- bool gray = jpeg_settings.colour_mode == COLOURMODE_GRAY;
+ bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY;
rb->set_bool("Grayscale", &gray);
- jpeg_settings.colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
+ settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
return false;
}
-bool set_option_dithering(void)
+static bool set_option_dithering(void)
{
static const struct opt_items dithering[DITHER_NUM_MODES] = {
[DITHER_NONE] = { "Off", -1 },
@@ -307,7 +226,7 @@ bool set_option_dithering(void)
[DITHER_DIFFUSION] = { "Diffusion", -1 },
};
- rb->set_option("Dithering", &jpeg_settings.dither_mode, INT,
+ rb->set_option("Dithering", &settings.jpeg_dither_mode, INT,
dithering, DITHER_NUM_MODES, NULL);
return false;
}
@@ -323,9 +242,9 @@ static void display_options(void)
{
rb->do_menu(&display_menu, NULL, NULL, false);
}
-#endif /* HAVE_LCD_COLOR */
+#endif /* defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) */
-int show_menu(void) /* return 1 to quit */
+static int show_menu(void) /* return 1 to quit */
{
#if LCD_DEPTH > 1
rb->lcd_set_backdrop(old_backdrop);
@@ -347,19 +266,19 @@ int show_menu(void) /* return 1 to quit */
#if PLUGIN_BUFFER_SIZE >= MIN_MEM
MIID_SHOW_PLAYBACK_MENU,
#endif
-#ifdef HAVE_LCD_COLOR
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
MIID_DISPLAY_OPTIONS,
#endif
MIID_QUIT,
};
- MENUITEM_STRINGLIST(menu, "Jpeg Menu", NULL,
+ MENUITEM_STRINGLIST(menu, MENU_TITLE, NULL,
"Return", "Toggle Slideshow Mode",
"Change Slideshow Time",
#if PLUGIN_BUFFER_SIZE >= MIN_MEM
"Show Playback Menu",
#endif
-#ifdef HAVE_LCD_COLOR
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
"Display Options",
#endif
"Quit");
@@ -381,7 +300,7 @@ int show_menu(void) /* return 1 to quit */
break;
case MIID_CHANGE_SS_MODE:
rb->set_int("Slideshow Time", "s", UNIT_SEC,
- &jpeg_settings.ss_timeout, NULL, 1,
+ &settings.ss_timeout, NULL, 1,
SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
break;
@@ -397,7 +316,7 @@ int show_menu(void) /* return 1 to quit */
}
break;
#endif
-#ifdef HAVE_LCD_COLOR
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
case MIID_DISPLAY_OPTIONS:
display_options();
break;
@@ -407,14 +326,14 @@ int show_menu(void) /* return 1 to quit */
break;
}
-#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
+#ifdef DISK_SPINDOWN
/* change ata spindown time based on slideshow time setting */
immediate_ata_off = false;
rb->storage_spindown(rb->global_settings->disk_spindown);
if (slideshow_enabled)
{
- if(jpeg_settings.ss_timeout < 10)
+ if(settings.ss_timeout < 10)
{
/* slideshow times < 10s keep disk spinning */
rb->storage_spindown(0);
@@ -435,115 +354,96 @@ int show_menu(void) /* return 1 to quit */
return 0;
}
-void draw_image_rect(struct t_disp* pdisp, int x, int y, int width, int height)
-{
-#ifdef HAVE_LCD_COLOR
- yuv_bitmap_part(
- pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
- pdisp->x + x, pdisp->y + y, pdisp->stride,
- x + MAX(0, (LCD_WIDTH - pdisp->width) / 2),
- y + MAX(0, (LCD_HEIGHT - pdisp->height) / 2),
- width, height,
- jpeg_settings.colour_mode, jpeg_settings.dither_mode);
-#else
- MYXLCD(gray_bitmap_part)(
- pdisp->bitmap[0], pdisp->x + x, pdisp->y + y, pdisp->stride,
- x + MAX(0, (LCD_WIDTH-pdisp->width)/2),
- y + MAX(0, (LCD_HEIGHT-pdisp->height)/2),
- width, height);
-#endif
-}
-
/* Pan the viewing window right - move image to the left and fill in
the right-hand side */
-static void pan_view_right(struct t_disp* pdisp)
+static void pan_view_right(struct image_info *info)
{
int move;
- move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH);
+ move = MIN(HSCROLL, info->width - info->x - LCD_WIDTH);
if (move > 0)
{
MYXLCD(scroll_left)(move); /* scroll left */
- pdisp->x += move;
- draw_image_rect(pdisp, LCD_WIDTH - move, 0, move, pdisp->height-pdisp->y);
+ info->x += move;
+ draw_image_rect(info, LCD_WIDTH - move, 0, move, info->height-info->y);
MYLCD_UPDATE();
}
}
/* Pan the viewing window left - move image to the right and fill in
the left-hand side */
-static void pan_view_left(struct t_disp* pdisp)
+static void pan_view_left(struct image_info *info)
{
int move;
- move = MIN(HSCROLL, pdisp->x);
+ move = MIN(HSCROLL, info->x);
if (move > 0)
{
MYXLCD(scroll_right)(move); /* scroll right */
- pdisp->x -= move;
- draw_image_rect(pdisp, 0, 0, move, pdisp->height-pdisp->y);
+ info->x -= move;
+ draw_image_rect(info, 0, 0, move, info->height-info->y);
MYLCD_UPDATE();
}
}
/* Pan the viewing window up - move image down and fill in
the top */
-static void pan_view_up(struct t_disp* pdisp)
+static void pan_view_up(struct image_info *info)
{
int move;
- move = MIN(VSCROLL, pdisp->y);
+ move = MIN(VSCROLL, info->y);
if (move > 0)
{
MYXLCD(scroll_down)(move); /* scroll down */
- pdisp->y -= move;
-#ifdef HAVE_LCD_COLOR
- if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
+ info->y -= move;
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
+ if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
{
/* Draw over the band at the top of the last update
caused by lack of error history on line zero. */
- move = MIN(move + 1, pdisp->y + pdisp->height);
+ move = MIN(move + 1, info->y + info->height);
}
#endif
- draw_image_rect(pdisp, 0, 0, pdisp->width-pdisp->x, move);
+ draw_image_rect(info, 0, 0, info->width-info->x, move);
MYLCD_UPDATE();
}
}
/* Pan the viewing window down - move image up and fill in
the bottom */
-static void pan_view_down(struct t_disp* pdisp)
+static void pan_view_down(struct image_info *info)
{
int move;
- move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT);
+ move = MIN(VSCROLL, info->height - info->y - LCD_HEIGHT);
if (move > 0)
{
MYXLCD(scroll_up)(move); /* scroll up */
- pdisp->y += move;
-#ifdef HAVE_LCD_COLOR
- if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
+ info->y += move;
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
+ if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
{
/* Save the line that was on the last line of the display
and draw one extra line above then recover the line with
image data that had an error history when it was drawn.
*/
- move++, pdisp->y--;
+ move++, info->y--;
rb->memcpy(rgb_linebuf,
rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
LCD_WIDTH*sizeof (fb_data));
}
#endif
- draw_image_rect(pdisp, 0, LCD_HEIGHT - move, pdisp->width-pdisp->x, move);
+ draw_image_rect(info, 0, LCD_HEIGHT - move, info->width-info->x, move);
-#ifdef HAVE_LCD_COLOR
- if (jpeg_settings.dither_mode == DITHER_DIFFUSION)
+#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER)
+ if (settings.jpeg_dither_mode == DITHER_DIFFUSION)
{
/* Cover the first row drawn with previous image data. */
rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
rgb_linebuf, LCD_WIDTH*sizeof (fb_data));
- pdisp->y++;
+ info->y++;
}
#endif
MYLCD_UPDATE();
@@ -551,7 +451,7 @@ static void pan_view_down(struct t_disp* pdisp)
}
/* interactively scroll around the image */
-int scroll_bmp(struct t_disp* pdisp)
+static int scroll_bmp(struct image_info *info)
{
int button;
int lastbutton = 0;
@@ -559,7 +459,7 @@ int scroll_bmp(struct t_disp* pdisp)
while (true)
{
if (slideshow_enabled)
- button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
+ button = rb->button_get_w_tmo(settings.ss_timeout * HZ);
else
button = rb->button_get(true);
@@ -567,30 +467,30 @@ int scroll_bmp(struct t_disp* pdisp)
switch(button)
{
- case JPEG_LEFT:
- if (entries > 1 && pdisp->width <= LCD_WIDTH
- && pdisp->height <= LCD_HEIGHT)
+ case IMGVIEW_LEFT:
+ if (entries > 1 && info->width <= LCD_WIDTH
+ && info->height <= LCD_HEIGHT)
return change_filename(DIR_PREV);
- case JPEG_LEFT | BUTTON_REPEAT:
- pan_view_left(pdisp);
+ case IMGVIEW_LEFT | BUTTON_REPEAT:
+ pan_view_left(info);
break;
- case JPEG_RIGHT:
- if (entries > 1 && pdisp->width <= LCD_WIDTH
- && pdisp->height <= LCD_HEIGHT)
+ case IMGVIEW_RIGHT:
+ if (entries > 1 && info->width <= LCD_WIDTH
+ && info->height <= LCD_HEIGHT)
return change_filename(DIR_NEXT);
- case JPEG_RIGHT | BUTTON_REPEAT:
- pan_view_right(pdisp);
+ case IMGVIEW_RIGHT | BUTTON_REPEAT:
+ pan_view_right(info);
break;
- case JPEG_UP:
- case JPEG_UP | BUTTON_REPEAT:
- pan_view_up(pdisp);
+ case IMGVIEW_UP:
+ case IMGVIEW_UP | BUTTON_REPEAT:
+ pan_view_up(info);
break;
- case JPEG_DOWN:
- case JPEG_DOWN | BUTTON_REPEAT:
- pan_view_down(pdisp);
+ case IMGVIEW_DOWN:
+ case IMGVIEW_DOWN | BUTTON_REPEAT:
+ pan_view_down(info);
break;
case BUTTON_NONE:
@@ -601,48 +501,48 @@ int scroll_bmp(struct t_disp* pdisp)
return change_filename(DIR_NEXT);
break;
-#ifdef JPEG_SLIDE_SHOW
- case JPEG_SLIDE_SHOW:
+#ifdef IMGVIEW_SLIDE_SHOW
+ case IMGVIEW_SLIDE_SHOW:
slideshow_enabled = !slideshow_enabled;
running_slideshow = slideshow_enabled;
break;
#endif
-#ifdef JPEG_NEXT_REPEAT
- case JPEG_NEXT_REPEAT:
+#ifdef IMGVIEW_NEXT_REPEAT
+ case IMGVIEW_NEXT_REPEAT:
#endif
- case JPEG_NEXT:
+ case IMGVIEW_NEXT:
if (entries > 1)
return change_filename(DIR_NEXT);
break;
-#ifdef JPEG_PREVIOUS_REPEAT
- case JPEG_PREVIOUS_REPEAT:
+#ifdef IMGVIEW_PREVIOUS_REPEAT
+ case IMGVIEW_PREVIOUS_REPEAT:
#endif
- case JPEG_PREVIOUS:
+ case IMGVIEW_PREVIOUS:
if (entries > 1)
return change_filename(DIR_PREV);
break;
- case JPEG_ZOOM_IN:
-#ifdef JPEG_ZOOM_PRE
- if (lastbutton != JPEG_ZOOM_PRE)
+ case IMGVIEW_ZOOM_IN:
+#ifdef IMGVIEW_ZOOM_PRE
+ if (lastbutton != IMGVIEW_ZOOM_PRE)
break;
#endif
return ZOOM_IN;
break;
- case JPEG_ZOOM_OUT:
-#ifdef JPEG_ZOOM_PRE
- if (lastbutton != JPEG_ZOOM_PRE)
+ case IMGVIEW_ZOOM_OUT:
+#ifdef IMGVIEW_ZOOM_PRE
+ if (lastbutton != IMGVIEW_ZOOM_PRE)
break;
#endif
return ZOOM_OUT;
break;
-#ifdef JPEG_RC_MENU
- case JPEG_RC_MENU:
+#ifdef IMGVIEW_RC_MENU
+ case IMGVIEW_RC_MENU:
#endif
- case JPEG_MENU:
+ case IMGVIEW_MENU:
#ifdef USEGSLIB
grey_show(false); /* switch off greyscale overlay */
#endif
@@ -652,8 +552,8 @@ int scroll_bmp(struct t_disp* pdisp)
#ifdef USEGSLIB
grey_show(true); /* switch on greyscale overlay */
#else
- draw_image_rect(pdisp, 0, 0,
- pdisp->width-pdisp->x, pdisp->height-pdisp->y);
+ draw_image_rect(info, 0, 0,
+ info->width-info->x, info->height-info->y);
MYLCD_UPDATE();
#endif
break;
@@ -672,7 +572,7 @@ int scroll_bmp(struct t_disp* pdisp)
/********************* main function *************************/
-/* callback updating a progress meter while JPEG decoding */
+/* callback updating a progress meter while image decoding */
void cb_progress(int current, int total)
{
rb->yield(); /* be nice to the other threads */
@@ -695,45 +595,27 @@ void cb_progress(int current, int total)
#endif
}
-int jpegmem(struct jpeg *p_jpg, int ds)
-{
- int size;
-
- size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
- * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
-#ifdef HAVE_LCD_COLOR
- if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
- {
- size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
- * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
- size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
- * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
- }
-#endif
- return size;
-}
-
/* how far can we zoom in without running out of memory */
-int min_downscale(struct jpeg *p_jpg, int bufsize)
+static int min_downscale(int bufsize)
{
int downscale = 8;
- if (jpegmem(p_jpg, 8) > bufsize)
+ if (img_mem(8) > bufsize)
return 0; /* error, too large, even 1:8 doesn't fit */
- while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
+ while (downscale > 1 && img_mem(downscale/2) <= bufsize)
downscale /= 2;
return downscale;
}
/* how far can we zoom out, to fit image into the LCD */
-int max_downscale(struct jpeg *p_jpg)
+static int max_downscale(struct image_info *info)
{
int downscale = 1;
- while (downscale < 8 && (p_jpg->x_size/downscale > LCD_WIDTH
- || p_jpg->y_size/downscale > LCD_HEIGHT))
+ while (downscale < 8 && (info->x_size/downscale > LCD_WIDTH
+ || info->y_size/downscale > LCD_HEIGHT))
{
downscale *= 2;
}
@@ -741,218 +623,40 @@ int max_downscale(struct jpeg *p_jpg)
return downscale;
}
-/* load image from filename. */
-int load_image(char* filename, struct jpeg *p_jpg)
-{
- int fd;
- int filesize;
- unsigned char* buf_jpeg; /* compressed JPEG image */
- int status;
-
- fd = rb->open(filename, O_RDONLY);
- if (fd < 0)
- {
- rb->splashf(HZ, "err opening %s:%d", filename, fd);
- return PLUGIN_ERROR;
- }
- filesize = rb->filesize(fd);
-
- /* allocate JPEG buffer */
- buf_jpeg = buf;
-
- /* we can start the decompressed images behind it */
- buf_images = buf_root = buf + filesize;
- buf_images_size = root_size = buf_size - filesize;
-
- if (buf_images_size <= 0)
- {
- rb->close(fd);
- return PLUGIN_OUTOFMEM;
- }
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
- rb->lcd_puts(0, 0, print);
- rb->lcd_update();
-
- rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
- rb->lcd_puts(0, 1, print);
- rb->lcd_update();
- }
-
- rb->read(fd, buf_jpeg, filesize);
- rb->close(fd);
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "decoding markers");
- rb->lcd_puts(0, 2, print);
- rb->lcd_update();
- }
-#ifndef SIMULATOR
- else if(immediate_ata_off)
- {
- /* running slideshow and time is long enough: power down disk */
- rb->storage_sleep();
- }
-#endif
-
- /* process markers, unstuffing */
- status = process_markers(buf_jpeg, filesize, p_jpg);
-
- if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
- { /* bad format or minimum components not contained */
- rb->splashf(HZ, "unsupported %d", status);
- return PLUGIN_ERROR;
- }
-
- if (!(status & DHT)) /* if no Huffman table present: */
- default_huff_tbl(p_jpg); /* use default */
- build_lut(p_jpg); /* derive Huffman and other lookup-tables */
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "image %dx%d",
- p_jpg->x_size, p_jpg->y_size);
- rb->lcd_puts(0, 2, print);
- rb->lcd_update();
- }
-
- return PLUGIN_OK;
-}
-
-/* return decoded or cached image */
-struct t_disp* get_image(struct jpeg* p_jpg, int ds)
-{
- int w, h; /* used to center output */
- int size; /* decompressed image size */
- long time; /* measured ticks */
- int status;
-
- struct t_disp* p_disp = &disp[ds]; /* short cut */
-
- if (p_disp->bitmap[0] != NULL)
- {
- return p_disp; /* we still have it */
- }
-
- /* assign image buffer */
-
- /* physical size needed for decoding */
- size = jpegmem(p_jpg, ds);
- if (buf_images_size <= size)
- { /* have to discard the current */
- int i;
- for (i=1; i<=8; i++)
- disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
- buf_images = buf_root; /* start again from the beginning of the buffer */
- buf_images_size = root_size;
- }
-
-#ifdef HAVE_LCD_COLOR
- if (p_jpg->blocks > 1) /* colour jpeg */
- {
- int i;
-
- for (i = 1; i < 3; i++)
- {
- size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
- * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
- p_disp->bitmap[i] = buf_images;
- buf_images += size;
- buf_images_size -= size;
- }
- p_disp->csub_x = p_jpg->subsample_x[1];
- p_disp->csub_y = p_jpg->subsample_y[1];
- }
- else
- {
- p_disp->csub_x = p_disp->csub_y = 0;
- p_disp->bitmap[1] = p_disp->bitmap[2] = buf_images;
- }
-#endif
- /* size may be less when decoded (if height is not block aligned) */
- size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
- p_disp->bitmap[0] = buf_images;
- buf_images += size;
- buf_images_size -= size;
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "decoding %d*%d",
- p_jpg->x_size/ds, p_jpg->y_size/ds);
- rb->lcd_puts(0, 3, print);
- rb->lcd_update();
- }
-
- /* update image properties */
- p_disp->width = p_jpg->x_size / ds;
- p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
- p_disp->height = p_jpg->y_size / ds;
-
- /* the actual decoding */
- time = *rb->current_tick;
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(true);
- status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
- rb->cpu_boost(false);
-#else
- status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
-#endif
- if (status)
- {
- rb->splashf(HZ, "decode error %d", status);
- return NULL;
- }
- time = *rb->current_tick - time;
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
- rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
- rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
- rb->lcd_update();
- }
-
- return p_disp;
-}
-
-
/* set the view to the given center point, limit if necessary */
-void set_view (struct t_disp* p_disp, int cx, int cy)
+static void set_view(struct image_info *info, int cx, int cy)
{
int x, y;
/* plain center to available width/height */
- x = cx - MIN(LCD_WIDTH, p_disp->width) / 2;
- y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2;
+ x = cx - MIN(LCD_WIDTH, info->width) / 2;
+ y = cy - MIN(LCD_HEIGHT, info->height) / 2;
/* limit against upper image size */
- x = MIN(p_disp->width - LCD_WIDTH, x);
- y = MIN(p_disp->height - LCD_HEIGHT, y);
+ x = MIN(info->width - LCD_WIDTH, x);
+ y = MIN(info->height - LCD_HEIGHT, y);
/* limit against negative side */
x = MAX(0, x);
y = MAX(0, y);
- p_disp->x = x; /* set the values */
- p_disp->y = y;
+ info->x = x; /* set the values */
+ info->y = y;
}
/* calculate the view center based on the bitmap position */
-void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
+static void get_view(struct image_info *info, int *p_cx, int *p_cy)
{
- *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2;
- *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
+ *p_cx = info->x + MIN(LCD_WIDTH, info->width) / 2;
+ *p_cy = info->y + MIN(LCD_HEIGHT, info->height) / 2;
}
/* load, decode, display the image */
-int load_and_show(char* filename)
+static int load_and_show(char* filename, struct image_info *info)
{
int status;
- struct t_disp* p_disp; /* currenly displayed image */
- int cx, cy; /* view center */
+ int cx, cy;
+ ssize_t remaining;
#if LCD_DEPTH > 1
rb->lcd_set_foreground(LCD_WHITE);
@@ -961,13 +665,13 @@ int load_and_show(char* filename)
#endif
rb->lcd_clear_display();
- rb->memset(&disp, 0, sizeof(disp));
- rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
+ rb->memset(info, 0, sizeof(*info));
+ remaining = buf_size;
- if (rb->button_get(false) == JPEG_MENU)
+ if (rb->button_get(false) == IMGVIEW_MENU)
status = PLUGIN_ABORT;
else
- status = load_image(filename, &jpg);
+ status = load_image(filename, info, buf, &remaining);
if (status == PLUGIN_OUTOFMEM)
{
@@ -993,18 +697,18 @@ int load_and_show(char* filename)
int button = rb->button_get(true);
switch(button)
{
- case JPEG_ZOOM_IN:
+ case IMGVIEW_ZOOM_IN:
plug_buf = false;
buf = rb->plugin_get_audio_buffer((size_t *)&buf_size);
/*try again this file, now using the audio buffer */
return PLUGIN_OTHER;
-#ifdef JPEG_RC_MENU
- case JPEG_RC_MENU:
+#ifdef IMGVIEW_RC_MENU
+ case IMGVIEW_RC_MENU:
#endif
- case JPEG_MENU:
+ case IMGVIEW_MENU:
return PLUGIN_OK;
- case JPEG_LEFT:
+ case IMGVIEW_LEFT:
if(entries>1)
{
rb->lcd_clear_display();
@@ -1012,7 +716,7 @@ int load_and_show(char* filename)
}
break;
- case JPEG_RIGHT:
+ case IMGVIEW_RIGHT:
if(entries>1)
{
rb->lcd_clear_display();
@@ -1045,43 +749,49 @@ int load_and_show(char* filename)
return PLUGIN_OK;
}
- ds_max = max_downscale(&jpg); /* check display constraint */
- ds_min = min_downscale(&jpg, buf_images_size); /* check memory constraint */
+ ds_max = max_downscale(info); /* check display constraint */
+ ds_min = min_downscale(remaining); /* check memory constraint */
if (ds_min == 0)
{
+#if UNSCALED_IS_AVAILABLE
+ /* Can not resize the image but original one is available, so use it. */
+ ds_min = ds_max = 1;
+#else
+ /* not enough memory to decode image. */
rb->splash(HZ, "too large");
file_pt[curfile] = NULL;
return change_filename(direction);
+#endif
}
else if (ds_max < ds_min)
ds_max = ds_min;
ds = ds_max; /* initialize setting */
- cx = jpg.x_size/ds/2; /* center the view */
- cy = jpg.y_size/ds/2;
+ cx = info->x_size/ds/2; /* center the view */
+ cy = info->y_size/ds/2;
do /* loop the image prepare and decoding when zoomed */
{
- p_disp = get_image(&jpg, ds); /* decode or fetch from cache */
- if (p_disp == NULL)
+ status = get_image(info, ds); /* decode or fetch from cache */
+ if (status == PLUGIN_ERROR)
{
file_pt[curfile] = NULL;
return change_filename(direction);
}
- set_view(p_disp, cx, cy);
+ set_view(info, cx, cy);
if(!running_slideshow)
{
rb->snprintf(print, sizeof(print), "showing %dx%d",
- p_disp->width, p_disp->height);
+ info->width, info->height);
rb->lcd_puts(0, 3, print);
rb->lcd_update();
}
MYLCD(clear_display)();
- draw_image_rect(p_disp, 0, 0,
- p_disp->width-p_disp->x, p_disp->height-p_disp->y);
+ draw_image_rect(info, 0, 0,
+ info->width-info->x, info->height-info->y);
MYLCD_UPDATE();
#ifdef USEGSLIB
@@ -1093,15 +803,25 @@ int load_and_show(char* filename)
*/
while (1)
{
- status = scroll_bmp(p_disp);
+ status = scroll_bmp(info);
if (status == ZOOM_IN)
{
+#if UNSCALED_IS_AVAILABLE
+ if (ds > 1)
+#else
if (ds > ds_min)
+#endif
{
- ds /= 2; /* reduce downscaling to zoom in */
- get_view(p_disp, &cx, &cy);
- cx *= 2; /* prepare the position in the new image */
- cy *= 2;
+#if UNSCALED_IS_AVAILABLE
+ /* if 1/1 is always available, jump ds from ds_min to 1. */
+ int zoom = (ds == ds_min)? ds_min: 2;
+#else
+ const int zoom = 2;
+#endif
+ ds /= zoom; /* reduce downscaling to zoom in */
+ get_view(info, &cx, &cy);
+ cx *= zoom; /* prepare the position in the new image */
+ cy *= zoom;
}
else
continue;
@@ -1111,10 +831,16 @@ int load_and_show(char* filename)
{
if (ds < ds_max)
{
- ds *= 2; /* increase downscaling to zoom out */
- get_view(p_disp, &cx, &cy);
- cx /= 2; /* prepare the position in the new image */
- cy /= 2;
+#if UNSCALED_IS_AVAILABLE
+ /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */
+ int zoom = (ds < ds_min)? ds_min: 2;
+#else
+ const int zoom = 2;
+#endif
+ ds *= zoom; /* increase downscaling to zoom out */
+ get_view(info, &cx, &cy);
+ cx /= zoom; /* prepare the position in the new image */
+ cy /= zoom;
}
else
continue;
@@ -1160,7 +886,7 @@ enum plugin_status plugin_start(const void* parameter)
if(!entries) return PLUGIN_ERROR;
-#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
+#if PLUGIN_BUFFER_SIZE >= MIN_MEM
if(!rb->audio_status())
{
plug_buf = false;
@@ -1181,28 +907,28 @@ enum plugin_status plugin_start(const void* parameter)
/* should be ok to just load settings since the plugin itself has
just been loaded from disk and the drive should be spinning */
- configfile_load(JPEG_CONFIGFILE, jpeg_config,
- ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION);
- old_settings = jpeg_settings;
+ configfile_load(IMGVIEW_CONFIGFILE, config,
+ ARRAYLEN(config), IMGVIEW_SETTINGS_MINVERSION);
+ rb->memcpy(&old_settings, &settings, sizeof (settings));
/* Turn off backlight timeout */
backlight_force_on(); /* backlight control in lib/helper.c */
do
{
- condition = load_and_show(np_file);
+ condition = load_and_show(np_file, &image_info);
} while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
&& condition != PLUGIN_ERROR);
- if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
+ if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
{
/* Just in case drive has to spin, keep it from looking locked */
rb->splash(0, "Saving Settings");
- configfile_save(JPEG_CONFIGFILE, jpeg_config,
- ARRAYLEN(jpeg_config), JPEG_SETTINGS_VERSION);
+ configfile_save(IMGVIEW_CONFIGFILE, config,
+ ARRAYLEN(config), IMGVIEW_SETTINGS_VERSION);
}
-#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
+#ifdef DISK_SPINDOWN
/* set back ata spindown time in case we changed it */
rb->storage_spindown(rb->global_settings->disk_spindown);
#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * user intereface of image viewers (jpeg, png, etc.)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _IMGVIEW_IMGVIEW_H
+#define _IMGVIEW_IMGVIEW_H
+
+#include "plugin.h"
+
+/* variable button definitions */
+#if CONFIG_KEYPAD == RECORDER_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_PLAY
+#define IMGVIEW_ZOOM_OUT BUTTON_ON
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_F3
+#define IMGVIEW_PREVIOUS BUTTON_F2
+#define IMGVIEW_MENU BUTTON_OFF
+
+#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_SELECT
+#define IMGVIEW_ZOOM_OUT BUTTON_ON
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_F3
+#define IMGVIEW_PREVIOUS BUTTON_F2
+#define IMGVIEW_MENU BUTTON_OFF
+
+#elif CONFIG_KEYPAD == ONDIO_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_MENU
+#define IMGVIEW_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT (BUTTON_MENU | BUTTON_RIGHT)
+#define IMGVIEW_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
+#define IMGVIEW_MENU BUTTON_OFF
+
+#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
+ (CONFIG_KEYPAD == IRIVER_H300_PAD)
+#define IMGVIEW_ZOOM_IN BUTTON_SELECT
+#define IMGVIEW_ZOOM_OUT BUTTON_MODE
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
+#define IMGVIEW_NEXT BUTTON_ON
+#define IMGVIEW_PREVIOUS BUTTON_REC
+#else
+#define IMGVIEW_NEXT BUTTON_REC
+#define IMGVIEW_PREVIOUS BUTTON_ON
+#endif
+#define IMGVIEW_MENU BUTTON_OFF
+#define IMGVIEW_RC_MENU BUTTON_RC_STOP
+
+#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
+ (CONFIG_KEYPAD == IPOD_1G2G_PAD)
+#define IMGVIEW_ZOOM_IN BUTTON_SCROLL_FWD
+#define IMGVIEW_ZOOM_OUT BUTTON_SCROLL_BACK
+#define IMGVIEW_UP BUTTON_MENU
+#define IMGVIEW_DOWN BUTTON_PLAY
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
+#define IMGVIEW_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
+#define IMGVIEW_MENU (BUTTON_SELECT | BUTTON_MENU)
+
+#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_PLAY
+#define IMGVIEW_PREVIOUS BUTTON_REC
+#define IMGVIEW_MENU BUTTON_POWER
+
+#elif CONFIG_KEYPAD == GIGABEAT_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
+#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT (BUTTON_A | BUTTON_RIGHT)
+#define IMGVIEW_PREVIOUS (BUTTON_A | BUTTON_LEFT)
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == SANSA_E200_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_SCROLL_FWD
+#define IMGVIEW_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
+#define IMGVIEW_PREVIOUS BUTTON_SCROLL_BACK
+#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
+#define IMGVIEW_MENU BUTTON_POWER
+#define IMGVIEW_SLIDE_SHOW BUTTON_REC
+
+#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_SCROLL_FWD
+#define IMGVIEW_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
+#define IMGVIEW_PREVIOUS BUTTON_SCROLL_BACK
+#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
+#define IMGVIEW_MENU (BUTTON_HOME|BUTTON_REPEAT)
+
+#elif CONFIG_KEYPAD == SANSA_C200_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_VOL_UP
+#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
+#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
+#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
+#define IMGVIEW_MENU BUTTON_POWER
+#define IMGVIEW_SLIDE_SHOW BUTTON_REC
+
+#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_VOL_UP
+#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
+#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
+#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
+#define IMGVIEW_MENU BUTTON_POWER
+#define IMGVIEW_SLIDE_SHOW BUTTON_HOME
+
+#elif CONFIG_KEYPAD == SANSA_M200_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_SELECT
+#define IMGVIEW_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_VOL_UP
+#define IMGVIEW_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
+#define IMGVIEW_PREVIOUS BUTTON_VOL_DOWN
+#define IMGVIEW_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
+#define IMGVIEW_MENU BUTTON_POWER
+#define IMGVIEW_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
+
+#elif CONFIG_KEYPAD == IRIVER_H10_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_PLAY
+#define IMGVIEW_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_SCROLL_UP
+#define IMGVIEW_DOWN BUTTON_SCROLL_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_FF
+#define IMGVIEW_PREVIOUS BUTTON_REW
+#define IMGVIEW_MENU BUTTON_POWER
+
+#elif CONFIG_KEYPAD == MROBE500_PAD
+#define IMGVIEW_MENU BUTTON_POWER
+
+#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
+#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_NEXT
+#define IMGVIEW_PREVIOUS BUTTON_PREV
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == MROBE100_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_SELECT
+#define IMGVIEW_ZOOM_OUT BUTTON_PLAY
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
+#define IMGVIEW_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
+#define IMGVIEW_ZOOM_PRE BUTTON_RC_PLAY
+#define IMGVIEW_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
+#define IMGVIEW_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
+#define IMGVIEW_UP BUTTON_RC_VOL_UP
+#define IMGVIEW_DOWN BUTTON_RC_VOL_DOWN
+#define IMGVIEW_LEFT BUTTON_RC_REW
+#define IMGVIEW_RIGHT BUTTON_RC_FF
+#define IMGVIEW_NEXT BUTTON_RC_MODE
+#define IMGVIEW_PREVIOUS BUTTON_RC_MENU
+#define IMGVIEW_MENU BUTTON_RC_REC
+
+#elif CONFIG_KEYPAD == COWON_D2_PAD
+
+#elif CONFIG_KEYPAD == IAUDIO67_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_VOLUP
+#define IMGVIEW_ZOOM_OUT BUTTON_VOLDOWN
+#define IMGVIEW_UP BUTTON_STOP
+#define IMGVIEW_DOWN BUTTON_PLAY
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
+#define IMGVIEW_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
+
+#define IMGVIEW_ZOOM_IN BUTTON_PLAY
+#define IMGVIEW_ZOOM_OUT BUTTON_CUSTOM
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_SELECT
+#define IMGVIEW_PREVIOUS BUTTON_BACK
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
+#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_VIEW
+#define IMGVIEW_PREVIOUS BUTTON_PLAYLIST
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
+#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
+#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_PREV
+#define IMGVIEW_RIGHT BUTTON_NEXT
+#define IMGVIEW_NEXT BUTTON_RIGHT
+#define IMGVIEW_PREVIOUS BUTTON_LEFT
+#define IMGVIEW_MENU BUTTON_MENU
+
+#elif CONFIG_KEYPAD == ONDAVX747_PAD
+#elif CONFIG_KEYPAD == ONDAVX777_PAD
+
+#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
+#define IMGVIEW_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
+#define IMGVIEW_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
+#define IMGVIEW_UP BUTTON_UP
+#define IMGVIEW_DOWN BUTTON_DOWN
+#define IMGVIEW_LEFT BUTTON_LEFT
+#define IMGVIEW_RIGHT BUTTON_RIGHT
+#define IMGVIEW_NEXT BUTTON_FFWD
+#define IMGVIEW_PREVIOUS BUTTON_REW
+#define IMGVIEW_MENU BUTTON_PLAY
+
+#else
+#error No keymap defined!
+#endif
+
+#ifdef HAVE_TOUCHSCREEN
+#ifndef IMGVIEW_UP
+#define IMGVIEW_UP BUTTON_TOPMIDDLE
+#endif
+#ifndef IMGVIEW_DOWN
+#define IMGVIEW_DOWN BUTTON_BOTTOMMIDDLE
+#endif
+#ifndef IMGVIEW_LEFT
+#define IMGVIEW_LEFT BUTTON_MIDLEFT
+#endif
+#ifndef IMGVIEW_RIGHT
+#define IMGVIEW_RIGHT BUTTON_MIDRIGHT
+#endif
+#ifndef IMGVIEW_ZOOM_IN
+#define IMGVIEW_ZOOM_IN BUTTON_TOPRIGHT
+#endif
+#ifndef IMGVIEW_ZOOM_OUT
+#define IMGVIEW_ZOOM_OUT BUTTON_TOPLEFT
+#endif
+#ifndef IMGVIEW_MENU
+#define IMGVIEW_MENU (BUTTON_CENTER|BUTTON_REL)
+#endif
+#ifndef IMGVIEW_NEXT
+#define IMGVIEW_NEXT BUTTON_BOTTOMRIGHT
+#endif
+#ifndef IMGVIEW_PREVIOUS
+#define IMGVIEW_PREVIOUS BUTTON_BOTTOMLEFT
+#endif
+#endif
+
+/* different graphics libraries */
+#if LCD_DEPTH < 8
+#define USEGSLIB
+#include <lib/grey.h>
+#define MYLCD(fn) grey_ub_ ## fn
+#define MYLCD_UPDATE()
+#define MYXLCD(fn) grey_ub_ ## fn
+#else
+#include <lib/xlcd.h>
+#define MYLCD(fn) rb->lcd_ ## fn
+#define MYLCD_UPDATE() rb->lcd_update();
+#define MYXLCD(fn) xlcd_ ## fn
+#endif
+
+/* Min memory allowing us to use the plugin buffer
+ * and thus not stopping the music
+ * *Very* rough estimation:
+ * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
+ * + 30k code size = 70 000
+ * + 50k min for image = 120 000
+ */
+#define MIN_MEM 120000
+
+/* State code for output with return. */
+#define PLUGIN_OTHER 10
+#define PLUGIN_ABORT 11
+#define PLUGIN_OUTOFMEM 12
+
+#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
+#define DISK_SPINDOWN
+#endif
+
+/* Settings. jpeg needs these */
+struct imgview_settings
+{
+ /* include all settings for varias decoders as using same setting file. */
+#ifdef HAVE_LCD_COLOR
+ int jpeg_colour_mode;
+ int jpeg_dither_mode;
+#endif
+ int ss_timeout;
+};
+
+/* structure passed to decoder. */
+struct image_info {
+ int x_size, y_size; /* set size of loaded image in load_image(). */
+ int width, height; /* set size of resized image in get_image(). */
+ int x, y; /* display position */
+ void *data; /* use freely in decoder. not touched in ui. */
+};
+
+/* callback updating a progress meter while image decoding */
+extern void cb_progress(int current, int total);
+
+extern struct imgview_settings settings;
+extern bool slideshow_enabled;
+extern bool running_slideshow;
+#ifdef DISK_SPINDOWN
+extern bool immediate_ata_off;
+#endif
+#if PLUGIN_BUFFER_SIZE >= MIN_MEM
+extern bool plug_buf;
+#endif
+
+/* functions needed to be implemented in each image decoders. */
+/* return true if ext is supported by the decoder. */
+extern bool img_ext(const char *ext);
+/* return needed size of buffer to store downscaled image by ds */
+extern int img_mem(int ds);
+/* load image from filename. set width and height of info properly. alos, set
+ * buf_size to remaining size of buf after load image. it is used to caluclate
+ * min downscale. */
+extern int load_image(char *filename, struct image_info *info,
+ unsigned char *buf, ssize_t *buf_size);
+/* downscale loaded image by ds. note that buf to store reszied image is not
+ * provided. return PLUGIN_ERROR for error. ui will skip to next image. */
+extern int get_image(struct image_info *info, int ds);
+/* draw part of image */
+extern void draw_image_rect(struct image_info *info,
+ int x, int y, int width, int height);
+
+#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 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+IMGVSRCDIR := $(APPSDIR)/plugins/imageviewer
+IMGVBUILDDIR := $(BUILDDIR)/apps/plugins/imageviewer
+
+# include actual viewer's make file
+IMGVSUBDIRS := $(call preprocess, $(IMGVSRCDIR)/SUBDIRS)
+$(foreach dir,$(IMGVSUBDIRS),$(eval include $(dir)/$(notdir $(dir)).make))
+
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 @@
+jpeg_ui.c
jpeg.c
jpeg_decoder.c
#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 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* JPEG image viewer
+* (This is a real mess if it has to be coded in one single C file)
+*
+* File scrolling addition (C) 2005 Alexander Spyridakis
+* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
+* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
+* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "plugin.h"
+
+#include "../imageviewer.h"
+#include "jpeg_decoder.h"
+
+#ifdef HAVE_LCD_COLOR
+#include "yuv2rgb.h"
+#endif
+
+/**************** begin Application ********************/
+
+/************************* Types ***************************/
+
+struct t_disp
+{
+#ifdef HAVE_LCD_COLOR
+ unsigned char* bitmap[3]; /* Y, Cr, Cb */
+ int csub_x, csub_y;
+#else
+ unsigned char* bitmap[1]; /* Y only */
+#endif
+ int stride;
+};
+
+/************************* Globals ***************************/
+
+/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
+static struct t_disp disp[9];
+
+/* my memory pool (from the mp3 buffer) */
+static char print[32]; /* use a common snprintf() buffer */
+
+/* the root of the images, hereafter are decompresed ones */
+static unsigned char* buf_root;
+static int root_size;
+
+/* up to here currently used by image(s) */
+static unsigned char* buf_images;
+static ssize_t buf_images_size;
+
+static struct jpeg jpg; /* too large for stack */
+
+/************************* Implementation ***************************/
+
+bool img_ext(const char *ext)
+{
+ if(!ext)
+ return false;
+ if(!rb->strcasecmp(ext,".jpg") ||
+ !rb->strcasecmp(ext,".jpe") ||
+ !rb->strcasecmp(ext,".jpeg"))
+ return true;
+ else
+ return false;
+}
+
+void draw_image_rect(struct image_info *info,
+ int x, int y, int width, int height)
+{
+ struct t_disp* pdisp = (struct t_disp*)info->data;
+#ifdef HAVE_LCD_COLOR
+ yuv_bitmap_part(
+ pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
+ info->x + x, info->y + y, pdisp->stride,
+ x + MAX(0, (LCD_WIDTH - info->width) / 2),
+ y + MAX(0, (LCD_HEIGHT - info->height) / 2),
+ width, height,
+ settings.jpeg_colour_mode, settings.jpeg_dither_mode);
+#else
+ MYXLCD(gray_bitmap_part)(
+ pdisp->bitmap[0], info->x + x, info->y + y, pdisp->stride,
+ x + MAX(0, (LCD_WIDTH-info->width)/2),
+ y + MAX(0, (LCD_HEIGHT-info->height)/2),
+ width, height);
+#endif
+}
+
+int img_mem(int ds)
+{
+ int size;
+ struct jpeg *p_jpg = &jpg;
+
+ size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
+ * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
+#ifdef HAVE_LCD_COLOR
+ if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
+ {
+ size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
+ * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
+ size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
+ * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
+ }
+#endif
+ return size;
+}
+
+int load_image(char *filename, struct image_info *info,
+ unsigned char *buf, ssize_t *buf_size)
+{
+ int fd;
+ int filesize;
+ unsigned char* buf_jpeg; /* compressed JPEG image */
+ int status;
+ struct jpeg *p_jpg = &jpg;
+
+ rb->memset(&disp, 0, sizeof(disp));
+ rb->memset(&jpg, 0, sizeof(jpg));
+
+ fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ {
+ rb->splashf(HZ, "err opening %s:%d", filename, fd);
+ return PLUGIN_ERROR;
+ }
+ filesize = rb->filesize(fd);
+
+ /* allocate JPEG buffer */
+ buf_jpeg = buf;
+
+ /* we can start the decompressed images behind it */
+ buf_images = buf_root = buf + filesize;
+ buf_images_size = root_size = *buf_size - filesize;
+
+ if (buf_images_size <= 0)
+ {
+ rb->close(fd);
+ return PLUGIN_OUTOFMEM;
+ }
+
+ if(!running_slideshow)
+ {
+ rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
+ rb->lcd_puts(0, 0, print);
+ rb->lcd_update();
+
+ rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
+ rb->lcd_puts(0, 1, print);
+ rb->lcd_update();
+ }
+
+ rb->read(fd, buf_jpeg, filesize);
+ rb->close(fd);
+
+ if(!running_slideshow)
+ {
+ rb->snprintf(print, sizeof(print), "decoding markers");
+ rb->lcd_puts(0, 2, print);
+ rb->lcd_update();
+ }
+#ifdef DISK_SPINDOWN
+ else if(immediate_ata_off)
+ {
+ /* running slideshow and time is long enough: power down disk */
+ rb->storage_sleep();
+ }
+#endif
+
+ /* process markers, unstuffing */
+ status = process_markers(buf_jpeg, filesize, p_jpg);
+
+ if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
+ { /* bad format or minimum components not contained */
+ rb->splashf(HZ, "unsupported %d", status);
+ return PLUGIN_ERROR;
+ }
+
+ if (!(status & DHT)) /* if no Huffman table present: */
+ default_huff_tbl(p_jpg); /* use default */
+ build_lut(p_jpg); /* derive Huffman and other lookup-tables */
+
+ if(!running_slideshow)
+ {
+ rb->snprintf(print, sizeof(print), "image %dx%d",
+ p_jpg->x_size, p_jpg->y_size);
+ rb->lcd_puts(0, 2, print);
+ rb->lcd_update();
+ }
+
+ info->x_size = p_jpg->x_size;
+ info->y_size = p_jpg->y_size;
+ *buf_size = buf_images_size;
+ return PLUGIN_OK;
+}
+
+int get_image(struct image_info *info, int ds)
+{
+ int w, h; /* used to center output */
+ int size; /* decompressed image size */
+ long time; /* measured ticks */
+ int status;
+ struct jpeg* p_jpg = &jpg;
+ struct t_disp* p_disp = &disp[ds]; /* short cut */
+
+ info->width = p_jpg->x_size / ds;
+ info->height = p_jpg->y_size / ds;
+ info->data = p_disp;
+
+ if (p_disp->bitmap[0] != NULL)
+ {
+ /* we still have it */
+ return PLUGIN_OK;
+ }
+
+ /* assign image buffer */
+
+ /* physical size needed for decoding */
+ size = img_mem(ds);
+ if (buf_images_size <= size)
+ { /* have to discard the current */
+ int i;
+ for (i=1; i<=8; i++)
+ disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
+ buf_images = buf_root; /* start again from the beginning of the buffer */
+ buf_images_size = root_size;
+ }
+
+#ifdef HAVE_LCD_COLOR
+ if (p_jpg->blocks > 1) /* colour jpeg */
+ {
+ int i;
+
+ for (i = 1; i < 3; i++)
+ {
+ size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
+ * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
+ p_disp->bitmap[i] = buf_images;
+ buf_images += size;
+ buf_images_size -= size;
+ }
+ p_disp->csub_x = p_jpg->subsample_x[1];
+ p_disp->csub_y = p_jpg->subsample_y[1];
+ }
+ else
+ {
+ p_disp->csub_x = p_disp->csub_y = 0;
+ p_disp->bitmap[1] = p_disp->bitmap[2] = buf_images;
+ }
+#endif
+ /* size may be less when decoded (if height is not block aligned) */
+ size = (p_jpg->x_phys/ds) * (p_jpg->y_size/ds);
+ p_disp->bitmap[0] = buf_images;
+ buf_images += size;
+ buf_images_size -= size;
+
+ if(!running_slideshow)
+ {
+ rb->snprintf(print, sizeof(print), "decoding %d*%d",
+ p_jpg->x_size/ds, p_jpg->y_size/ds);
+ rb->lcd_puts(0, 3, print);
+ rb->lcd_update();
+ }
+
+ /* update image properties */
+ p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
+
+ /* the actual decoding */
+ time = *rb->current_tick;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+ status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
+ rb->cpu_boost(false);
+#else
+ status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progress);
+#endif
+ if (status)
+ {
+ rb->splashf(HZ, "decode error %d", status);
+ return PLUGIN_ERROR;
+ }
+ time = *rb->current_tick - time;
+
+ if(!running_slideshow)
+ {
+ rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
+ rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */
+ rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print);
+ rb->lcd_update();
+ }
+
+ return PLUGIN_OK;
+}
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 @@
# $Id$
#
-JPEGSRCDIR := $(APPSDIR)/plugins/jpeg
-JPEGBUILDDIR := $(BUILDDIR)/apps/plugins/jpeg
+JPEGSRCDIR := $(IMGVSRCDIR)/jpeg
+JPEGBUILDDIR := $(IMGVBUILDDIR)/jpeg
ROCKS += $(JPEGBUILDDIR)/jpeg.rock
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 @@
+#define JPEG_VIEWER
+#define MENU_TITLE "Jpeg Menu"
+#define UNSCALED_IS_AVAILABLE 0
+
+#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
inflate.c
inftrees.c
png.c
+png_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;
will return Z_BUF_ERROR if it has not reached the end of the stream.
*/
-extern void cb_progress(int current, int total);
-
int ZEXPORT inflate(strm, flush)
z_streamp strm;
int flush;
@@ -1132,7 +1130,7 @@ int flush;
return Z_STREAM_ERROR;
}
//DEBUGF("%d / %d\n", strm->total_in, strm->avail_in);
- if (rb->button_get(false) == PNG_MENU)
+ if (rb->button_get(false) == IMGVIEW_MENU)
return PLUGIN_ABORT;
else cb_progress(insize - strm->avail_in, insize);
}
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.
#include "plugin.h"
#include "lcd.h"
-#include <lib/playback_control.h>
-#include <lib/helper.h>
-#include <lib/configfile.h>
-#include <lib/grey.h>
#include <lib/pluginlib_bmp.h>
#include "zlib.h"
#include "png.h"
-PLUGIN_HEADER
-
/* ////////////////////////////////////////////////////////////////////////// */
/* LodeFlate & LodeZlib Setting structs */
/* ////////////////////////////////////////////////////////////////////////// */
@@ -140,26 +134,10 @@ typedef struct LodePNG_Decoder
LodePNG_InfoPng infoPng; /*info of the PNG image obtained after decoding*/
long error;
char error_msg[128];
- int x,y;
- int width,height;
} LodePNG_Decoder;
#define VERSION_STRING "20080927"
-/* Min memory allowing us to use the plugin buffer
- * and thus not stopping the music
- * *Very* rough estimation:
- * Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
- * + 30k code size = 70 000
- * + 50k min for png = 130 000
- */
-#define MIN_MEM 130000
-
-/* Headings */
-#define DIR_PREV 1
-#define DIR_NEXT -1
-#define DIR_NONE 0
-
/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
static fb_data *disp[9];
/* up to here currently used by image(s) */
@@ -180,62 +158,7 @@ static size_t converted_image_size;
static unsigned char *decoded_image; /* the decoded image */
static size_t decoded_image_size;
-static fb_data *resized_image; /* the decoded image */
-
-static struct tree_context *tree;
-
-/* the current full file name */
-static char np_file[MAX_PATH];
-static int curfile = 0, direction = DIR_NONE, entries = 0;
-
-static LodePNG_Decoder decoder;
-
-/* list of the png files */
-static char **file_pt;
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
-/* are we using the plugin buffer or the audio buffer? */
-static bool plug_buf = true;
-#endif
-
-/* Persistent configuration */
-#define PNG_CONFIGFILE "png.cfg"
-#define PNG_SETTINGS_MINVERSION 1
-#define PNG_SETTINGS_VERSION 1
-
-/* Slideshow times */
-#define SS_MIN_TIMEOUT 1
-#define SS_MAX_TIMEOUT 20
-#define SS_DEFAULT_TIMEOUT 5
-
-struct png_settings
-{
- int ss_timeout;
-};
-
-static struct png_settings png_settings =
- {
- SS_DEFAULT_TIMEOUT
- };
-static struct png_settings old_settings;
-
-static struct configdata png_config[] =
- {
- { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT,
- { .int_p = &png_settings.ss_timeout }, "Slideshow Time", NULL
- },
- };
-
-#if LCD_DEPTH > 1
-static fb_data* old_backdrop;
-#endif
-
-static int slideshow_enabled = false; /* run slideshow */
-static int running_slideshow = false; /* loading image because of slideshw */
-#ifndef SIMULATOR
-static int immediate_ata_off = false; /* power down disk after loading */
-#endif
-
-static unsigned ds, ds_min, ds_max; /* downscaling and limits */
+static LodePNG_Decoder _decoder;
/*
The 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
if (!decoder->error)
{
unsigned char *scanlines = idat + idat_size;
- size_t scanlines_size = (size_t)memory_max - idat_size + 1;
+ size_t scanlines_size = (size_t)memory_max - idat_size;
long time = *rb->current_tick;
decoder->error = LodePNG_decompress(scanlines, &scanlines_size, idat, idat_size, decoder->error_msg); /*decompress with the Zlib decompressor*/
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
{
decoded_image_size = (decoder->infoPng.height * decoder->infoPng.width * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8;
if (decoded_image_size > memory_size) { decoder->error = OUT_OF_MEMORY; return; }
- decoded_image = memory_max - decoded_image_size + 1;
+ decoded_image = memory_max - decoded_image_size;
if (scanlines + scanlines_size >= decoded_image) { decoder->error = OUT_OF_MEMORY; return; }
memset(decoded_image, 0, decoded_image_size * sizeof(unsigned char));
if (!running_slideshow)
@@ -1373,7 +1296,7 @@ static const unsigned char *png_error_messages[PNG_ERROR_MAX-PNG_ERROR_MIN+1] =
"invalid pHYs chunk size", /*74*/
};
-bool png_ext(const char ext[])
+bool img_ext(const char *ext)
{
if (!ext)
return false;
@@ -1383,436 +1306,36 @@ bool png_ext(const char ext[])
return false;
}
-/*Read directory contents for scrolling. */
-void get_pic_list(void)
-{
- int i;
- struct entry *dircache;
- char *pname;
- tree = rb->tree_get_context();
- dircache = tree->dircache;
-
- file_pt = (char **) memory;
-
- /* Remove path and leave only the name.*/
- pname = rb->strrchr(np_file,'/');
- pname++;
-
- for (i = 0; i < tree->filesindir; i++)
- {
- if (!(dircache[i].attr & ATTR_DIRECTORY)
- && png_ext(rb->strrchr(dircache[i].name, '.')))
- {
- file_pt[entries] = dircache[i].name;
- /* Set Selected File. */
- if (!rb->strcmp(file_pt[entries], pname))
- curfile = entries;
- entries++;
- }
- }
-
- memory += (entries * sizeof(char**));
- memory_size -= (entries * sizeof(char**));
-}
-
-int change_filename(int direct)
-{
- bool file_erased = (file_pt[curfile] == NULL);
- direction = direct;
-
- curfile += (direct == DIR_PREV? entries - 1: 1);
- if (curfile >= entries)
- curfile -= entries;
-
- if (file_erased)
- {
- /* remove 'erased' file names from list. */
- int count, i;
- for (count = i = 0; i < entries; i++)
- {
- if (curfile == i)
- curfile = count;
- if (file_pt[i] != NULL)
- file_pt[count++] = file_pt[i];
- }
- entries = count;
- }
-
- if (entries == 0)
- {
- rb->splash(HZ, "No supported files");
- return PLUGIN_ERROR;
- }
-
- if (rb->strlen(tree->currdir) > 1)
- {
- rb->strcpy(np_file, tree->currdir);
- rb->strcat(np_file, "/");
- }
- else
- rb->strcpy(np_file, tree->currdir);
-
- rb->strcat(np_file, file_pt[curfile]);
-
- return PLUGIN_OTHER;
-}
-
-/* switch off overlay, for handling SYS_ events */
-void cleanup(void *parameter)
+void draw_image_rect(struct image_info *info,
+ int x, int y, int width, int height)
{
- (void)parameter;
+ fb_data **pdisp = (fb_data**)info->data;
+ rb->lcd_bitmap_part(*pdisp, info->x + x, info->y + y, info->width,
+ x + MAX(0, (LCD_WIDTH-info->width)/2),
+ y + MAX(0, (LCD_HEIGHT-info->height)/2),
+ width, height);
}
-#define VSCROLL (LCD_HEIGHT/8)
-#define HSCROLL (LCD_WIDTH/10)
-
-#define ZOOM_IN 100 /* return codes for below function */
-#define ZOOM_OUT 101
-
-int show_menu(void) /* return 1 to quit */
-{
-#if LCD_DEPTH > 1
- rb->lcd_set_backdrop(old_backdrop);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(rb->global_settings->fg_color);
- rb->lcd_set_background(rb->global_settings->bg_color);
-#else
- rb->lcd_set_foreground(LCD_BLACK);
- rb->lcd_set_background(LCD_WHITE);
-#endif
-#endif
- int result;
-
- enum menu_id
- {
- MIID_RETURN = 0,
- MIID_TOGGLE_SS_MODE,
- MIID_CHANGE_SS_MODE,
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- MIID_SHOW_PLAYBACK_MENU,
-#endif
- MIID_QUIT,
- };
-
- MENUITEM_STRINGLIST(menu, "Png Menu", NULL,
- "Return", "Toggle Slideshow Mode",
- "Change Slideshow Time",
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- "Show Playback Menu",
-#endif
- "Quit");
-
- static const struct opt_items slideshow[2] = {
- { "Disable", -1 },
- { "Enable", -1 },
- };
-
- result=rb->do_menu(&menu, NULL, NULL, false);
-
- switch (result)
- {
- case MIID_RETURN:
- break;
- case MIID_TOGGLE_SS_MODE:
- rb->set_option("Toggle Slideshow", &slideshow_enabled, INT,
- slideshow , 2, NULL);
- break;
- case MIID_CHANGE_SS_MODE:
- rb->set_int("Slideshow Time", "s", UNIT_SEC,
- &png_settings.ss_timeout, NULL, 1,
- SS_MIN_TIMEOUT, SS_MAX_TIMEOUT, NULL);
- break;
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- case MIID_SHOW_PLAYBACK_MENU:
- if (plug_buf)
- {
- playback_control(NULL);
- }
- else
- {
- rb->splash(HZ, "Cannot restart playback");
- }
- break;
-#endif
- case MIID_QUIT:
- return 1;
- break;
- }
-
-#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
- /* change ata spindown time based on slideshow time setting */
- immediate_ata_off = false;
- rb->storage_spindown(rb->global_settings->disk_spindown);
-
- if (slideshow_enabled)
- {
- if (png_settings.ss_timeout < 10)
- {
- /* slideshow times < 10s keep disk spinning */
- rb->storage_spindown(0);
- }
- else if (!rb->mp3_is_playing())
- {
- /* slideshow times > 10s and not playing: ata_off after load */
- immediate_ata_off = true;
- }
- }
-#endif
-#if LCD_DEPTH > 1
- rb->lcd_set_backdrop(NULL);
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_BLACK);
-#endif
- rb->lcd_clear_display();
- return 0;
-}
-
-void draw_image(struct LodePNG_Decoder* decoder)
-{
- rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->width,
- MAX(0, (LCD_WIDTH - decoder->width) / 2),
- MAX(0, (LCD_HEIGHT - decoder->height) / 2),
- decoder->width - decoder->x,
- decoder->height - decoder->y);
-}
-
-/* Pan the viewing window right - move image to the left and fill in
- the right-hand side */
-static void pan_view_right(struct LodePNG_Decoder* decoder)
-{
- int move;
-
- move = MIN(HSCROLL, decoder->width - decoder->x - LCD_WIDTH);
- if (move > 0)
- {
- decoder->x += move;
- draw_image(decoder);
- rb->lcd_update();
- }
-}
-
-/* Pan the viewing window left - move image to the right and fill in
- the left-hand side */
-static void pan_view_left(struct LodePNG_Decoder* decoder)
-{
- int move;
-
- move = MIN(HSCROLL, decoder->x);
- if (move > 0)
- {
- decoder->x -= move;
- draw_image(decoder);
- rb->lcd_update();
- }
-}
-
-
-/* Pan the viewing window up - move image down and fill in
- the top */
-static void pan_view_up(struct LodePNG_Decoder* decoder)
-{
- int move;
-
- move = MIN(VSCROLL, decoder->y);
- if (move > 0)
- {
- decoder->y -= move;
- draw_image(decoder);
- rb->lcd_update();
- }
-}
-
-/* Pan the viewing window down - move image up and fill in
- the bottom */
-static void pan_view_down(struct LodePNG_Decoder* decoder)
-{
- int move;
-
- move = MIN(VSCROLL, decoder->height - decoder->y - LCD_HEIGHT);
- if (move > 0)
- {
- decoder->y += move;
- draw_image(decoder);
- rb->lcd_update();
- }
-}
-
-/* interactively scroll around the image */
-int scroll_bmp(struct LodePNG_Decoder* decoder)
-{
- int button;
- int lastbutton = 0;
-
- while (true)
- {
- if (slideshow_enabled)
- button = rb->button_get_w_tmo(png_settings.ss_timeout * HZ);
- else
- button = rb->button_get(true);
-
- running_slideshow = false;
-
- switch (button)
- {
- case PNG_LEFT:
- if (entries > 1 && decoder->width <= LCD_WIDTH
- && decoder->height <= LCD_HEIGHT)
- return change_filename(DIR_PREV);
- case PNG_LEFT | BUTTON_REPEAT:
- pan_view_left(decoder);
- break;
-
- case PNG_RIGHT:
- if (entries > 1 && decoder->width <= LCD_WIDTH
- && decoder->height <= LCD_HEIGHT)
- return change_filename(DIR_NEXT);
- case PNG_RIGHT | BUTTON_REPEAT:
- pan_view_right(decoder);
- break;
-
- case PNG_UP:
- case PNG_UP | BUTTON_REPEAT:
- pan_view_up(decoder);
- break;
-
- case PNG_DOWN:
- case PNG_DOWN | BUTTON_REPEAT:
- pan_view_down(decoder);
- break;
-
- case BUTTON_NONE:
- if (!slideshow_enabled)
- break;
- running_slideshow = true;
- if (entries > 1)
- return change_filename(DIR_NEXT);
- break;
-
-#ifdef PNG_SLIDE_SHOW
- case PNG_SLIDE_SHOW:
- slideshow_enabled = !slideshow_enabled;
- running_slideshow = slideshow_enabled;
- break;
-#endif
-
-#ifdef PNG_NEXT_REPEAT
- case PNG_NEXT_REPEAT:
-#endif
- case PNG_NEXT:
- if (entries > 1)
- return change_filename(DIR_NEXT);
- break;
-
-#ifdef PNG_PREVIOUS_REPEAT
- case PNG_PREVIOUS_REPEAT:
-#endif
- case PNG_PREVIOUS:
- if (entries > 1)
- return change_filename(DIR_PREV);
- break;
-
- case PNG_ZOOM_IN:
-#ifdef PNG_ZOOM_PRE
- if (lastbutton != PNG_ZOOM_PRE)
- break;
-#endif
- return ZOOM_IN;
- break;
-
- case PNG_ZOOM_OUT:
-#ifdef PNG_ZOOM_PRE
- if (lastbutton != PNG_ZOOM_PRE)
- break;
-#endif
- return ZOOM_OUT;
- break;
-
-#ifdef PNG_RC_MENU
- case PNG_RC_MENU:
-#endif
- case PNG_MENU:
-
- if (show_menu() == 1)
- return PLUGIN_OK;
-
- draw_image(decoder);
- rb->lcd_update();
-
- break;
- default:
- if (rb->default_event_handler_ex(button, cleanup, NULL)
- == SYS_USB_CONNECTED)
- return PLUGIN_USB_CONNECTED;
- break;
-
- } /* switch */
-
- if (button != BUTTON_NONE)
- lastbutton = button;
- } /* while (true) */
-}
-
-/* callback updating a progress meter while PNG decoding */
-void cb_progress(int current, int total)
-{
-
- if (current & 1) rb->yield(); /* be nice to the other threads */
- if (!running_slideshow)
- {
- rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
- 0, LCD_HEIGHT-8, LCD_WIDTH, 8,
- total, 0, current, HORIZONTAL);
- rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
- }
- else
- {
- /* in slideshow mode, keep gui interference to a minimum */
- rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
- 0, LCD_HEIGHT-4, LCD_WIDTH, 4,
- total, 0, current, HORIZONTAL);
- rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4);
- }
-}
-
-int pngmem(struct LodePNG_Decoder* decoder, int ds)
+int img_mem(int ds)
{
+ LodePNG_Decoder *decoder = &_decoder;
return (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds) * FB_DATA_SZ;
}
-/* how far can we zoom in without running out of memory */
-int min_downscale(struct LodePNG_Decoder* decoder, int bufsize)
-{
- int downscale = 8;
-
- if (pngmem(decoder, 8) > bufsize)
- return 0; /* error, too large, even 1:8 doesn't fit */
-
- while (downscale > 1 && pngmem(decoder, downscale/2) <= bufsize)
- downscale /= 2;
-
- return downscale;
-}
-
-/* how far can we zoom out, to fit image into the LCD */
-unsigned max_downscale(struct LodePNG_Decoder* decoder)
-{
- unsigned downscale = 1;
-
- while (downscale < 8 && (decoder->infoPng.width/downscale > LCD_WIDTH
- || decoder->infoPng.height/downscale > LCD_HEIGHT))
- {
- downscale *= 2;
- }
-
- return downscale;
-}
-
-/* load image from filename. */
-int load_image(char* filename, struct LodePNG_Decoder* decoder)
+int load_image(char *filename, struct image_info *info,
+ unsigned char *buf, ssize_t *buf_size)
{
int fd;
long time = 0; /* measured ticks */
int w, h; /* used to center output */
+ LodePNG_Decoder *decoder = &_decoder;
+
+ memset(&disp, 0, sizeof(disp));
+ LodePNG_Decoder_init(decoder);
+
+ memory = buf;
+ memory_size = *buf_size;
+ memory_max = memory + memory_size;
fd = rb->open(filename, O_RDONLY);
if (fd < 0)
@@ -1833,12 +1356,6 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
if (image_size > memory_size) {
decoder->error = FILE_TOO_LARGE;
rb->close(fd);
-#ifndef SIMULATOR
- if (running_slideshow && immediate_ata_off) {
- /* running slideshow and time is long enough: power down disk */
- rb->storage_sleep();
- }
-#endif
} else {
if (!running_slideshow) {
@@ -1847,7 +1364,7 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
rb->lcd_update();
}
- image = memory_max - image_size + 1;
+ image = memory_max - image_size;
rb->read(fd, image, image_size);
rb->close(fd);
@@ -1856,7 +1373,7 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
rb->lcd_puts(0, 2, print);
rb->lcd_update();
}
-#ifndef SIMULATOR
+#ifdef DISK_SPINDOWN
else if (immediate_ata_off) {
/* running slideshow and time is long enough: power down disk */
rb->storage_sleep();
@@ -1939,21 +1456,27 @@ int load_image(char* filename, struct LodePNG_Decoder* decoder)
else
return PLUGIN_ERROR;
}
+
+ disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
+ info->x_size = decoder->infoPng.width;
+ info->y_size = decoder->infoPng.height;
+ *buf_size = memory_max - (unsigned char*)disp_buf;
return PLUGIN_OK;
}
-/* return decoded or cached image */
-fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
+int get_image(struct image_info *info, int ds)
{
- fb_data * p_disp = disp[ds]; /* short cut */
+ fb_data **p_disp = &disp[ds]; /* short cut */
+ LodePNG_Decoder *decoder = &_decoder;
- decoder->width = decoder->infoPng.width / ds;
- decoder->height = decoder->infoPng.height / ds;
+ info->width = decoder->infoPng.width / ds;
+ info->height = decoder->infoPng.height / ds;
+ info->data = p_disp;
- if (p_disp != NULL)
+ if (*p_disp != NULL)
{
- DEBUGF("Found an image in cache\n");
- return p_disp; /* we still have it */
+ /* we still have it */
+ return PLUGIN_OK;
}
/* assign image buffer */
@@ -1961,13 +1484,13 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
if (!running_slideshow)
{
rb->snprintf(print, sizeof(print), "resizing %d*%d",
- decoder->width, decoder->height);
+ info->width, info->height);
rb->lcd_puts(0, 3, print);
rb->lcd_update();
}
struct bitmap bmp_src, bmp_dst;
- int size = decoder->width * decoder->height;
+ int size = info->width * info->height;
if ((unsigned char *)(disp_buf + size) >= memory_max) {
/* have to discard the current */
@@ -1978,16 +1501,16 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
}
- disp[ds] = disp_buf;
- disp_buf = (fb_data *)((intptr_t)(disp[ds] + size + 3) & ~3);
+ *p_disp = disp_buf;
+ disp_buf = (fb_data *)((intptr_t)(disp_buf + size + 3) & ~3);
bmp_src.width = decoder->infoPng.width;
bmp_src.height = decoder->infoPng.height;
bmp_src.data = (unsigned char *)converted_image;
- bmp_dst.width = decoder->width;
- bmp_dst.height = decoder->height;
- bmp_dst.data = (unsigned char *)disp[ds];
+ bmp_dst.width = info->width;
+ bmp_dst.height = info->height;
+ bmp_dst.data = (unsigned char *)*p_disp;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(true);
smooth_resize_bitmap(&bmp_src, &bmp_dst);
@@ -1996,276 +1519,8 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
smooth_resize_bitmap(&bmp_src, &bmp_dst);
#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
} else {
- disp[ds] = converted_image;
- return converted_image;
- }
-
- return disp[ds];
-}
-
-/* set the view to the given center point, limit if necessary */
-void set_view (struct LodePNG_Decoder* decoder, int cx, int cy)
-{
- int x, y;
-
- /* plain center to available width/height */
- x = cx - MIN(LCD_WIDTH, decoder->width) / 2;
- y = cy - MIN(LCD_HEIGHT, decoder->height) / 2;
-
- /* limit against upper image size */
- x = MIN(decoder->width - LCD_WIDTH, x);
- y = MIN(decoder->height - LCD_HEIGHT, y);
-
- /* limit against negative side */
- x = MAX(0, x);
- y = MAX(0, y);
-
- decoder->x = x; /* set the values */
- decoder->y = y;
-}
-
-/* calculate the view center based on the bitmap position */
-void get_view(struct LodePNG_Decoder* decoder, int* p_cx, int* p_cy)
-{
- *p_cx = decoder->x + MIN(LCD_WIDTH, decoder->width) / 2;
- *p_cy = decoder->y + MIN(LCD_HEIGHT, decoder->height) / 2;
-}
-
-/* load, decode, display the image */
-int load_and_show(char* filename)
-{
- int status;
- int cx=0, cy=0; /* view center */
-
-#if LCD_DEPTH > 1
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_BLACK);
- rb->lcd_set_backdrop(NULL);
-#endif
- rb->lcd_clear_display();
-
- memset(&disp, 0, sizeof(disp));
- LodePNG_Decoder_init(&decoder);
-
- if (rb->button_get(false) == PNG_MENU)
- status = PLUGIN_ABORT;
- else
- status = load_image(filename, &decoder);
-
- if (status == PLUGIN_OUTOFMEM)
- {
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- if (plug_buf)
- {
- rb->lcd_setfont(FONT_SYSFIXED);
- rb->lcd_clear_display();
- rb->snprintf(print,sizeof(print),"%s:",rb->strrchr(filename,'/')+1);
- rb->lcd_puts(0,0,print);
- rb->lcd_puts(0,1,"Not enough plugin memory!");
- rb->lcd_puts(0,2,"Zoom In: Stop playback.");
- if (entries>1)
- rb->lcd_puts(0,3,"Left/Right: Skip File.");
- rb->lcd_puts(0,4,"Show Menu: Quit.");
- rb->lcd_update();
- rb->lcd_setfont(FONT_UI);
-
- rb->button_clear_queue();
-
- while (1)
- {
- int button = rb->button_get(true);
- switch (button)
- {
- case PNG_ZOOM_IN:
- plug_buf = false;
- memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
- memory_max = memory + memory_size - 1;
- /*try again this file, now using the audio buffer */
- return PLUGIN_OTHER;
-#ifdef PNG_RC_MENU
- case PNG_RC_MENU:
-#endif
- case PNG_MENU:
- return PLUGIN_OK;
-
- case PNG_LEFT:
- if (entries>1)
- {
- rb->lcd_clear_display();
- return change_filename(DIR_PREV);
- }
- break;
-
- case PNG_RIGHT:
- if (entries>1)
- {
- rb->lcd_clear_display();
- return change_filename(DIR_NEXT);
- }
- break;
- default:
- if (rb->default_event_handler_ex(button, cleanup, NULL)
- == SYS_USB_CONNECTED)
- return PLUGIN_USB_CONNECTED;
-
- }
- }
- }
- else
-#endif
- {
- rb->splash(HZ, "Out of Memory");
- file_pt[curfile] = NULL;
- return change_filename(direction);
- }
- }
- else if (status == PLUGIN_ERROR)
- {
- file_pt[curfile] = NULL;
- return change_filename(direction);
- }
- else if (status == PLUGIN_ABORT) {
- rb->splash(HZ, "aborted");
- return PLUGIN_OK;
+ *p_disp = converted_image;
}
- disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
- ds_max = max_downscale(&decoder); /* check display constraint */
- ds_min = min_downscale(&decoder, memory_max - (unsigned char*)disp_buf); /* check memory constraint */
- if (ds_min == 0) {
- /* Can not resize the image */
- ds_min = ds_max = 1;
- } else if (ds_max < ds_min) {
- ds_max = ds_min;
- }
-
- ds = ds_max; /* initialize setting */
- cx = decoder.infoPng.width/ds/2; /* center the view */
- cy = decoder.infoPng.height/ds/2;
-
- do {
- resized_image = get_image(&decoder, ds); /* decode or fetch from cache */
-
- set_view(&decoder, cx, cy);
-
- if (!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "showing %dx%d",
- decoder.width, decoder.height);
- rb->lcd_puts(0, 3, print);
- rb->lcd_update();
- }
-
- rb->lcd_clear_display();
- draw_image(&decoder);
- rb->lcd_update();
-
- /* drawing is now finished, play around with scrolling
- * until you press OFF or connect USB
- */
- while (1)
- {
- status = scroll_bmp(&decoder);
- if (status == ZOOM_IN)
- {
- if (ds > 1)
- {
- /* as 1/1 is always available, jump ds to 1 if ds is ds_min. */
- int zoom = (ds == ds_min)? ds_min: 2;
- ds /= zoom; /* reduce downscaling to zoom in */
- get_view(&decoder, &cx, &cy);
- cx *= zoom; /* prepare the position in the new image */
- cy *= zoom;
- }
- else
- continue;
- }
-
- if (status == ZOOM_OUT)
- {
- if (ds < ds_max)
- {
- /* if ds is 1 and ds_min is greater than 1, jump ds to ds_min. */
- int zoom = (ds < ds_min)? ds_min: 2;
- ds *= zoom; /* increase downscaling to zoom out */
- get_view(&decoder, &cx, &cy);
- cx /= zoom; /* prepare the position in the new image */
- cy /= zoom;
- }
- else
- continue;
- }
- break;
- }
- rb->lcd_clear_display();
- }
- while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
- && status != PLUGIN_OTHER);
-
- return status;
-}
-
-/******************** Plugin entry point *********************/
-
-enum plugin_status plugin_start(const void* parameter)
-{
- int condition;
-#if LCD_DEPTH > 1
- old_backdrop = rb->lcd_get_backdrop();
-#endif
-
- if (!parameter) return PLUGIN_ERROR;
-
-#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- memory = rb->plugin_get_buffer((size_t *)&memory_size);
-#else
- memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
-#endif
-
- rb->strcpy(np_file, parameter);
- get_pic_list();
-
- if (!entries) return PLUGIN_ERROR;
-
-#if (PLUGIN_BUFFER_SIZE >= MIN_MEM) && !defined(SIMULATOR)
- if (!rb->audio_status()) {
- plug_buf = false;
- memory = rb->plugin_get_audio_buffer((size_t *)&memory_size);
- }
-#endif
-
- memory_max = memory + memory_size - 1;
-
- /* should be ok to just load settings since the plugin itself has
- just been loaded from disk and the drive should be spinning */
- configfile_load(PNG_CONFIGFILE, png_config,
- ARRAYLEN(png_config), PNG_SETTINGS_MINVERSION);
- old_settings = png_settings;
-
- /* Turn off backlight timeout */
- backlight_force_on(); /* backlight control in lib/helper.c */
-
- do
- {
- condition = load_and_show(np_file);
- } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
- && condition != PLUGIN_ERROR);
-
- if (rb->memcmp(&png_settings, &old_settings, sizeof (png_settings)))
- {
- /* Just in case drive has to spin, keep it from looking locked */
- rb->splash(0, "Saving Settings");
- configfile_save(PNG_CONFIGFILE, png_config,
- ARRAYLEN(png_config), PNG_SETTINGS_VERSION);
- }
-
-#if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
- /* set back ata spindown time in case we changed it */
- rb->storage_spindown(rb->global_settings->disk_spindown);
-#endif
-
- /* Turn on backlight timeout (revert to settings) */
- backlight_use_settings(); /* backlight control in lib/helper.c */
-
- return condition;
+ return PLUGIN_OK;
}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$id $
+ *
+ * Copyright (C) 2009 by Christophe Gouiran <bechris13250 -at- gmail -dot- com>
+ *
+ * Based on lodepng, a lightweight png decoder/encoder
+ * (c) 2005-2008 Lode Vandevenne
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "../imageviewer.h"
+
+#define OUT_OF_MEMORY 9900
+#define FILE_TOO_LARGE 9910
+
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 @@
# $Id$
#
-PNGSRCDIR := $(APPSDIR)/plugins/png
-PNGBUILDDIR := $(BUILDDIR)/apps/plugins/png
+PNGSRCDIR := $(IMGVSRCDIR)/png
+PNGBUILDDIR := $(IMGVBUILDDIR)/png
ROCKS += $(PNGBUILDDIR)/png.rock
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 @@
+#define PNG_VIEWER
+#define MENU_TITLE "Png Menu"
+#define UNSCALED_IS_AVAILABLE 1
+
+#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 @@
-/***************************************************************************
-* __________ __ ___.
-* Open \______ \ ____ ____ | | _\_ |__ _______ ___
-* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
-* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
-* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
-* \/ \/ \/ \/ \/
-* $Id$
-*
-* JPEG image viewer
-* (This is a real mess if it has to be coded in one single C file)
-*
-* File scrolling addition (C) 2005 Alexander Spyridakis
-* Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon
-* Heavily borrowed from the IJG implementation (C) Thomas G. Lane
-* Small & fast downscaling IDCT (C) 2002 by Guido Vollbeding JPEGclub.org
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-* KIND, either express or implied.
-*
-****************************************************************************/
-
-#ifndef _JPEG_JPEG_H
-#define _JPEG_JPEG_H
-
-#include "plugin.h"
-
-/* variable button definitions */
-#if CONFIG_KEYPAD == RECORDER_PAD
-#define JPEG_ZOOM_IN BUTTON_PLAY
-#define JPEG_ZOOM_OUT BUTTON_ON
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_NEXT BUTTON_F3
-#define JPEG_PREVIOUS BUTTON_F2
-#define JPEG_MENU BUTTON_OFF
-
-#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
-#define JPEG_ZOOM_IN BUTTON_SELECT
-#define JPEG_ZOOM_OUT BUTTON_ON
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_NEXT BUTTON_F3
-#define JPEG_PREVIOUS BUTTON_F2
-#define JPEG_MENU BUTTON_OFF
-
-#elif CONFIG_KEYPAD == ONDIO_PAD
-#define JPEG_ZOOM_PRE BUTTON_MENU
-#define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
-#define JPEG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
-#define JPEG_MENU BUTTON_OFF
-
-#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define JPEG_ZOOM_IN BUTTON_SELECT
-#define JPEG_ZOOM_OUT BUTTON_MODE
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
-#define JPEG_NEXT BUTTON_ON
-#define JPEG_PREVIOUS BUTTON_REC
-#else
-#define JPEG_NEXT BUTTON_REC
-#define JPEG_PREVIOUS BUTTON_ON
-#endif
-#define JPEG_MENU BUTTON_OFF
-#define JPEG_RC_MENU BUTTON_RC_STOP
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
- (CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define JPEG_ZOOM_IN BUTTON_SCROLL_FWD
-#define JPEG_ZOOM_OUT BUTTON_SCROLL_BACK
-#define JPEG_UP BUTTON_MENU
-#define JPEG_DOWN BUTTON_PLAY
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU (BUTTON_SELECT | BUTTON_MENU)
-#define JPEG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
-#define JPEG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_NEXT BUTTON_PLAY
-#define JPEG_PREVIOUS BUTTON_REC
-
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define JPEG_ZOOM_IN BUTTON_VOL_UP
-#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT)
-#define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == SANSA_E200_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_SLIDE_SHOW BUTTON_REC
-#define JPEG_NEXT BUTTON_SCROLL_FWD
-#define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
-#define JPEG_PREVIOUS BUTTON_SCROLL_BACK
-#define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU (BUTTON_HOME|BUTTON_REPEAT)
-#define JPEG_NEXT BUTTON_SCROLL_FWD
-#define JPEG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
-#define JPEG_PREVIOUS BUTTON_SCROLL_BACK
-#define JPEG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_C200_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_SLIDE_SHOW BUTTON_REC
-#define JPEG_NEXT BUTTON_VOL_UP
-#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define JPEG_PREVIOUS BUTTON_VOL_DOWN
-#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_SLIDE_SHOW BUTTON_HOME
-#define JPEG_NEXT BUTTON_VOL_UP
-#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define JPEG_PREVIOUS BUTTON_VOL_DOWN
-#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_M200_PAD
-#define JPEG_ZOOM_PRE BUTTON_SELECT
-#define JPEG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
-#define JPEG_NEXT BUTTON_VOL_UP
-#define JPEG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define JPEG_PREVIOUS BUTTON_VOL_DOWN
-#define JPEG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define JPEG_ZOOM_PRE BUTTON_PLAY
-#define JPEG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
-#define JPEG_UP BUTTON_SCROLL_UP
-#define JPEG_DOWN BUTTON_SCROLL_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_POWER
-#define JPEG_NEXT BUTTON_FF
-#define JPEG_PREVIOUS BUTTON_REW
-
-#elif CONFIG_KEYPAD == MROBE500_PAD
-#define JPEG_MENU BUTTON_POWER
-
-#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
-#define JPEG_ZOOM_IN BUTTON_VOL_UP
-#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT BUTTON_NEXT
-#define JPEG_PREVIOUS BUTTON_PREV
-
-#elif CONFIG_KEYPAD == MROBE100_PAD
-#define JPEG_ZOOM_IN BUTTON_SELECT
-#define JPEG_ZOOM_OUT BUTTON_PLAY
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
-#define JPEG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
-#define JPEG_ZOOM_PRE BUTTON_RC_PLAY
-#define JPEG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
-#define JPEG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
-#define JPEG_UP BUTTON_RC_VOL_UP
-#define JPEG_DOWN BUTTON_RC_VOL_DOWN
-#define JPEG_LEFT BUTTON_RC_REW
-#define JPEG_RIGHT BUTTON_RC_FF
-#define JPEG_MENU BUTTON_RC_REC
-#define JPEG_NEXT BUTTON_RC_MODE
-#define JPEG_PREVIOUS BUTTON_RC_MENU
-
-#elif CONFIG_KEYPAD == COWON_D2_PAD
-
-#elif CONFIG_KEYPAD == IAUDIO67_PAD
-#define JPEG_ZOOM_IN BUTTON_VOLUP
-#define JPEG_ZOOM_OUT BUTTON_VOLDOWN
-#define JPEG_UP BUTTON_STOP
-#define JPEG_DOWN BUTTON_PLAY
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
-#define JPEG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
-
-#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
-
-#define JPEG_ZOOM_IN BUTTON_PLAY
-#define JPEG_ZOOM_OUT BUTTON_CUSTOM
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT BUTTON_SELECT
-#define JPEG_PREVIOUS BUTTON_BACK
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
-#define JPEG_ZOOM_IN BUTTON_VOL_UP
-#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT BUTTON_VIEW
-#define JPEG_PREVIOUS BUTTON_PLAYLIST
-
-#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
-#define JPEG_ZOOM_IN BUTTON_VOL_UP
-#define JPEG_ZOOM_OUT BUTTON_VOL_DOWN
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_PREV
-#define JPEG_RIGHT BUTTON_NEXT
-#define JPEG_MENU BUTTON_MENU
-#define JPEG_NEXT BUTTON_RIGHT
-#define JPEG_PREVIOUS BUTTON_LEFT
-
-#elif CONFIG_KEYPAD == ONDAVX747_PAD
-#elif CONFIG_KEYPAD == ONDAVX777_PAD
-
-#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
-#define JPEG_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
-#define JPEG_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
-#define JPEG_UP BUTTON_UP
-#define JPEG_DOWN BUTTON_DOWN
-#define JPEG_LEFT BUTTON_LEFT
-#define JPEG_RIGHT BUTTON_RIGHT
-#define JPEG_MENU BUTTON_PLAY
-#define JPEG_NEXT BUTTON_FFWD
-#define JPEG_PREVIOUS BUTTON_REW
-
-#else
-#error No keymap defined!
-#endif
-
-#ifdef HAVE_TOUCHSCREEN
-#ifndef JPEG_UP
-#define JPEG_UP BUTTON_TOPMIDDLE
-#endif
-#ifndef JPEG_DOWN
-#define JPEG_DOWN BUTTON_BOTTOMMIDDLE
-#endif
-#ifndef JPEG_LEFT
-#define JPEG_LEFT BUTTON_MIDLEFT
-#endif
-#ifndef JPEG_RIGHT
-#define JPEG_RIGHT BUTTON_MIDRIGHT
-#endif
-#ifndef JPEG_ZOOM_IN
-#define JPEG_ZOOM_IN BUTTON_TOPRIGHT
-#endif
-#ifndef JPEG_ZOOM_OUT
-#define JPEG_ZOOM_OUT BUTTON_TOPLEFT
-#endif
-#ifndef JPEG_MENU
-#define JPEG_MENU (BUTTON_CENTER|BUTTON_REL)
-#endif
-#ifndef JPEG_NEXT
-#define JPEG_NEXT BUTTON_BOTTOMRIGHT
-#endif
-#ifndef JPEG_PREVIOUS
-#define JPEG_PREVIOUS BUTTON_BOTTOMLEFT
-#endif
-#endif
-
-
-#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 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$id $
- *
- * Copyright (C) 2009 by Christophe Gouiran <bechris13250 -at- gmail -dot- com>
- *
- * Based on lodepng, a lightweight png decoder/encoder
- * (c) 2005-2008 Lode Vandevenne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-/*
-LodePNG version 20080927
-
-Copyright (c) 2005-2008 Lode Vandevenne
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source
- distribution.
-*/
-
-/*
-The manual and changelog can be found in the header file "lodepng.h"
-You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
-*/
-
-/* variable button definitions */
-#if CONFIG_KEYPAD == RECORDER_PAD
-#define PNG_ZOOM_IN BUTTON_PLAY
-#define PNG_ZOOM_OUT BUTTON_ON
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_NEXT BUTTON_F3
-#define PNG_PREVIOUS BUTTON_F2
-#define PNG_MENU BUTTON_OFF
-
-#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
-#define PNG_ZOOM_IN BUTTON_SELECT
-#define PNG_ZOOM_OUT BUTTON_ON
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_NEXT BUTTON_F3
-#define PNG_PREVIOUS BUTTON_F2
-#define PNG_MENU BUTTON_OFF
-
-#elif CONFIG_KEYPAD == ONDIO_PAD
-#define PNG_ZOOM_PRE BUTTON_MENU
-#define PNG_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_NEXT (BUTTON_MENU | BUTTON_RIGHT)
-#define PNG_PREVIOUS (BUTTON_MENU | BUTTON_LEFT)
-#define PNG_MENU BUTTON_OFF
-
-#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define PNG_ZOOM_IN BUTTON_SELECT
-#define PNG_ZOOM_OUT BUTTON_MODE
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
-#define PNG_NEXT BUTTON_ON
-#define PNG_PREVIOUS BUTTON_REC
-#else
-#define PNG_NEXT BUTTON_REC
-#define PNG_PREVIOUS BUTTON_ON
-#endif
-#define PNG_MENU BUTTON_OFF
-#define PNG_RC_MENU BUTTON_RC_STOP
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
- (CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define PNG_ZOOM_IN BUTTON_SCROLL_FWD
-#define PNG_ZOOM_OUT BUTTON_SCROLL_BACK
-#define PNG_UP BUTTON_MENU
-#define PNG_DOWN BUTTON_PLAY
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU (BUTTON_SELECT | BUTTON_MENU)
-#define PNG_NEXT (BUTTON_SELECT | BUTTON_RIGHT)
-#define PNG_PREVIOUS (BUTTON_SELECT | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_NEXT BUTTON_PLAY
-#define PNG_PREVIOUS BUTTON_REC
-
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define PNG_ZOOM_IN BUTTON_VOL_UP
-#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT (BUTTON_A | BUTTON_RIGHT)
-#define PNG_PREVIOUS (BUTTON_A | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == SANSA_E200_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_SLIDE_SHOW BUTTON_REC
-#define PNG_NEXT BUTTON_SCROLL_FWD
-#define PNG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
-#define PNG_PREVIOUS BUTTON_SCROLL_BACK
-#define PNG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU (BUTTON_HOME|BUTTON_REPEAT)
-#define PNG_NEXT BUTTON_SCROLL_FWD
-#define PNG_NEXT_REPEAT (BUTTON_SCROLL_FWD|BUTTON_REPEAT)
-#define PNG_PREVIOUS BUTTON_SCROLL_BACK
-#define PNG_PREVIOUS_REPEAT (BUTTON_SCROLL_BACK|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_C200_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_SLIDE_SHOW BUTTON_REC
-#define PNG_NEXT BUTTON_VOL_UP
-#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define PNG_PREVIOUS BUTTON_VOL_DOWN
-#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_SLIDE_SHOW BUTTON_HOME
-#define PNG_NEXT BUTTON_VOL_UP
-#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define PNG_PREVIOUS BUTTON_VOL_DOWN
-#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == SANSA_M200_PAD
-#define PNG_ZOOM_PRE BUTTON_SELECT
-#define PNG_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_SLIDE_SHOW (BUTTON_SELECT | BUTTON_UP)
-#define PNG_NEXT BUTTON_VOL_UP
-#define PNG_NEXT_REPEAT (BUTTON_VOL_UP|BUTTON_REPEAT)
-#define PNG_PREVIOUS BUTTON_VOL_DOWN
-#define PNG_PREVIOUS_REPEAT (BUTTON_VOL_DOWN|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define PNG_ZOOM_PRE BUTTON_PLAY
-#define PNG_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
-#define PNG_UP BUTTON_SCROLL_UP
-#define PNG_DOWN BUTTON_SCROLL_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_POWER
-#define PNG_NEXT BUTTON_FF
-#define PNG_PREVIOUS BUTTON_REW
-
-#elif CONFIG_KEYPAD == MROBE500_PAD
-
-#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
-#define PNG_ZOOM_IN BUTTON_VOL_UP
-#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT BUTTON_NEXT
-#define PNG_PREVIOUS BUTTON_PREV
-
-#elif CONFIG_KEYPAD == MROBE100_PAD
-#define PNG_ZOOM_IN BUTTON_SELECT
-#define PNG_ZOOM_OUT BUTTON_PLAY
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT (BUTTON_DISPLAY | BUTTON_RIGHT)
-#define PNG_PREVIOUS (BUTTON_DISPLAY | BUTTON_LEFT)
-
-#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
-#define PNG_ZOOM_PRE BUTTON_RC_PLAY
-#define PNG_ZOOM_IN (BUTTON_RC_PLAY|BUTTON_REL)
-#define PNG_ZOOM_OUT (BUTTON_RC_PLAY|BUTTON_REPEAT)
-#define PNG_UP BUTTON_RC_VOL_UP
-#define PNG_DOWN BUTTON_RC_VOL_DOWN
-#define PNG_LEFT BUTTON_RC_REW
-#define PNG_RIGHT BUTTON_RC_FF
-#define PNG_MENU BUTTON_RC_REC
-#define PNG_NEXT BUTTON_RC_MODE
-#define PNG_PREVIOUS BUTTON_RC_MENU
-
-#elif CONFIG_KEYPAD == COWON_D2_PAD
-
-#elif CONFIG_KEYPAD == IAUDIO67_PAD
-#define PNG_ZOOM_IN BUTTON_VOLUP
-#define PNG_ZOOM_OUT BUTTON_VOLDOWN
-#define PNG_UP BUTTON_STOP
-#define PNG_DOWN BUTTON_PLAY
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT (BUTTON_PLAY|BUTTON_VOLUP)
-#define PNG_PREVIOUS (BUTTON_PLAY|BUTTON_VOLDOWN)
-
-#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
-
-#define PNG_ZOOM_IN BUTTON_PLAY
-#define PNG_ZOOM_OUT BUTTON_CUSTOM
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT BUTTON_SELECT
-#define PNG_PREVIOUS BUTTON_BACK
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
-#define PNG_ZOOM_IN BUTTON_VOL_UP
-#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT BUTTON_VIEW
-#define PNG_PREVIOUS BUTTON_PLAYLIST
-
-#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
-#define PNG_ZOOM_IN BUTTON_VOL_UP
-#define PNG_ZOOM_OUT BUTTON_VOL_DOWN
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_PREV
-#define PNG_RIGHT BUTTON_NEXT
-#define PNG_MENU BUTTON_MENU
-#define PNG_NEXT BUTTON_RIGHT
-#define PNG_PREVIOUS BUTTON_LEFT
-
-#elif CONFIG_KEYPAD == ONDAVX747_PAD
-#define PNG_MENU BUTTON_POWER
-#elif CONFIG_KEYPAD == ONDAVX777_PAD
-#define PNG_MENU BUTTON_POWER
-
-#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
-#define PNG_ZOOM_IN (BUTTON_PLAY|BUTTON_UP)
-#define PNG_ZOOM_OUT (BUTTON_PLAY|BUTTON_DOWN)
-#define PNG_UP BUTTON_UP
-#define PNG_DOWN BUTTON_DOWN
-#define PNG_LEFT BUTTON_LEFT
-#define PNG_RIGHT BUTTON_RIGHT
-#define PNG_MENU BUTTON_PLAY
-#define PNG_NEXT BUTTON_FFWD
-#define PNG_PREVIOUS BUTTON_REW
-
-#else
-#error No keymap defined!
-#endif
-
-#ifdef HAVE_TOUCHSCREEN
-#ifndef PNG_UP
-#define PNG_UP BUTTON_TOPMIDDLE
-#endif
-#ifndef PNG_DOWN
-#define PNG_DOWN BUTTON_BOTTOMMIDDLE
-#endif
-#ifndef PNG_LEFT
-#define PNG_LEFT BUTTON_MIDLEFT
-#endif
-#ifndef PNG_RIGHT
-#define PNG_RIGHT BUTTON_MIDRIGHT
-#endif
-#ifndef PNG_ZOOM_IN
-#define PNG_ZOOM_IN BUTTON_TOPRIGHT
-#endif
-#ifndef PNG_ZOOM_OUT
-#define PNG_ZOOM_OUT BUTTON_TOPLEFT
-#endif
-#ifndef PNG_MENU
-#define PNG_MENU (BUTTON_CENTER|BUTTON_REL)
-#endif
-#ifndef PNG_NEXT
-#define PNG_NEXT BUTTON_BOTTOMRIGHT
-#endif
-#ifndef PNG_PREVIOUS
-#define PNG_PREVIOUS BUTTON_BOTTOMLEFT
-#endif
-#endif
-
-#define PLUGIN_OTHER 10 /* State code for output with return. */
-#define PLUGIN_ABORT 11
-#define PLUGIN_OUTOFMEM 12
-#define OUT_OF_MEMORY 9900
-#define FILE_TOO_LARGE 9910