image viewer: ppm:

* return proper error code when image is too large.
* check return value of read() properly.
* display progressbar.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29090 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Teruaki Kawashima 2011-01-19 12:51:57 +00:00
parent d1ff237798
commit 622be891b3
3 changed files with 56 additions and 64 deletions

View file

@ -106,11 +106,6 @@ static int load_image(char *filename, struct image_info *info,
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();
}
@ -130,14 +125,11 @@ static int load_image(char *filename, struct image_info *info,
#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 )
if (rc != PLUGIN_OK)
{
rb->splashf(HZ, "ppm decoder error");
return PLUGIN_ERROR;
return rc;
}
if (!iv->running_slideshow)

View file

@ -18,12 +18,10 @@ OTHER_SRC += $(PPM_SRC)
ROCKS += $(PPMBUILDDIR)/ppm.ovl
$(PPMBUILDDIR)/ppm.refmap: $(PPM_OBJ)
$(PPMBUILDDIR)/ppm.link: $(PPM_OBJ) $(PPMBUILDDIR)/ppm.refmap
$(PPMBUILDDIR)/ppm.link: $(PLUGIN_LDS) $(PPMBUILDDIR)/ppm.refmap
$(PPMBUILDDIR)/ppm.ovl: $(PPM_OBJ)
PPMFLAGS = $(IMGDECFLAGS) -Os
# Compile PPM plugin with extra flags (adapted from ZXBox)
# special pattern rule for compiling image decoder with extra flags
$(PPMBUILDDIR)/%.o: $(PPMSRCDIR)/%.c $(PPMSRCDIR)/ppm.make
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(PPMFLAGS) -c $< -o $@
$(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(IMGDECFLAGS) -c $< -o $@

View file

@ -22,42 +22,43 @@
#include "plugin.h"
#include "lib/pluginlib_bmp.h"
#include "ppm_decoder.h"
#include "../imageviewer.h"
static int ppm_read_magic_number(int fd)
{
char i1, i2;
if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1))
unsigned char i1, i2;
if(rb->read(fd, &i1, 1) < 1 || rb->read(fd, &i2, 1) < 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)
static int ppm_getc(int fd)
{
char ch;
unsigned char ch;
if (!rb->read(fd, &ch, 1)) {
if (rb->read(fd, &ch, 1) < 1) {
ppm_error("EOF. Read error reading a byte");
return PLUGIN_ERROR;
}
if (ch == '#') {
do {
if (!rb->read(fd, &ch, 1)) {
if (rb->read(fd, &ch, 1) < 1) {
ppm_error("EOF. Read error reading a byte");
return PLUGIN_ERROR;
}
} while (ch != '\n' && ch != '\r');
}
return ch;
return (int)ch;
}
static int ppm_getuint(int fd)
{
char ch;
int ch;
int i;
int digitVal;
@ -65,6 +66,7 @@ static int ppm_getuint(int fd)
ch = ppm_getc(fd);
} while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
if (ch == PLUGIN_ERROR) return PLUGIN_ERROR;
if (ch < '0' || ch > '9') {
ppm_error("Junk (%c) in file where an integer should be.", ch);
return PLUGIN_ERROR;
@ -83,8 +85,9 @@ static int ppm_getuint(int fd)
i = i * 10 + digitVal;
ch = ppm_getc(fd);
} while (ch >= '0' && ch <= '9');
if (ch == PLUGIN_ERROR) return PLUGIN_ERROR;
return i;
}
@ -93,7 +96,7 @@ static int ppm_getrawbyte(int fd)
{
unsigned char by;
if (!rb->read(fd, &by, 1)) {
if (rb->read(fd, &by, 1) < 1) {
ppm_error("EOF. Read error while reading a one-byte sample.");
return PLUGIN_ERROR;
}
@ -110,7 +113,7 @@ static int ppm_getrawsample(int fd, int const maxval)
/* The sample is two bytes. Read both. */
unsigned char byte_pair[2];
if (!rb->read(fd, byte_pair, 2)) {
if (rb->read(fd, byte_pair, 2) < 2) {
ppm_error("EOF. Read error while reading a long sample.");
return PLUGIN_ERROR;
}
@ -132,16 +135,12 @@ static int read_ppm_init_rest(int fd, struct ppm_info *ppm)
#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;
return PLUGIN_OUTOFMEM;
}
/* 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.",
@ -152,40 +151,40 @@ static int read_ppm_init_rest(int fd, struct ppm_info *ppm)
ppm_error("maxval of input image is zero.");
return PLUGIN_ERROR;
}
return 1;
return PLUGIN_OK;
}
static void read_ppm_init(int fd, struct ppm_info *ppm)
static int 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;
if (ppm->format == PLUGIN_ERROR) return PLUGIN_ERROR;
switch (ppm->format) {
case PPM_FORMAT:
case RPPM_FORMAT:
if(read_ppm_init_rest(fd, ppm) == PLUGIN_ERROR) {
ppm->format = PLUGIN_ERROR;
}
break;
return read_ppm_init_rest(fd, ppm);
default:
ppm_error( "Bad magic number - not a ppm or rppm file." );
ppm->format = PLUGIN_ERROR;
return PLUGIN_ERROR;
}
return PLUGIN_OK;
}
#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)
static int read_ppm_row(int fd, struct ppm_info *ppm, int row)
{
int col;
int r, g, b;
#ifdef HAVE_LCD_COLOR
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
fb_data *dst = (fb_data *) ppm->buf + row;
const int stride = ppm->x;
#else
fb_data *dst = (fb_data *) ppm->buf + ppm->x*row;
const int stride = 1;
#endif
#endif /* HAVE_LCD_COLOR */
switch (ppm->format) {
case PPM_FORMAT:
for (col = 0; col < ppm->x; ++col) {
@ -197,11 +196,12 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row)
b == PLUGIN_ERROR)
{
return PLUGIN_ERROR;
}
*(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK(
}
*dst = LCD_RGBPACK(
(255 * r)/ppm->maxval,
(255 * g)/ppm->maxval,
(255 * b)/ppm->maxval);
dst += stride;
}
break;
@ -216,10 +216,11 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row)
{
return PLUGIN_ERROR;
}
*(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK(
*dst = LCD_RGBPACK(
(255 * r)/ppm->maxval,
(255 * g)/ppm->maxval,
(255 * b)/ppm->maxval);
dst += stride;
}
break;
@ -227,24 +228,25 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row)
ppm_error("What?!");
return PLUGIN_ERROR;
}
return 1;
return PLUGIN_OK;
}
/* public */
int read_ppm(int fd, struct ppm_info *ppm)
{
int row;
int row, ret;
read_ppm_init(fd, ppm);
if(ppm->format == PLUGIN_ERROR) {
return PLUGIN_ERROR;
ret = read_ppm_init(fd, ppm);
if(ret != PLUGIN_OK) {
return ret;
}
for (row = 0; row < ppm->y; ++row) {
if( read_ppm_row(fd, ppm, row) == PLUGIN_ERROR) {
return PLUGIN_ERROR;
ret = read_ppm_row(fd, ppm, row);
if(ret != PLUGIN_OK) {
return ret;
}
iv->cb_progress(row, ppm->y);
}
return 1;
return PLUGIN_OK;
}