From 3e2aba0c3eded353ba119e5df23968d70b1263c5 Mon Sep 17 00:00:00 2001 From: Teruaki Kawashima Date: Fri, 18 Dec 2009 13:06:21 +0000 Subject: 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 --- apps/plugins/jpeg/jpeg.c | 224 +++++++++++++----------- apps/plugins/png/png.c | 438 +++++++++++++++++++++++++---------------------- apps/plugins/png/png.h | 10 +- 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 -- cgit v1.2.3