From 622be891b3fbf251c1a8f8c53a134a1092747bec Mon Sep 17 00:00:00 2001 From: Teruaki Kawashima Date: Wed, 19 Jan 2011 12:51:57 +0000 Subject: [PATCH] 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 --- apps/plugins/imageviewer/ppm/ppm.c | 12 +-- apps/plugins/imageviewer/ppm/ppm.make | 8 +- apps/plugins/imageviewer/ppm/ppm_decoder.c | 100 +++++++++++---------- 3 files changed, 56 insertions(+), 64 deletions(-) diff --git a/apps/plugins/imageviewer/ppm/ppm.c b/apps/plugins/imageviewer/ppm/ppm.c index 100a00ac84..20200d812e 100644 --- a/apps/plugins/imageviewer/ppm/ppm.c +++ b/apps/plugins/imageviewer/ppm/ppm.c @@ -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) diff --git a/apps/plugins/imageviewer/ppm/ppm.make b/apps/plugins/imageviewer/ppm/ppm.make index e77f282723..b98ee62832 100644 --- a/apps/plugins/imageviewer/ppm/ppm.make +++ b/apps/plugins/imageviewer/ppm/ppm.make @@ -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 $@ diff --git a/apps/plugins/imageviewer/ppm/ppm_decoder.c b/apps/plugins/imageviewer/ppm/ppm_decoder.c index 44c4f9232e..be459293fe 100644 --- a/apps/plugins/imageviewer/ppm/ppm_decoder.c +++ b/apps/plugins/imageviewer/ppm/ppm_decoder.c @@ -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; }