From 5e31d059aab7431b3efdc491e262804f744c8881 Mon Sep 17 00:00:00 2001 From: Teruaki Kawashima Date: Sun, 15 Nov 2009 14:03:57 +0000 Subject: jpeg/png: unify code to display image to draw_image(_rect). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23631 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/jpeg/jpeg.c | 109 ++++++++++++++--------------------------------- apps/plugins/png/png.c | 69 +++++++++++------------------- 2 files changed, 57 insertions(+), 121 deletions(-) (limited to 'apps') diff --git a/apps/plugins/jpeg/jpeg.c b/apps/plugins/jpeg/jpeg.c index fc98834a7d..807c6c4101 100644 --- a/apps/plugins/jpeg/jpeg.c +++ b/apps/plugins/jpeg/jpeg.c @@ -445,6 +445,25 @@ int show_menu(void) /* return 1 to quit */ return 0; } +void draw_image_rect(struct t_disp* pdisp, int x, int y, int width, int height) +{ +#ifdef HAVE_LCD_COLOR + yuv_bitmap_part( + pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, + pdisp->x + x, pdisp->y + y, pdisp->stride, + x + MAX(0, (LCD_WIDTH - pdisp->width) / 2), + y + MAX(0, (LCD_HEIGHT - pdisp->height) / 2), + width, height, + jpeg_settings.colour_mode, jpeg_settings.dither_mode); +#else + MYXLCD(gray_bitmap_part)( + pdisp->bitmap[0], pdisp->x + x, pdisp->y + y, pdisp->stride, + x + MAX(0, (LCD_WIDTH-pdisp->width)/2), + y + MAX(0, (LCD_HEIGHT-pdisp->height)/2), + width, height); +#endif +} + /* Pan the viewing window right - move image to the left and fill in the right-hand side */ static void pan_view_right(struct t_disp* pdisp) @@ -456,20 +475,7 @@ static void pan_view_right(struct t_disp* pdisp) { MYXLCD(scroll_left)(move); /* scroll left */ pdisp->x += move; -#ifdef HAVE_LCD_COLOR - yuv_bitmap_part( - pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, - pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride, - LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ - move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ - jpeg_settings.colour_mode, jpeg_settings.dither_mode); -#else - MYXLCD(gray_bitmap_part)( - pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move, - pdisp->y, pdisp->stride, - LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ - move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ -#endif + draw_image_rect(pdisp, LCD_WIDTH - move, 0, move, pdisp->height-pdisp->y); MYLCD_UPDATE(); } } @@ -485,24 +491,11 @@ static void pan_view_left(struct t_disp* pdisp) { MYXLCD(scroll_right)(move); /* scroll right */ pdisp->x -= move; -#ifdef HAVE_LCD_COLOR - yuv_bitmap_part( - pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, - pdisp->x, pdisp->y, pdisp->stride, - 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ - move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ - jpeg_settings.colour_mode, jpeg_settings.dither_mode); -#else - MYXLCD(gray_bitmap_part)( - pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, - 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ - move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ -#endif + draw_image_rect(pdisp, 0, 0, move, pdisp->height-pdisp->y); MYLCD_UPDATE(); } } - /* Pan the viewing window up - move image down and fill in the top */ static void pan_view_up(struct t_disp* pdisp) @@ -521,19 +514,8 @@ static void pan_view_up(struct t_disp* pdisp) caused by lack of error history on line zero. */ move = MIN(move + 1, pdisp->y + pdisp->height); } - - yuv_bitmap_part( - pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, - pdisp->x, pdisp->y, pdisp->stride, - MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ - jpeg_settings.colour_mode, jpeg_settings.dither_mode); -#else - MYXLCD(gray_bitmap_part)( - pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, - MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ #endif + draw_image_rect(pdisp, 0, 0, pdisp->width-pdisp->x, move); MYLCD_UPDATE(); } } @@ -561,14 +543,11 @@ static void pan_view_down(struct t_disp* pdisp) rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, LCD_WIDTH*sizeof (fb_data)); } +#endif - yuv_bitmap_part( - pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x, - pdisp->y + LCD_HEIGHT - move, pdisp->stride, - MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ - jpeg_settings.colour_mode, jpeg_settings.dither_mode); + draw_image_rect(pdisp, 0, LCD_HEIGHT - move, pdisp->width-pdisp->x, move); +#ifdef HAVE_LCD_COLOR if (jpeg_settings.dither_mode == DITHER_DIFFUSION) { /* Cover the first row drawn with previous image data. */ @@ -577,12 +556,6 @@ static void pan_view_down(struct t_disp* pdisp) LCD_WIDTH*sizeof (fb_data)); pdisp->y++; } -#else - MYXLCD(gray_bitmap_part)( - pdisp->bitmap[0], pdisp->x, - pdisp->y + LCD_HEIGHT - move, pdisp->stride, - MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ #endif MYLCD_UPDATE(); } @@ -687,14 +660,8 @@ int scroll_bmp(struct t_disp* pdisp) #ifdef USEGSLIB grey_show(true); /* switch on greyscale overlay */ #else - yuv_bitmap_part( - pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, - pdisp->x, pdisp->y, pdisp->stride, - MAX(0, (LCD_WIDTH - pdisp->width) / 2), - MAX(0, (LCD_HEIGHT - pdisp->height) / 2), - MIN(LCD_WIDTH, pdisp->width), - MIN(LCD_HEIGHT, pdisp->height), - jpeg_settings.colour_mode, jpeg_settings.dither_mode); + draw_image_rect(pdisp, 0, 0, + pdisp->width-pdisp->x, pdisp->height-pdisp->y); MYLCD_UPDATE(); #endif break; @@ -1072,7 +1039,7 @@ int load_and_show(char* filename) return change_filename(direction); } - ds = ds_max; /* initials setting */ + ds = ds_max; /* initialize setting */ cx = jpg.x_size/ds/2; /* center the view */ cy = jpg.y_size/ds/2; @@ -1091,24 +1058,10 @@ int load_and_show(char* filename) rb->lcd_puts(0, 3, print); rb->lcd_update(); } + MYLCD(clear_display)(); -#ifdef HAVE_LCD_COLOR - yuv_bitmap_part( - p_disp->bitmap, p_disp->csub_x, p_disp->csub_y, - p_disp->x, p_disp->y, p_disp->stride, - MAX(0, (LCD_WIDTH - p_disp->width) / 2), - MAX(0, (LCD_HEIGHT - p_disp->height) / 2), - MIN(LCD_WIDTH, p_disp->width), - MIN(LCD_HEIGHT, p_disp->height), - jpeg_settings.colour_mode, jpeg_settings.dither_mode); -#else - MYXLCD(gray_bitmap_part)( - p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride, - MAX(0, (LCD_WIDTH - p_disp->width) / 2), - MAX(0, (LCD_HEIGHT - p_disp->height) / 2), - MIN(LCD_WIDTH, p_disp->width), - MIN(LCD_HEIGHT, p_disp->height)); -#endif + draw_image_rect(p_disp, 0, 0, + p_disp->width-p_disp->x, p_disp->height-p_disp->y); MYLCD_UPDATE(); #ifdef USEGSLIB diff --git a/apps/plugins/png/png.c b/apps/plugins/png/png.c index 216077767c..8a5d05be9a 100644 --- a/apps/plugins/png/png.c +++ b/apps/plugins/png/png.c @@ -1302,7 +1302,7 @@ void LodePNG_decode(LodePNG_Decoder* decoder, unsigned char* in, size_t insize, /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ if (!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56; return; } converted_image = (fb_data *)((intptr_t)(memory + 3) & ~3); - converted_image_size = FB_DATA_SZ*decoder->infoPng.width*decoder->infoPng.height; + converted_image_size = decoder->infoPng.width*decoder->infoPng.height; if ((unsigned char *)(converted_image + converted_image_size) >= decoded_image) { decoder->error = OUT_OF_MEMORY; } if (!decoder->error) decoder->error = LodePNG_convert(converted_image, decoded_image, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height); } @@ -1534,6 +1534,15 @@ int show_menu(void) /* return 1 to quit */ return 0; } +void draw_image(struct LodePNG_Decoder* decoder) +{ + rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, + MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2), + MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2), + decoder->infoPng.width/ds - decoder->x, + decoder->infoPng.height/ds - decoder->y); +} + /* Pan the viewing window right - move image to the left and fill in the right-hand side */ static void pan_view_right(struct LodePNG_Decoder* decoder) @@ -1541,14 +1550,10 @@ static void pan_view_right(struct LodePNG_Decoder* decoder) int move; move = MIN(HSCROLL, decoder->infoPng.width/ds - decoder->x - LCD_WIDTH); - if (move > 0 && decoder->infoPng.width/ds > LCD_WIDTH) + if (move > 0) { decoder->x += move; - rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, - MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2), - MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2), - MIN(LCD_WIDTH, decoder->infoPng.width/ds), - MIN(LCD_HEIGHT, decoder->infoPng.height/ds)); + draw_image(decoder); rb->lcd_update(); } } @@ -1563,11 +1568,7 @@ static void pan_view_left(struct LodePNG_Decoder* decoder) if (move > 0) { decoder->x -= move; - rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, - MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2), - MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2), - MIN(LCD_WIDTH, decoder->infoPng.width/ds), - MIN(LCD_HEIGHT, decoder->infoPng.height/ds)); + draw_image(decoder); rb->lcd_update(); } } @@ -1583,11 +1584,7 @@ static void pan_view_up(struct LodePNG_Decoder* decoder) if (move > 0) { decoder->y -= move; - rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, - MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2), - MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2), - MIN(LCD_WIDTH, decoder->infoPng.width/ds), - MIN(LCD_HEIGHT, decoder->infoPng.height/ds)); + draw_image(decoder); rb->lcd_update(); } } @@ -1599,14 +1596,10 @@ static void pan_view_down(struct LodePNG_Decoder* decoder) int move; move = MIN(VSCROLL, decoder->infoPng.height/ds - decoder->y - LCD_HEIGHT); - if (move > 0 && decoder->infoPng.height/ds > LCD_HEIGHT) + if (move > 0) { decoder->y += move; - rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, - MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2), - MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2), - MIN(LCD_WIDTH, decoder->infoPng.width/ds), - MIN(LCD_HEIGHT, decoder->infoPng.height/ds)); + draw_image(decoder); rb->lcd_update(); } } @@ -1765,7 +1758,7 @@ void cb_progress(int current, int total) int pngmem(struct LodePNG_Decoder* decoder, int ds) { - return decoder->infoPng.width * decoder->infoPng.height * FB_DATA_SZ / ds; + return (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds) * FB_DATA_SZ; } /* how far can we zoom in without running out of memory */ @@ -1819,7 +1812,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder) previous_size = converted_image_size; } - size[ds] = decoder->infoPng.width * decoder->infoPng.height * FB_DATA_SZ / ds; + size[ds] = (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds); /* assign image buffer */ if (ds > 1) { @@ -1837,7 +1830,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder) if ((unsigned char *)(disp[ds] + size[ds]) >= memory_max) { //rb->splash(HZ, "Out of Memory"); // Still display the original image which is already decoded in RAM - disp[ds] = NULL; + disp[ds] = converted_image; ds = 1; return converted_image; } else { @@ -1858,10 +1851,9 @@ fb_data *get_image(struct LodePNG_Decoder* decoder) } } else { disp[ds] = converted_image; + return converted_image; } - - previous_disp = disp[ds]; previous_size = size[ds]; @@ -1958,6 +1950,7 @@ int load_and_show(char* filename) rb->lcd_puts(0, 2, print); rb->lcd_update(); } + ds_max = max_downscale(&decoder); /* check display constraint */ ds = ds_max; /* initials setting */ @@ -2009,7 +2002,6 @@ int load_and_show(char* filename) rb->lcd_update(); } - do { #if PLUGIN_BUFFER_SIZE >= MIN_MEM if (plug_buf && (decoder.error == FILE_TOO_LARGE || decoder.error == OUT_OF_MEMORY || decoder.error == Z_MEM_ERROR)) { @@ -2073,9 +2065,6 @@ int load_and_show(char* filename) //else #endif - if (!decoder.error) { - resized_image = get_image(&decoder); /* decode or fetch from cache */ - } if (decoder.error) { switch (decoder.error) { @@ -2152,11 +2141,14 @@ int load_and_show(char* filename) } else if (decoder.error == OUT_OF_MEMORY && entries == 1) { return PLUGIN_ERROR; } else { + file_pt[curfile] = '\0'; return change_filename(direction); } - } + do { + resized_image = get_image(&decoder); /* decode or fetch from cache */ + cx = decoder.infoPng.width/ds/2; /* center the view */ cy = decoder.infoPng.height/ds/2; @@ -2171,18 +2163,9 @@ int load_and_show(char* filename) } rb->lcd_clear_display(); - - rb->lcd_bitmap_part(resized_image, decoder.x, decoder.y, decoder.infoPng.width/ds /*stride*/, - MAX(0, (LCD_WIDTH - (int)decoder.infoPng.width/(int)ds) / 2), - MAX(0, (LCD_HEIGHT - (int)decoder.infoPng.height/(int)ds) / 2), - MIN(LCD_WIDTH, decoder.infoPng.width/ds), - MIN(LCD_HEIGHT, decoder.infoPng.height/ds)); - + draw_image(&decoder); rb->lcd_update(); - //} - //} - /* drawing is now finished, play around with scrolling * until you press OFF or connect USB */ -- cgit v1.2.3