summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/CATEGORIES2
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/imageviewer/SUBDIRS3
-rw-r--r--apps/plugins/imageviewer/image_decoder.c6
-rw-r--r--apps/plugins/imageviewer/image_decoder.h3
-rw-r--r--apps/plugins/imageviewer/ppm/SOURCES2
-rw-r--r--apps/plugins/imageviewer/ppm/ppm.c233
-rw-r--r--apps/plugins/imageviewer/ppm/ppm.make29
-rw-r--r--apps/plugins/imageviewer/ppm/ppm_decoder.c250
-rw-r--r--apps/plugins/imageviewer/ppm/ppm_decoder.h44
-rw-r--r--apps/plugins/ppmviewer.c355
-rw-r--r--apps/plugins/viewers.config4
12 files changed, 574 insertions, 358 deletions
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index c310a2c..66b6f5e 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -71,7 +71,7 @@ pitch_detector,apps
plasma,demos
png,viewers
pong,games
-ppmviewer,viewers
+ppm,viewers
properties,viewers
random_folder_advance_config,apps
remote_control,apps
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 3c4e9e1..7afd973 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -182,7 +182,6 @@ plasma.c
#ifdef HAVE_LCD_COLOR
clix.c
-ppmviewer.c
codebuster.c
#endif
diff --git a/apps/plugins/imageviewer/SUBDIRS b/apps/plugins/imageviewer/SUBDIRS
index 9d8da7d..0f8d953 100644
--- a/apps/plugins/imageviewer/SUBDIRS
+++ b/apps/plugins/imageviewer/SUBDIRS
@@ -1,3 +1,6 @@
bmp
jpeg
png
+#ifdef HAVE_LCD_COLOR
+ppm
+#endif
diff --git a/apps/plugins/imageviewer/image_decoder.c b/apps/plugins/imageviewer/image_decoder.c
index b4fa27e..553632e 100644
--- a/apps/plugins/imageviewer/image_decoder.c
+++ b/apps/plugins/imageviewer/image_decoder.c
@@ -27,6 +27,9 @@ static const char *decoder_names[MAX_IMAGE_TYPES] = {
"bmp",
"jpeg",
"png",
+#ifdef HAVE_LCD_COLOR
+ "ppm"
+#endif
};
/* check file type by extention */
@@ -41,6 +44,9 @@ enum image_type get_image_type(const char *name)
{ ".jpe", IMAGE_JPEG },
{ ".jpeg", IMAGE_JPEG },
{ ".png", IMAGE_PNG },
+#ifdef HAVE_LCD_COLOR
+ { ".ppm", IMAGE_PPM },
+#endif
};
const char *ext = rb->strrchr(name, '.');
diff --git a/apps/plugins/imageviewer/image_decoder.h b/apps/plugins/imageviewer/image_decoder.h
index 93608b1..1ccf9ca 100644
--- a/apps/plugins/imageviewer/image_decoder.h
+++ b/apps/plugins/imageviewer/image_decoder.h
@@ -29,6 +29,9 @@ enum image_type {
IMAGE_BMP = 0,
IMAGE_JPEG,
IMAGE_PNG,
+#ifdef HAVE_LCD_COLOR
+ IMAGE_PPM,
+#endif
MAX_IMAGE_TYPES
};
diff --git a/apps/plugins/imageviewer/ppm/SOURCES b/apps/plugins/imageviewer/ppm/SOURCES
new file mode 100644
index 0000000..492cca3
--- /dev/null
+++ b/apps/plugins/imageviewer/ppm/SOURCES
@@ -0,0 +1,2 @@
+ppm.c
+ppm_decoder.c
diff --git a/apps/plugins/imageviewer/ppm/ppm.c b/apps/plugins/imageviewer/ppm/ppm.c
new file mode 100644
index 0000000..100a00a
--- /dev/null
+++ b/apps/plugins/imageviewer/ppm/ppm.c
@@ -0,0 +1,233 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Marcin Bukat
+ *
+ * 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 "lcd.h"
+#include <lib/pluginlib_bmp.h>
+#include "../imageviewer.h"
+#include "ppm_decoder.h"
+#include "bmp.h"
+
+static char print[32]; /* use a common snprintf() buffer */
+
+/* decompressed image in the possible sizes (1,2,4,8), wasting the other */
+static unsigned char *disp[9];
+static unsigned char *disp_buf;
+static struct ppm_info ppm;
+
+#if defined(HAVE_LCD_COLOR)
+#define resize_bitmap smooth_resize_bitmap
+#else
+#define resize_bitmap grey_resize_bitmap
+#endif
+
+#if defined(USEGSLIB) && (CONFIG_PLATFORM & PLATFORM_HOSTED)
+/* hack: fix error "undefined reference to `_grey_info'". */
+GREY_INFO_STRUCT
+#endif /* USEGSLIB */
+
+static void draw_image_rect(struct image_info *info,
+ int x, int y, int width, int height)
+{
+ unsigned char **pdisp = (unsigned char **)info->data;
+
+#ifdef HAVE_LCD_COLOR
+ rb->lcd_bitmap_part((fb_data *)*pdisp, info->x + x, info->y + y,
+ STRIDE(SCREEN_MAIN, info->width, info->height),
+ x + MAX(0, (LCD_WIDTH-info->width)/2),
+ y + MAX(0, (LCD_HEIGHT-info->height)/2),
+ width, height);
+#else
+ mylcd_ub_gray_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);
+#endif
+}
+
+static int img_mem(int ds)
+{
+
+#ifdef USEGSLIB
+ return (ppm.x/ds) * (ppm.y/ds);
+#else
+ return (ppm.x/ds) * (ppm.y/ds) * FB_DATA_SZ;
+#endif
+}
+
+static int load_image(char *filename, struct image_info *info,
+ unsigned char *buf, ssize_t *buf_size)
+{
+ int fd;
+ int rc = PLUGIN_OK;
+ long time = 0; /* measured ticks */
+ int w, h; /* used to center output */
+
+ unsigned char *memory, *memory_max;
+ size_t memory_size, file_size;
+
+ /* cleanup */
+ memset(&disp, 0, sizeof(disp));
+
+ /* align buffer */
+ memory = (unsigned char *)((intptr_t)(buf + 3) & ~3);
+ memory_max = (unsigned char *)((intptr_t)(memory + *buf_size) & ~3);
+ memory_size = memory_max - memory;
+
+ fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ {
+ rb->splashf(HZ, "err opening %s: %d", filename, fd);
+ return PLUGIN_ERROR;
+ }
+
+ file_size = rb->filesize(fd);
+ DEBUGF("reading file '%s'\n", filename);
+
+ if (!iv->running_slideshow)
+ {
+ rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1);
+ rb->lcd_update();
+ }
+
+ if (!iv->running_slideshow)
+ {
+ rb->lcd_putsf(0, 1, "loading %zu bytes", file_size);
+ rb->lcd_update();
+ }
+
+ /* init decoder struct */
+ ppm.buf = memory;
+ ppm.buf_size = memory_size;
+
+ /* the actual decoding */
+ time = *rb->current_tick;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+ rc = read_ppm(fd, &ppm);
+ rb->cpu_boost(false);
+#else
+ rc = read_ppm(fd, &ppm);
+#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
+ time = *rb->current_tick - time;
+
+ /* close file descriptor */
+ rb->close(fd);
+
+ /* check return value from decoder */
+ if ( rc == PLUGIN_ERROR )
+ {
+ rb->splashf(HZ, "ppm decoder error");
+ return PLUGIN_ERROR;
+ }
+
+ if (!iv->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();
+ }
+
+ info->x_size = ppm.x;
+ info->y_size = ppm.y;
+
+ ppm.native_img_size = (ppm.native_img_size + 3) & ~3;
+ disp_buf = buf + ppm.native_img_size;
+ *buf_size = memory_max - disp_buf;
+
+ return PLUGIN_OK;
+}
+
+static int get_image(struct image_info *info, int ds)
+{
+ unsigned char **p_disp = &disp[ds]; /* short cut */
+ struct ppm_info *p_ppm = &ppm;
+
+ info->width = ppm.x / ds;
+ info->height = ppm.y / ds;
+ info->data = p_disp;
+
+ if (*p_disp != NULL)
+ {
+ /* we still have it */
+ return PLUGIN_OK;
+ }
+
+ /* assign image buffer */
+ if (ds > 1)
+ {
+ if (!iv->running_slideshow)
+ {
+ rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height);
+ rb->lcd_update();
+ }
+
+ struct bitmap bmp_src, bmp_dst;
+ int size = img_mem(ds);
+
+ if (disp_buf + size >= p_ppm->buf + p_ppm->buf_size)
+ {
+ /* have to discard the current */
+ int i;
+ for (i=1; i<=8; i++)
+ disp[i] = NULL; /* invalidate all bitmaps */
+
+ /* start again from the beginning of the buffer */
+ disp_buf = p_ppm->buf + p_ppm->native_img_size;
+ }
+
+ *p_disp = disp_buf;
+ disp_buf += size;
+
+ bmp_src.width = ppm.x;
+ bmp_src.height = ppm.y;
+ bmp_src.data = ppm.buf;
+
+ bmp_dst.width = info->width;
+ bmp_dst.height = info->height;
+ bmp_dst.data = *p_disp;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+ resize_bitmap(&bmp_src, &bmp_dst);
+ rb->cpu_boost(false);
+#else
+ resize_bitmap(&bmp_src, &bmp_dst);
+#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
+ }
+ else
+ {
+ *p_disp = p_ppm->buf;
+ }
+
+ return PLUGIN_OK;
+}
+
+const struct image_decoder image_decoder = {
+ true,
+ img_mem,
+ load_image,
+ get_image,
+ draw_image_rect,
+};
+
+IMGDEC_HEADER
diff --git a/apps/plugins/imageviewer/ppm/ppm.make b/apps/plugins/imageviewer/ppm/ppm.make
new file mode 100644
index 0000000..e77f282
--- /dev/null
+++ b/apps/plugins/imageviewer/ppm/ppm.make
@@ -0,0 +1,29 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+PPMSRCDIR := $(IMGVSRCDIR)/ppm
+PPMBUILDDIR := $(IMGVBUILDDIR)/ppm
+
+PPM_SRC := $(call preprocess, $(PPMSRCDIR)/SOURCES)
+PPM_OBJ := $(call c2obj, $(PPM_SRC))
+
+OTHER_SRC += $(PPM_SRC)
+
+ROCKS += $(PPMBUILDDIR)/ppm.ovl
+
+$(PPMBUILDDIR)/ppm.refmap: $(PPM_OBJ)
+$(PPMBUILDDIR)/ppm.link: $(PPM_OBJ) $(PPMBUILDDIR)/ppm.refmap
+$(PPMBUILDDIR)/ppm.ovl: $(PPM_OBJ)
+
+PPMFLAGS = $(IMGDECFLAGS) -Os
+
+# Compile PPM plugin with extra flags (adapted from ZXBox)
+$(PPMBUILDDIR)/%.o: $(PPMSRCDIR)/%.c $(PPMSRCDIR)/ppm.make
+ $(SILENT)mkdir -p $(dir $@)
+ $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(PPMFLAGS) -c $< -o $@
diff --git a/apps/plugins/imageviewer/ppm/ppm_decoder.c b/apps/plugins/imageviewer/ppm/ppm_decoder.c
new file mode 100644
index 0000000..44c4f92
--- /dev/null
+++ b/apps/plugins/imageviewer/ppm/ppm_decoder.c
@@ -0,0 +1,250 @@
+/*****************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
+ * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 Alexander Papst
+ *
+ * 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/pluginlib_bmp.h"
+#include "ppm_decoder.h"
+
+static int ppm_read_magic_number(int fd)
+{
+ char i1, i2;
+ if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1))
+ {
+ ppm_error( "Error reading magic number from ppm image stream. "\
+ "Most often, this means your input file is empty." );
+ return PLUGIN_ERROR;
+ }
+ return i1 * 256 + i2;
+}
+
+static char ppm_getc(int fd)
+{
+ char ch;
+
+ if (!rb->read(fd, &ch, 1)) {
+ ppm_error("EOF. Read error reading a byte");
+ return PLUGIN_ERROR;
+ }
+
+ if (ch == '#') {
+ do {
+ if (!rb->read(fd, &ch, 1)) {
+ ppm_error("EOF. Read error reading a byte");
+ return PLUGIN_ERROR;
+ }
+ } while (ch != '\n' && ch != '\r');
+ }
+ return ch;
+}
+
+static int ppm_getuint(int fd)
+{
+ char ch;
+ int i;
+ int digitVal;
+
+ do {
+ ch = ppm_getc(fd);
+ } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
+
+ if (ch < '0' || ch > '9') {
+ ppm_error("Junk (%c) in file where an integer should be.", ch);
+ return PLUGIN_ERROR;
+ }
+
+ i = 0;
+
+ do {
+ digitVal = ch - '0';
+
+ if (i > INT_MAX/10 - digitVal) {
+ ppm_error("ASCII decimal integer in file is "\
+ "too large to be processed.");
+ return PLUGIN_ERROR;
+ }
+
+ i = i * 10 + digitVal;
+ ch = ppm_getc(fd);
+
+ } while (ch >= '0' && ch <= '9');
+
+ return i;
+}
+
+static int ppm_getrawbyte(int fd)
+{
+ unsigned char by;
+
+ if (!rb->read(fd, &by, 1)) {
+ ppm_error("EOF. Read error while reading a one-byte sample.");
+ return PLUGIN_ERROR;
+ }
+
+ return (int)by;
+}
+
+static int ppm_getrawsample(int fd, int const maxval)
+{
+ if (maxval < 256) {
+ /* The sample is just one byte. Read it. */
+ return(ppm_getrawbyte(fd));
+ } else {
+ /* The sample is two bytes. Read both. */
+ unsigned char byte_pair[2];
+
+ if (!rb->read(fd, byte_pair, 2)) {
+ ppm_error("EOF. Read error while reading a long sample.");
+ return PLUGIN_ERROR;
+ }
+ return((byte_pair[0]<<8) | byte_pair[1]);
+ }
+}
+
+/* Read from the file header dimensions as well as max
+ * int value used
+ */
+static int read_ppm_init_rest(int fd, struct ppm_info *ppm)
+{
+ /* Read size. */
+ ppm->x = ppm_getuint(fd);
+ ppm->y = ppm_getuint(fd);
+
+#ifdef HAVE_LCD_COLOR
+ ppm->native_img_size = ppm->x * ppm->y * FB_DATA_SZ;
+#endif
+
+ if (ppm->native_img_size > ppm->buf_size) {
+ ppm_error("Imagesize (%ld pixels) is too large. "\
+ "The maximum allowed is %ld.",
+ (long)ppm->native_img_size,
+ (long)ppm->buf_size);
+ return PLUGIN_ERROR;
+ }
+
+ /* Read maxval. */
+ ppm->maxval = ppm_getuint(fd);
+
+ if (ppm->maxval > PPM_OVERALLMAXVAL) {
+ ppm_error("maxval of input image (%u) is too large. "\
+ "The maximum allowed by the PPM is %u.",
+ ppm->maxval, PPM_OVERALLMAXVAL);
+ return PLUGIN_ERROR;
+ }
+ if (ppm->maxval == 0) {
+ ppm_error("maxval of input image is zero.");
+ return PLUGIN_ERROR;
+ }
+ return 1;
+}
+
+static void read_ppm_init(int fd, struct ppm_info *ppm)
+{
+ /* Check magic number. */
+ ppm->format = ppm_read_magic_number( fd );
+
+ if (ppm->format == PLUGIN_ERROR) return;
+ switch (ppm->format) {
+ case PPM_FORMAT:
+ case RPPM_FORMAT:
+ if(read_ppm_init_rest(fd, ppm) == PLUGIN_ERROR) {
+ ppm->format = PLUGIN_ERROR;
+ }
+ break;
+
+ default:
+ ppm_error( "Bad magic number - not a ppm or rppm file." );
+ ppm->format = PLUGIN_ERROR;
+ }
+}
+
+#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+#define BUFADDR(x, y, width, height) ( ppm->buf + (height*(x) + (y))*FB_DATA_SZ)
+#else
+#define BUFADDR(x, y, width, height) ( ppm->buf + (width*(y) + (x))*FB_DATA_SZ)
+#endif
+
+static int read_ppm_row(int fd, struct ppm_info *ppm, int row)
+{
+
+ int col;
+ int r, g, b;
+ switch (ppm->format) {
+ case PPM_FORMAT:
+ for (col = 0; col < ppm->x; ++col) {
+ r = ppm_getuint(fd);
+ g = ppm_getuint(fd);
+ b = ppm_getuint(fd);
+
+ if (r == PLUGIN_ERROR || g == PLUGIN_ERROR ||
+ b == PLUGIN_ERROR)
+ {
+ return PLUGIN_ERROR;
+ }
+ *(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK(
+ (255 * r)/ppm->maxval,
+ (255 * g)/ppm->maxval,
+ (255 * b)/ppm->maxval);
+ }
+ break;
+
+ case RPPM_FORMAT:
+ for (col = 0; col < ppm->x; ++col) {
+ r = ppm_getrawsample(fd, ppm->maxval);
+ g = ppm_getrawsample(fd, ppm->maxval);
+ b = ppm_getrawsample(fd, ppm->maxval);
+
+ if (r == PLUGIN_ERROR || g == PLUGIN_ERROR ||
+ b == PLUGIN_ERROR)
+ {
+ return PLUGIN_ERROR;
+ }
+ *(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK(
+ (255 * r)/ppm->maxval,
+ (255 * g)/ppm->maxval,
+ (255 * b)/ppm->maxval);
+ }
+ break;
+
+ default:
+ ppm_error("What?!");
+ return PLUGIN_ERROR;
+ }
+ return 1;
+}
+
+/* public */
+int read_ppm(int fd, struct ppm_info *ppm)
+{
+ int row;
+
+ read_ppm_init(fd, ppm);
+
+ if(ppm->format == PLUGIN_ERROR) {
+ return PLUGIN_ERROR;
+ }
+
+ for (row = 0; row < ppm->y; ++row) {
+ if( read_ppm_row(fd, ppm, row) == PLUGIN_ERROR) {
+ return PLUGIN_ERROR;
+ }
+ }
+ return 1;
+}
diff --git a/apps/plugins/imageviewer/ppm/ppm_decoder.h b/apps/plugins/imageviewer/ppm/ppm_decoder.h
new file mode 100644
index 0000000..edd1bcb
--- /dev/null
+++ b/apps/plugins/imageviewer/ppm/ppm_decoder.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Marcin Bukat
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* Magic constants. */
+#define PPM_MAGIC1 'P'
+#define PPM_MAGIC2 '3'
+#define RPPM_MAGIC2 '6'
+#define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2)
+#define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2)
+
+#define PPM_OVERALLMAXVAL 65535
+
+#define ppm_error(...) rb->splashf(HZ*2, __VA_ARGS__ )
+
+struct ppm_info {
+ int x;
+ int y;
+ int maxval;
+ int format;
+ unsigned char *buf;
+ size_t buf_size;
+ unsigned int native_img_size;
+};
+
+/* public prototype */
+int read_ppm(int fd, struct ppm_info *ppm);
diff --git a/apps/plugins/ppmviewer.c b/apps/plugins/ppmviewer.c
deleted file mode 100644
index e138692..0000000
--- a/apps/plugins/ppmviewer.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*****************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
- * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2008 Alexander Papst
- *
- * 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/pluginlib_bmp.h"
-
-/* Magic constants. */
-#define PPM_MAGIC1 'P'
-#define PPM_MAGIC2 '3'
-#define RPPM_MAGIC2 '6'
-#define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2)
-#define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2)
-
-#define PPM_OVERALLMAXVAL 65535
-#define PPM_MAXSIZE (300*1024)/sizeof(fb_data)
-
-#define ppm_error(...) rb->splashf(HZ*2, __VA_ARGS__ )
-
-static fb_data *buffer, *lcd_buf;
-
-int ppm_read_magic_number(int fd)
-{
- char i1, i2;
- if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1))
- {
- ppm_error( "Error reading magic number from ppm image stream. "\
- "Most often, this means your input file is empty." );
- return PLUGIN_ERROR;
- }
- return i1 * 256 + i2;
-}
-
-char ppm_getc(int fd)
-{
- char ch;
-
- if (!rb->read(fd, &ch, 1)) {
- ppm_error("EOF. Read error reading a byte");
- return PLUGIN_ERROR;
- }
-
- if (ch == '#') {
- do {
- if (!rb->read(fd, &ch, 1)) {
- ppm_error("EOF. Read error reading a byte");
- return PLUGIN_ERROR;
- }
- } while (ch != '\n' && ch != '\r');
- }
- return ch;
-}
-
-int ppm_getuint(int fd)
-{
- char ch;
- int i;
- int digitVal;
-
- do {
- ch = ppm_getc(fd);
- } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
-
- if (ch < '0' || ch > '9') {
- ppm_error("Junk (%c) in file where an integer should be.", ch);
- return PLUGIN_ERROR;
- }
-
- i = 0;
-
- do {
- digitVal = ch - '0';
-
- if (i > INT_MAX/10 - digitVal) {
- ppm_error("ASCII decimal integer in file is "\
- "too large to be processed.");
- return PLUGIN_ERROR;
- }
-
- i = i * 10 + digitVal;
- ch = ppm_getc(fd);
-
- } while (ch >= '0' && ch <= '9');
-
- return i;
-}
-
-int ppm_getrawbyte(int fd)
-{
- unsigned char by;
-
- if (!rb->read(fd, &by, 1)) {
- ppm_error("EOF. Read error while reading a one-byte sample.");
- return PLUGIN_ERROR;
- }
-
- return (int)by;
-}
-
-int ppm_getrawsample(int fd, int const maxval)
-{
- if (maxval < 256) {
- /* The sample is just one byte. Read it. */
- return(ppm_getrawbyte(fd));
- } else {
- /* The sample is two bytes. Read both. */
- unsigned char byte_pair[2];
-
- if (!rb->read(fd, byte_pair, 2)) {
- ppm_error("EOF. Read error while reading a long sample.");
- return PLUGIN_ERROR;
- }
- return((byte_pair[0]<<8) | byte_pair[1]);
- }
-}
-
-int read_ppm_init_rest(int fd,
- int * const cols,
- int * const rows,
- int * const maxval)
-{
- /* Read size. */
- *cols = ppm_getuint(fd);
- *rows = ppm_getuint(fd);
-
- if ((long unsigned int)(*cols * *rows) > PPM_MAXSIZE) {
- ppm_error("Imagesize (%ld pixels) is too large. "\
- "The maximum allowed is %ld.",
- (long unsigned int)(*cols * *rows),
- (long unsigned int)PPM_MAXSIZE);
- return PLUGIN_ERROR;
- }
-
- /* Read maxval. */
- *maxval = ppm_getuint(fd);
-
- if (*maxval > PPM_OVERALLMAXVAL) {
- ppm_error("maxval of input image (%u) is too large. "\
- "The maximum allowed by the PPM is %u.",
- *maxval, PPM_OVERALLMAXVAL);
- return PLUGIN_ERROR;
- }
- if (*maxval == 0) {
- ppm_error("maxval of input image is zero.");
- return PLUGIN_ERROR;
- }
- return 1;
-}
-
-void read_ppm_init(int fd,
- int * const cols,
- int * const rows,
- int * const maxval,
- int * const format)
-{
- /* Check magic number. */
- *format = ppm_read_magic_number( fd );
-
- if (*format == PLUGIN_ERROR) return;
- switch (*format) {
- case PPM_FORMAT:
- case RPPM_FORMAT:
- if(read_ppm_init_rest(fd, cols, rows, maxval) == PLUGIN_ERROR) {
- *format = PLUGIN_ERROR;
- }
- break;
-
- default:
- ppm_error( "Bad magic number - not a ppm or rppm file." );
- *format = PLUGIN_ERROR;
- }
-}
-
-#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
-#define BUFADDR(x, y, width, height) ( buffer + height*(x) + (y))
-#else
-#define BUFADDR(x, y, width, height) ( buffer + width*(y) + (x))
-#endif
-
-int read_ppm_row(int fd,
- int const row,
- int const cols,
- int const rows,
- int const maxval,
- int const format)
-{
-#if !(defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE)
- (void) rows;
-#endif
-
- int col;
- int r, g, b;
- switch (format) {
- case PPM_FORMAT:
- for (col = 0; col < cols; ++col) {
- r = ppm_getuint(fd);
- g = ppm_getuint(fd);
- b = ppm_getuint(fd);
-
- if (r == PLUGIN_ERROR || g == PLUGIN_ERROR ||
- b == PLUGIN_ERROR)
- {
- return PLUGIN_ERROR;
- }
- *BUFADDR(col, row, cols, rows) = LCD_RGBPACK(
- (255 / maxval) * r,
- (255 / maxval) * g,
- (255 / maxval) * b);
- }
- break;
-
- case RPPM_FORMAT:
- for (col = 0; col < cols; ++col) {
- r = ppm_getrawsample(fd, maxval);
- g = ppm_getrawsample(fd, maxval);
- b = ppm_getrawsample(fd, maxval);
-
- if (r == PLUGIN_ERROR || g == PLUGIN_ERROR ||
- b == PLUGIN_ERROR)
- {
- return PLUGIN_ERROR;
- }
- *BUFADDR(col, row, cols, rows) = LCD_RGBPACK(
- (255 / maxval) * r,
- (255 / maxval) * g,
- (255 / maxval) * b);
- }
- break;
-
- default:
- ppm_error("What?!");
- return PLUGIN_ERROR;
- }
- return 1;
-}
-
-int read_ppm(int fd,
- int * const cols,
- int * const rows,
- int * const maxval)
-{
- int row;
- int format;
-
- read_ppm_init(fd, cols, rows, maxval, &format);
-
- if(format == PLUGIN_ERROR) {
- return PLUGIN_ERROR;
- }
-
- for (row = 0; row < *rows; ++row) {
- if( read_ppm_row(fd, row, *cols, *rows, *maxval, format) == PLUGIN_ERROR) {
- return PLUGIN_ERROR;
- }
- }
- return 1;
-}
-
-/* this is the plugin entry point */
-enum plugin_status plugin_start(const void* parameter)
-{
- static char filename[MAX_PATH];
- int fd;
-
- int cols;
- int rows;
- int maxval;
-
- int result;
-
- struct bitmap small_bitmap, orig_bitmap;
-
- if(!parameter) return PLUGIN_ERROR;
-
- size_t buffer_size;
- char *audiobuf = rb->plugin_get_buffer(&buffer_size);
- if (buffer_size < PPM_MAXSIZE + LCD_WIDTH * LCD_HEIGHT + 1)
- {
- /* steal from audiobuffer if plugin buffer is too small */
- audiobuf = rb->plugin_get_audio_buffer(&buffer_size);
-
- if (buffer_size < PPM_MAXSIZE + LCD_WIDTH * LCD_HEIGHT + 1)
- {
- rb->splash(HZ, "Not enough memory");
- return PLUGIN_ERROR;
- }
- }
-
- /* align on 16 bits */
- audiobuf = (char *)(((uintptr_t)audiobuf + 1) & ~1);
- buffer = (fb_data *)audiobuf;
- lcd_buf = (fb_data*) (audiobuf + PPM_MAXSIZE);
-
- rb->strcpy(filename, parameter);
-
- fd = rb->open(filename, O_RDONLY);
- if (fd < 0)
- {
- ppm_error("Couldnt open file: %s, %d", filename, fd);
- return PLUGIN_ERROR;
- }
-
- result = read_ppm(fd, &cols, &rows, &maxval);
-
- rb->close(fd);
- if(result == PLUGIN_ERROR) return PLUGIN_ERROR;
-
- orig_bitmap.width = cols;
- orig_bitmap.height = rows;
- orig_bitmap.data = (char*)buffer;
-
- if (cols > LCD_WIDTH || rows > LCD_HEIGHT)
- {
- if (cols > LCD_WIDTH) {
- small_bitmap.width = LCD_WIDTH;
- small_bitmap.height =
- (int)(((float)LCD_WIDTH / (float)cols) * (float)rows);
-
- } else { /* rows > LCD_HEIGHT */
-
- small_bitmap.width =
- (int)(((float)LCD_HEIGHT / (float)rows) * (float)cols);
- small_bitmap.height = LCD_HEIGHT;
- }
- small_bitmap.data = (char*)lcd_buf;
-
- smooth_resize_bitmap( &orig_bitmap, &small_bitmap );
-
- rb->lcd_bitmap((fb_data*)small_bitmap.data, 0, 0,
- small_bitmap.width, small_bitmap.height);
- } else {
- rb->lcd_bitmap((fb_data*)orig_bitmap.data, 0, 0, cols, rows);
- }
- rb->lcd_update();
- rb->button_get(true);
-
- return PLUGIN_OK;
-}
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 0170883..ed2f68a 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -20,6 +20,9 @@ jpeg,viewers/test_core_jpeg,-
jpeg,viewers/test_mem_jpeg,-
jpeg,viewers/bench_mem_jpeg,-
png,viewers/imageviewer,2
+#ifdef HAVE_LCD_COLOR
+ppm,viewers/imageviewer,2
+#endif
ucl,viewers/rockbox_flash,3
rvf,viewers/video,4
mp3,viewers/vbrfix,5
@@ -73,7 +76,6 @@ tap,viewers/zxbox,12
sna,viewers/zxbox,12
tzx,viewers/zxbox,12
z80,viewers/zxbox,12
-ppm,viewers/ppmviewer,2
cfg,viewers/theme_remove,-
*,viewers/properties,-
*,viewers/shortcuts_append,-