summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2009-12-18 13:06:21 +0000
committerTeruaki Kawashima <teru@rockbox.org>2009-12-18 13:06:21 +0000
commit3e2aba0c3eded353ba119e5df23968d70b1263c5 (patch)
tree56ff071a728f451afd7a1f7e091bd201db85f11a
parentd42cdfd91c581d20a4e895a73e5fdc8830693ba2 (diff)
downloadrockbox-3e2aba0c3eded353ba119e5df23968d70b1263c5.tar.gz
rockbox-3e2aba0c3eded353ba119e5df23968d70b1263c5.zip
jpeg,png: Separate code to load file from load_and_show().
Add a way to abort loading to jpeg inspired by png. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24075 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/jpeg/jpeg.c224
-rw-r--r--apps/plugins/png/png.c438
-rw-r--r--apps/plugins/png/png.h10
3 files changed, 362 insertions, 310 deletions
diff --git a/apps/plugins/jpeg/jpeg.c b/apps/plugins/jpeg/jpeg.c
index 1049e4827e..e524b0cffd 100644
--- a/apps/plugins/jpeg/jpeg.c
+++ b/apps/plugins/jpeg/jpeg.c
@@ -69,7 +69,9 @@ GREY_INFO_STRUCT
#define DIR_NEXT -1
#define DIR_NONE 0
-#define PLUGIN_OTHER 10 /* State code for output with return. */
+#define PLUGIN_OTHER 10 /* State code for output with return. */
+#define PLUGIN_ABORT 11
+#define PLUGIN_OUTOFMEM 12
/******************************* Globals ***********************************/
@@ -105,25 +107,25 @@ struct jpeg_settings
};
static struct jpeg_settings jpeg_settings =
- {
+{
#ifdef HAVE_LCD_COLOR
- COLOURMODE_COLOUR,
- DITHER_NONE,
+ COLOURMODE_COLOUR,
+ DITHER_NONE,
#endif
- SS_DEFAULT_TIMEOUT
- };
+ SS_DEFAULT_TIMEOUT
+};
static struct jpeg_settings old_settings;
static struct configdata jpeg_config[] =
{
#ifdef HAVE_LCD_COLOR
- { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &jpeg_settings.colour_mode },
- "Colour Mode", (char *[]){ "Colour", "Grayscale" } },
- { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &jpeg_settings.dither_mode },
- "Dither Mode", (char *[]){ "None", "Ordered", "Diffusion" } },
+ { TYPE_ENUM, 0, COLOUR_NUM_MODES, { .int_p = &jpeg_settings.colour_mode },
+ "Colour Mode", (char *[]){ "Colour", "Grayscale" } },
+ { TYPE_ENUM, 0, DITHER_NUM_MODES, { .int_p = &jpeg_settings.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 },
+ { TYPE_INT, SS_MIN_TIMEOUT, SS_MAX_TIMEOUT,
+ { .int_p = &jpeg_settings.ss_timeout }, "Slideshow Time", NULL },
};
#if LCD_DEPTH > 1
@@ -526,8 +528,8 @@ static void pan_view_down(struct t_disp* pdisp)
*/
move++, pdisp->y--;
rb->memcpy(rgb_linebuf,
- rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
- LCD_WIDTH*sizeof (fb_data));
+ rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
+ LCD_WIDTH*sizeof (fb_data));
}
#endif
@@ -538,8 +540,7 @@ static void pan_view_down(struct t_disp* pdisp)
{
/* 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));
+ rgb_linebuf, LCD_WIDTH*sizeof (fb_data));
pdisp->y++;
}
#endif
@@ -557,7 +558,8 @@ int scroll_bmp(struct t_disp* pdisp)
{
if (slideshow_enabled)
button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ);
- else button = rb->button_get(true);
+ else
+ button = rb->button_get(true);
running_slideshow = false;
@@ -737,6 +739,86 @@ 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)
@@ -755,7 +837,7 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
/* assign image buffer */
- /* physical size needed for decoding */
+ /* physical size needed for decoding */
size = jpegmem(p_jpg, ds);
if (buf_images_size <= size)
{ /* have to discard the current */
@@ -856,7 +938,6 @@ void set_view (struct t_disp* p_disp, int cx, int cy)
p_disp->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)
{
@@ -864,37 +945,30 @@ void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy)
*p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2;
}
-
/* load, decode, display the image */
int load_and_show(char* filename)
{
- int fd;
- int filesize;
- unsigned char* buf_jpeg; /* compressed JPEG image */
int status;
struct t_disp* p_disp; /* currenly displayed image */
int cx, cy; /* view center */
- fd = rb->open(filename, O_RDONLY);
- if (fd < 0)
- {
- rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
- rb->splash(HZ, print);
- return PLUGIN_ERROR;
- }
- filesize = rb->filesize(fd);
- rb->memset(&disp, 0, sizeof(disp));
+#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();
- /* allocate JPEG buffer */
- buf_jpeg = buf;
+ rb->memset(&disp, 0, sizeof(disp));
+ rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
- /* we can start the decompressed images behind it */
- buf_images = buf_root = buf + filesize;
- buf_images_size = root_size = buf_size - filesize;
+ if (rb->button_get(false) == JPEG_MENU)
+ status = PLUGIN_ABORT;
+ else
+ status = load_image(filename, &jpg);
- if (buf_images_size <= 0)
+ if (status == PLUGIN_OUTOFMEM)
{
- rb->close(fd);
#if PLUGIN_BUFFER_SIZE >= MIN_MEM
if(plug_buf)
{
@@ -944,9 +1018,9 @@ int load_and_show(char* filename)
}
break;
default:
- if(rb->default_event_handler_ex(button, cleanup, NULL)
+ if(rb->default_event_handler_ex(button, cleanup, NULL)
== SYS_USB_CONNECTED)
- return PLUGIN_USB_CONNECTED;
+ return PLUGIN_USB_CONNECTED;
}
}
@@ -955,66 +1029,20 @@ int load_and_show(char* filename)
#endif
{
rb->splash(HZ, "Out of Memory");
- return PLUGIN_ERROR;
+ file_pt[curfile] = NULL;
+ return change_filename(direction);
}
}
-
- if(!running_slideshow)
+ else if (status == PLUGIN_ERROR)
{
-#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();
- 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
-
- rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
- /* process markers, unstuffing */
- status = process_markers(buf_jpeg, filesize, &jpg);
-
- if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0))
- { /* bad format or minimum components not contained */
- rb->splashf(HZ, "unsupported %d", status);
file_pt[curfile] = NULL;
return change_filename(direction);
}
-
- if (!(status & DHT)) /* if no Huffman table present: */
- default_huff_tbl(&jpg); /* use default */
- build_lut(&jpg); /* derive Huffman and other lookup-tables */
-
- if(!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "image %dx%d", jpg.x_size, jpg.y_size);
- rb->lcd_puts(0, 2, print);
- rb->lcd_update();
+ else if (status == PLUGIN_ABORT) {
+ rb->splash(HZ, "aborted");
+ return PLUGIN_OK;
}
+
ds_max = max_downscale(&jpg); /* check display constraint */
ds_min = min_downscale(&jpg, buf_images_size); /* check memory constraint */
if (ds_min == 0)
@@ -1023,6 +1051,8 @@ int load_and_show(char* filename)
file_pt[curfile] = NULL;
return change_filename(direction);
}
+ else if (ds_max < ds_min)
+ ds_max = ds_min;
ds = ds_max; /* initialize setting */
cx = jpg.x_size/ds/2; /* center the view */
@@ -1096,7 +1126,7 @@ int load_and_show(char* filename)
rb->lcd_clear_display();
}
while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED
- && status != PLUGIN_OTHER);
+ && status != PLUGIN_OTHER);
#ifdef USEGSLIB
rb->lcd_update();
#endif
@@ -1158,8 +1188,8 @@ enum plugin_status plugin_start(const void* parameter)
do
{
condition = load_and_show(np_file);
- }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
- && condition != PLUGIN_ERROR);
+ } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
+ && condition != PLUGIN_ERROR);
if (rb->memcmp(&jpeg_settings, &old_settings, sizeof (jpeg_settings)))
{
diff --git a/apps/plugins/png/png.c b/apps/plugins/png/png.c
index e24434fc72..9e3b780907 100644
--- a/apps/plugins/png/png.c
+++ b/apps/plugins/png/png.c
@@ -260,7 +260,7 @@ static unsigned LodePNG_decompress(unsigned char* out, size_t* outsize, const un
z_stream stream;
int err;
- error_msg = "";
+ rb->strcpy(error_msg, "");
stream.next_in = (Bytef*)in;
stream.avail_in = (uInt)insize;
@@ -284,7 +284,8 @@ static unsigned LodePNG_decompress(unsigned char* out, size_t* outsize, const un
*outsize = stream.total_out;
err = inflateEnd(&stream);
- error_msg = stream.msg;
+ if (stream.msg != Z_NULL)
+ rb->strcpy(error_msg, stream.msg);
return err;
}
@@ -1324,6 +1325,60 @@ void LodePNG_Decoder_cleanup(LodePNG_Decoder* decoder)
LodePNG_InfoPng_cleanup(&decoder->infoPng);
}
+#define PNG_ERROR_MIN 27
+#define PNG_ERROR_MAX 74
+static const unsigned char *png_error_messages[PNG_ERROR_MAX-PNG_ERROR_MIN+1] =
+{
+ "png file smaller than a png header", /*27*/
+ "incorrect png signature", /*28*/
+ "first chunk is not IHDR", /*29*/
+ "chunk length too large", /*30*/
+ "illegal PNG color type or bpp", /*31*/
+ "illegal PNG compression method", /*32*/
+ "illegal PNG filter method", /*33*/
+ "illegal PNG interlace method", /*34*/
+ "chunk length of a chunk is too large or the chunk too small", /*35*/
+ "illegal PNG filter type encountered", /*36*/
+ "illegal bit depth for this color type given", /*37*/
+ "the palette is too big (more than 256 colors)", /*38*/
+ "more palette alpha values given in tRNS, than there are colors in the palette", /*39*/
+ "tRNS chunk has wrong size for greyscale image", /*40*/
+ "tRNS chunk has wrong size for RGB image", /*41*/
+ "tRNS chunk appeared while it was not allowed for this color type", /*42*/
+ "bKGD chunk has wrong size for palette image", /*43*/
+ "bKGD chunk has wrong size for greyscale image", /*44*/
+ "bKGD chunk has wrong size for RGB image", /*45*/
+ "value encountered in indexed image is larger than the palette size", /*46*/
+ "value encountered in indexed image is larger than the palette size", /*47*/
+ "input file is empty", /*48*/
+ NULL, /*49*/
+ NULL, /*50*/
+ NULL, /*51*/
+ NULL, /*52*/
+ NULL, /*53*/
+ NULL, /*54*/
+ NULL, /*55*/
+ NULL, /*56*/
+ "invalid CRC", /*57*/
+ NULL, /*58*/
+ "conversion to unexisting or unsupported color type or bit depth", /*59*/
+ NULL, /*60*/
+ NULL, /*61*/
+ NULL, /*62*/
+ "png chunk too long", /*63*/
+ NULL, /*64*/
+ NULL, /*65*/
+ NULL, /*66*/
+ NULL, /*67*/
+ NULL, /*68*/
+ "unknown critical chunk", /*69*/
+ NULL, /*70*/
+ NULL, /*71*/
+ NULL, /*72*/
+ "invalid tIME chunk size", /*73*/
+ "invalid pHYs chunk size", /*74*/
+};
+
bool png_ext(const char ext[])
{
if (!ext)
@@ -1454,9 +1509,9 @@ int show_menu(void) /* return 1 to quit */
"Quit");
static const struct opt_items slideshow[2] = {
- { "Disable", -1 },
- { "Enable", -1 },
- };
+ { "Disable", -1 },
+ { "Enable", -1 },
+ };
result=rb->do_menu(&menu, NULL, NULL, false);
@@ -1598,7 +1653,8 @@ int scroll_bmp(struct LodePNG_Decoder* decoder)
{
if (slideshow_enabled)
button = rb->button_get_w_tmo(png_settings.ss_timeout * HZ);
- else button = rb->button_get(true);
+ else
+ button = rb->button_get(true);
running_slideshow = false;
@@ -1681,10 +1737,12 @@ int scroll_bmp(struct LodePNG_Decoder* decoder)
case PNG_RC_MENU:
#endif
case PNG_MENU:
+
if (show_menu() == 1)
return PLUGIN_OK;
- else
- return PLUGIN_REFRESH;
+
+ draw_image(decoder);
+ rb->lcd_update();
break;
default:
@@ -1755,6 +1813,140 @@ unsigned max_downscale(struct LodePNG_Decoder* decoder)
return downscale;
}
+/* load image from filename. */
+int load_image(char* filename, struct LodePNG_Decoder* decoder)
+{
+ int fd;
+ long time = 0; /* measured ticks */
+ int w, h; /* used to center output */
+
+ fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ {
+ rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
+ rb->splash(HZ, print);
+ return PLUGIN_ERROR;
+ }
+ image_size = rb->filesize(fd);
+
+ DEBUGF("reading file '%s'\n", filename);
+
+ if (!running_slideshow) {
+ rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
+ rb->lcd_puts(0, 0, print);
+ rb->lcd_update();
+ }
+
+ 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) {
+ rb->snprintf(print, sizeof(print), "loading %lu bytes", image_size);
+ rb->lcd_puts(0, 1, print);
+ rb->lcd_update();
+ }
+
+ image = memory_max - image_size + 1;
+ rb->read(fd, image, image_size);
+ rb->close(fd);
+
+ if (!running_slideshow) {
+ rb->snprintf(print, sizeof(print), "decoding image");
+ 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
+
+ decoder->settings.color_convert = 1;
+ decoder->infoRaw.color.colorType = 2;
+ decoder->infoRaw.color.bitDepth = 8;
+
+ LodePNG_inspect(decoder, image, image_size);
+
+ if (!decoder->error) {
+
+ if (!running_slideshow) {
+ rb->snprintf(print, sizeof(print), "image %dx%d",
+ decoder->infoPng.width, decoder->infoPng.height);
+ rb->lcd_puts(0, 2, print);
+ rb->lcd_update();
+
+ rb->snprintf(print, sizeof(print), "decoding %d*%d",
+ decoder->infoPng.width, decoder->infoPng.height);
+ rb->lcd_puts(0, 3, print);
+ rb->lcd_update();
+ }
+
+ /* the actual decoding */
+ time = *rb->current_tick;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+ LodePNG_decode(decoder, image, image_size, cb_progress);
+ rb->cpu_boost(false);
+#else
+ LodePNG_decode(decoder, image, image_size, cb_progress);
+#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
+ }
+ }
+
+ time = *rb->current_tick - time;
+
+ if (!running_slideshow && !decoder->error)
+ {
+ 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();
+ }
+
+ if (decoder->error) {
+ if (decoder->error == FILE_TOO_LARGE || decoder->error == OUT_OF_MEMORY
+ || decoder->error == Z_MEM_ERROR)
+ return PLUGIN_OUTOFMEM;
+
+ if (decoder->error >= PNG_ERROR_MIN && decoder->error <= PNG_ERROR_MAX
+ && png_error_messages[decoder->error-PNG_ERROR_MIN] != NULL)
+ {
+ rb->splash(HZ, png_error_messages[decoder->error-PNG_ERROR_MIN]);
+ }
+ else
+ {
+ switch (decoder->error) {
+ case PLUGIN_ABORT:
+ break;
+ case OUT_OF_MEMORY:
+ case Z_MEM_ERROR:
+ rb->splash(HZ, "Out of Memory");break;
+ case FILE_TOO_LARGE:
+ rb->splash(HZ, "File too large");break;
+ case Z_DATA_ERROR:
+ rb->splash(HZ, decoder->error_msg);break;
+ default:
+ rb->splashf(HZ, "other error : %ld", decoder->error);break;
+ }
+ }
+
+ if (decoder->error == PLUGIN_ABORT)
+ return PLUGIN_ABORT;
+ else
+ return PLUGIN_ERROR;
+ }
+ return PLUGIN_OK;
+}
+
/* return decoded or cached image */
fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
{
@@ -1778,7 +1970,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
rb->lcd_puts(0, 3, print);
rb->lcd_update();
}
- static struct bitmap bmp_src, bmp_dst;
+ struct bitmap bmp_src, bmp_dst;
int size = decoder->width * decoder->height;
@@ -1792,6 +1984,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
}
disp[ds] = disp_buf;
+ disp_buf = (fb_data *)((intptr_t)(disp[ds] + size + 3) & ~3);
bmp_src.width = decoder->infoPng.width;
bmp_src.height = decoder->infoPng.height;
@@ -1807,8 +2000,6 @@ fb_data *get_image(struct LodePNG_Decoder* decoder, int ds)
#else
smooth_resize_bitmap(&bmp_src, &bmp_dst);
#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
-
- disp_buf = (fb_data *)((intptr_t)(disp[ds] + size + 3) & ~3);
} else {
disp[ds] = converted_image;
return converted_image;
@@ -1848,132 +2039,28 @@ void get_view(struct LodePNG_Decoder* decoder, int* p_cx, int* p_cy)
/* load, decode, display the image */
int load_and_show(char* filename)
{
- int fd;
int status;
- long time=0; /* measured ticks */
int cx=0, cy=0; /* view center */
- int w, h; /* used to center output */
-
- LodePNG_Decoder_init(&decoder);
- rb->lcd_clear_display();
-
- fd = rb->open(filename, O_RDONLY);
- if (fd < 0)
- {
- rb->snprintf(print,sizeof(print),"err opening %s:%d",filename,fd);
- rb->splash(HZ, print);
- return PLUGIN_ERROR;
- }
- image_size = rb->filesize(fd);
- memset(&disp, 0, sizeof(disp));
-
- DEBUGF("reading file '%s'\n", filename);
-
- if (!running_slideshow) {
#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();
- rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1);
- rb->lcd_puts(0, 0, print);
- rb->lcd_update();
- }
-
- if (rb->button_get(false) == PNG_MENU) {
- decoder.error = PLUGIN_ABORT;
- rb->close(fd);
-
- } else if (image_size > memory_size) {
- decoder.error = FILE_TOO_LARGE;
- rb->close(fd);
-
- } else {
- if (!running_slideshow) {
- rb->snprintf(print, sizeof(print), "loading %lu bytes", image_size);
- rb->lcd_puts(0, 1, print);
- rb->lcd_update();
- }
-
- image = memory_max - image_size + 1;
- rb->read(fd, image, image_size);
- rb->close(fd);
-
- if (!running_slideshow) {
- rb->snprintf(print, sizeof(print), "decoding image");
- 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();
- }
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_set_background(LCD_BLACK);
+ rb->lcd_set_backdrop(NULL);
#endif
+ rb->lcd_clear_display();
- decoder.settings.color_convert = 1;
- decoder.infoRaw.color.colorType = 2;
- decoder.infoRaw.color.bitDepth = 8;
-
- if (rb->button_get(false) == PNG_MENU) {
- decoder.error = PLUGIN_ABORT;
- } else {
- LodePNG_inspect(&decoder, image, image_size);
- }
-
- if (!decoder.error) {
-
- if (!running_slideshow) {
- rb->snprintf(print, sizeof(print), "image %dx%d",
- decoder.infoPng.width, decoder.infoPng.height);
- rb->lcd_puts(0, 2, print);
- rb->lcd_update();
- }
-
- if (!running_slideshow)
- {
- rb->snprintf(print, sizeof(print), "decoding %d*%d",
- decoder.infoPng.width, decoder.infoPng.height);
- rb->lcd_puts(0, 3, print);
- rb->lcd_update();
- }
-
- /* the actual decoding */
- time = *rb->current_tick;
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(true);
- LodePNG_decode(&decoder, image, image_size, cb_progress);
- rb->cpu_boost(false);
-#else
- LodePNG_decode(&decoder, image, image_size, cb_progress);
-#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/
- }
- }
-
- if (decoder.error == PLUGIN_ABORT || decoder.error == FILE_TOO_LARGE) {
-#ifndef SIMULATOR
- if (immediate_ata_off) {
- /* running slideshow and time is long enough: power down disk */
- rb->storage_sleep();
- }
-#endif
- }
+ memset(&disp, 0, sizeof(disp));
+ LodePNG_Decoder_init(&decoder);
- time = *rb->current_tick - time;
+ if (rb->button_get(false) == PNG_MENU)
+ status = PLUGIN_ABORT;
+ else
+ status = load_image(filename, &decoder);
- if (!running_slideshow && !decoder.error)
+ if (status == PLUGIN_OUTOFMEM)
{
- 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();
- }
-
#if PLUGIN_BUFFER_SIZE >= MIN_MEM
- if (plug_buf && (decoder.error == FILE_TOO_LARGE || decoder.error == OUT_OF_MEMORY || decoder.error == Z_MEM_ERROR))
+ if (plug_buf)
{
rb->lcd_setfont(FONT_SYSFIXED);
rb->lcd_clear_display();
@@ -2029,87 +2116,23 @@ int load_and_show(char* filename)
}
}
}
- //else
+ else
#endif
-
- if (decoder.error) {
-
- switch (decoder.error) {
- case PLUGIN_ABORT:
- rb->splash(HZ, "aborted");break;
- case 27:
- rb->splash(HZ, "png file smaller than a png header");break;
- case 28:
- rb->splash(HZ, "incorrect png signature");break;
- case 29:
- rb->splash(HZ, "first chunk is not IHDR");break;
- case 30:
- rb->splash(HZ, "chunk length too large");break;
- case 31:
- rb->splash(HZ, "illegal PNG color type or bpp");break;
- case 32:
- rb->splash(HZ, "illegal PNG compression method");break;
- case 33:
- rb->splash(HZ, "illegal PNG filter method");break;
- case 34:
- rb->splash(HZ, "illegal PNG interlace method");break;
- case 35:
- rb->splash(HZ, "chunk length of a chunk is too large or the chunk too small");break;
- case 36:
- rb->splash(HZ, "illegal PNG filter type encountered");break;
- case 37:
- rb->splash(HZ, "illegal bit depth for this color type given");break;
- case 38:
- rb->splash(HZ, "the palette is too big (more than 256 colors)");break;
- case 39:
- rb->splash(HZ, "more palette alpha values given in tRNS, than there are colors in the palette");break;
- case 40:
- rb->splash(HZ, "tRNS chunk has wrong size for greyscale image");break;
- case 41:
- rb->splash(HZ, "tRNS chunk has wrong size for RGB image");break;
- case 42:
- rb->splash(HZ, "tRNS chunk appeared while it was not allowed for this color type");break;
- case 43:
- rb->splash(HZ, "bKGD chunk has wrong size for palette image");break;
- case 44:
- rb->splash(HZ, "bKGD chunk has wrong size for greyscale image");break;
- case 45:
- rb->splash(HZ, "bKGD chunk has wrong size for RGB image");break;
- case 46:
- case 47:
- rb->splash(HZ, "value encountered in indexed image is larger than the palette size");break;
- case 48:
- rb->splash(HZ, "input file is empty");break;
- case OUT_OF_MEMORY:
- case Z_MEM_ERROR:
- rb->splash(HZ, "Out of Memory");break;
- case 57:
- rb->splash(HZ, "invalid CRC");break;
- case 59:
- rb->splash(HZ, "conversion to unexisting or unsupported color type or bit depth");break;
- case 63:
- rb->splash(HZ, "png chunk too long");break;
- case 69:
- rb->splash(HZ, "unknown critical chunk");break;
- case 73:
- rb->splash(HZ, "invalid tIME chunk size");break;
- case 74:
- rb->splash(HZ, "invalid pHYs chunk size");break;
- case FILE_TOO_LARGE:
- rb->splash(HZ, "File too large");break;
- case Z_DATA_ERROR:
- rb->splash(HZ, decoder.error_msg);break;
- default:
- rb->splashf(HZ, "other error : %ld", decoder.error);break;
- }
-
- if (decoder.error == PLUGIN_ABORT) {
- return PLUGIN_OK;
- } else {
- file_pt[curfile] = NULL;
- return change_filename(direction);
- }
+ {
+ 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;
+ }
disp_buf = (fb_data *)((intptr_t)(converted_image + converted_image_size + 3) & ~3);
ds_max = max_downscale(&decoder); /* check display constraint */
@@ -2231,7 +2254,7 @@ enum plugin_status plugin_start(const void* parameter)
do
{
condition = load_and_show(np_file);
- }while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
+ } while (condition != PLUGIN_OK && condition != PLUGIN_USB_CONNECTED
&& condition != PLUGIN_ERROR);
if (rb->memcmp(&png_settings, &old_settings, sizeof (png_settings)))
@@ -2252,4 +2275,3 @@ enum plugin_status plugin_start(const void* parameter)
return condition;
}
-
diff --git a/apps/plugins/png/png.h b/apps/plugins/png/png.h
index 50ae334ad0..4699e24e70 100644
--- a/apps/plugins/png/png.h
+++ b/apps/plugins/png/png.h
@@ -359,8 +359,8 @@ You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
#endif
#endif
-#define PLUGIN_OTHER 10 /* State code for output with return. */
-#define PLUGIN_REFRESH 11 /* State code for output with return. */
-#define PLUGIN_ABORT 12
-#define OUT_OF_MEMORY 9900
-#define FILE_TOO_LARGE 9910
+#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