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
This commit is contained in:
Teruaki Kawashima 2009-12-18 13:06:21 +00:00
parent d42cdfd91c
commit 3e2aba0c3e
3 changed files with 362 additions and 310 deletions

View file

@ -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);
#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->memset(&disp, 0, sizeof(disp));
rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */
/* allocate JPEG buffer */
buf_jpeg = buf;
if (rb->button_get(false) == JPEG_MENU)
status = PLUGIN_ABORT;
else
status = load_image(filename, &jpg);
/* 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)
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)))
{

View file

@ -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);
#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();
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));
LodePNG_Decoder_init(&decoder);
DEBUGF("reading file '%s'\n", filename);
if (rb->button_get(false) == PNG_MENU)
status = PLUGIN_ABORT;
else
status = load_image(filename, &decoder);
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();
}
#endif
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
}
time = *rb->current_tick - time;
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;
}

View file

@ -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