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:
parent
d1ff237798
commit
622be891b3
3 changed files with 56 additions and 64 deletions
|
@ -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)
|
||||
|
|
|
@ -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 $@
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue