Index: apps/plugins/jpeg.c =================================================================== --- apps/plugins/jpeg.c (revision 18811) +++ apps/plugins/jpeg.c (working copy) @@ -301,6 +301,11 @@ #define INLINE static inline #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */ +/***************/ +int SCREENWIDTH = LCD_WIDTH; +int SCREENHEIGHT = LCD_HEIGHT; +static bool rotate_screen = false; /* rotate image */ +/***************/ static int slideshow_enabled = false; /* run slideshow */ static int running_slideshow = false; /* loading image because of slideshw */ #ifndef SIMULATOR @@ -2233,6 +2238,143 @@ }, }; +/*******************************************************************************************/ +/************** Credit to Rene Peinthor ****************************************************/ +/************** and Adam Gashlin with some additions by GRaTT ******************************/ +/************** Rotate function from sansa_video.patch FS# 6675 ****************************/ +/*******************************************************************************************/ +#define RYFAC (31*257) +#define GYFAC (63*257) +#define BYFAC (31*257) +#define R_RVFAC 11170 /* 31 * 257 * 1.402 */ +#define R_GVFAC (-11563) /* 63 * 257 * -0.714136 */ +#define R_GUFAC (-5572) /* 63 * 257 * -0.344136 */ +#define R_BUFAC 14118 /* 31 * 257 * 1.772 */ + +#define ROUNDOFFS (127*257) + +/* Performance function to blit a YUV bitmap directly to the LCD + Actually this code is from gigabeat, because this target is also + writing direct to a buffer. */ +#define R_SCREENWIDTH SCREENHEIGHT +#define R_SCREENHEIGHT SCREENWIDTH +void rotate(unsigned char *src[3], int csub_x, int csub_y, + int src_x, int src_y, int stride, + int _x, int _y, /* x, y */ + int width, int height) /* w, h */ + { + fb_data *dst, *dst_end; + const unsigned char *usrc; + const unsigned char *vsrc; + const unsigned char *ysrc; + int xphase; + int rc, gc, bc; + int y, u, v; + int red, green, blue; + unsigned rbits, gbits, bbits; + int count; + fb_data *dst_row; + + if (width > SCREENWIDTH) + width = SCREENWIDTH; /* if width of pict is bigger than SCREENHEIGHT */ + if (width < SCREENWIDTH) + _x = (SCREENWIDTH - width)/2; /* if width of pict is smaller then center */ +// if (_x < 0) +// width += _x, _x = 0; /* Clip left */ +// if (width <= 0) +// return; /* nothing left to do */ + + if (height > SCREENHEIGHT) + height = SCREENHEIGHT; /* if height is bigger than SCREENHEIGHT */ + if (height < SCREENHEIGHT) + _y = (SCREENHEIGHT - height)/2; /* if height of pict is smaller then center */ +// if (_y < 0) +// height += _y, _y = 0; /* Clip top */ +// if (height <= 0) +// return; /* nothing left to do */ + + width = (width + 1) & ~1; + + dst = rb->lcd_framebuffer + _x * SCREENHEIGHT + (SCREENHEIGHT - _y) - 1; + //dst = rb->lcd_framebuffer + _x * R_LCD_HEIGHT + (R_LCD_HEIGHT - _y) - 1; + dst_end = dst - (height - 1); + + do + { + dst_row = dst; + count = width; + ysrc = src[0] + stride * src_y + src_x; + + /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ + usrc = src[1] + (stride/csub_x) * (src_y/csub_y) + + (src_x/csub_x); + vsrc = src[2] + (stride/csub_x) * (src_y/csub_y) + + (src_x/csub_x); + xphase = src_x % csub_x; + + u = *usrc++ - 128; + v = *vsrc++ - 128; + rc = R_RVFAC * v + ROUNDOFFS; + gc = R_GVFAC * v + R_GUFAC * u + ROUNDOFFS; + bc = R_BUFAC * u + ROUNDOFFS; + + do + { + y = *ysrc++; + red = RYFAC * y + rc; + green = GYFAC * y + gc; + blue = BYFAC * y + bc; + + if ((unsigned)red > (RYFAC*255+ROUNDOFFS)) + { + if (red < 0) + red = 0; + else + red = (RYFAC*255+ROUNDOFFS); + } + if ((unsigned)green > (GYFAC*255+ROUNDOFFS)) + { + if (green < 0) + green = 0; + else + green = (GYFAC*255+ROUNDOFFS); + } + if ((unsigned)blue > (BYFAC*255+ROUNDOFFS)) + { + if (blue < 0) + blue = 0; + else + blue = (BYFAC*255+ROUNDOFFS); + } + rbits = ((unsigned)red) >> 16 ; + gbits = ((unsigned)green) >> 16 ; + bbits = ((unsigned)blue) >> 16 ; + + *dst_row = (rbits << 11) | (gbits << 5) | bbits; + + /* next pixel - since rotated, add WIDTH */ + dst_row += LCD_WIDTH; + + if (++xphase >= csub_x) + { + u = *usrc++ - 128; + v = *vsrc++ - 128; + rc = R_RVFAC * v + ROUNDOFFS; + gc = R_GVFAC * v + R_GUFAC * u + ROUNDOFFS; + bc = R_BUFAC * u + ROUNDOFFS; + xphase = 0; + } + } + while (--count); + + if (dst == dst_end) break; + + dst--; + src_y++; + } while( 1); + } +/*******************************************************************************/ + /** * Draw a partial YUV colour bitmap * @@ -2243,19 +2385,27 @@ int src_x, int src_y, int stride, int x, int y, int width, int height) { +/*******************************************************************************************/ + if(rotate_screen == true){ + /* rb->splashf(HZ*2, "ROTATE SCREEN == %d", rotate_screen); */ + rotate(src, csub_x, csub_y, + src_x, src_y, stride, + x, y, width, height); + }else{ +/*******************************************************************************************/ fb_data *dst, *dst_end; fb_data (*pixel_func)(void); struct rgb_pixel px; - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* Clip right */ + if (x + width > SCREENWIDTH) + width = SCREENWIDTH - x; /* Clip right */ if (x < 0) width += x, x = 0; /* Clip left */ if (width <= 0) return; /* nothing left to do */ - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* Clip bottom */ + if (y + height > SCREENHEIGHT) + height = SCREENHEIGHT - y; /* Clip bottom */ if (y < 0) height += y, y = 0; /* Clip top */ if (height <= 0) @@ -2263,8 +2413,8 @@ pixel = &px; - dst = rb->lcd_framebuffer + LCD_WIDTH * y + x; - dst_end = dst + LCD_WIDTH * height; + dst = rb->lcd_framebuffer + SCREENWIDTH * y + x; + dst_end = dst + SCREENWIDTH * height; if (jpeg_settings.colour_mode == COLOURMODE_GRAY) csub_y = 0; /* Ignore Cb, Cr */ @@ -2380,11 +2530,11 @@ } src_y++; - dst += LCD_WIDTH; + dst += SCREENWIDTH; } while (dst < dst_end); + } /*********************** end of screen_rotate == true ************************/ } - #endif /* HAVE_LCD_COLOR */ @@ -2458,7 +2608,8 @@ /* we "erase" the file name if we encounter * a non-supported file, so skip it now */ } - else /* DIR_NEXT/DIR_NONE */ + + else if(direct == DIR_NEXT)/* DIR_NEXTE */ { do { @@ -2469,7 +2620,12 @@ curfile++; }while(file_pt[curfile] == '\0' && count < entries); } + /* not required now maybe required later */ + //else /* DIR_NONE */ + //{ + //} + if(count == entries && file_pt[curfile] == '\0') { rb->splash(HZ, "No supported files"); @@ -2497,8 +2653,8 @@ #endif } -#define VSCROLL (LCD_HEIGHT/8) -#define HSCROLL (LCD_WIDTH/10) +#define VSCROLL (SCREENHEIGHT/8) +#define HSCROLL (SCREENWIDTH/10) #define ZOOM_IN 100 /* return codes for below function */ #define ZOOM_OUT 101 @@ -2559,6 +2715,7 @@ MIID_QUIT = 0, MIID_TOGGLE_SS_MODE, MIID_CHANGE_SS_MODE, + MIID_ROTATE, #if PLUGIN_BUFFER_SIZE >= MIN_MEM MIID_SHOW_PLAYBACK_MENU, #endif @@ -2575,6 +2732,8 @@ { "Toggle Slideshow Mode", NULL }, [MIID_CHANGE_SS_MODE] = { "Change Slideshow Time", NULL }, + [MIID_ROTATE] = + { "Switch Landscape/Portrait view", NULL }, #if PLUGIN_BUFFER_SIZE >= MIN_MEM [MIID_SHOW_PLAYBACK_MENU] = { "Show Playback Menu", NULL }, @@ -2602,6 +2761,9 @@ menu_exit(m); return 1; break; + case MIID_ROTATE: + return 3; + break; case MIID_TOGGLE_SS_MODE: rb->set_option("Toggle Slideshow", &slideshow_enabled, INT, slideshow , 2, NULL); @@ -2665,6 +2827,7 @@ int scroll_bmp(struct t_disp* pdisp) { int lastbutton = 0; + int menu_return = 0; while (true) { @@ -2692,13 +2855,13 @@ 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 */ + 0, MAX(0, (SCREENHEIGHT-pdisp->height)/2), /* x, y */ + move, MIN(SCREENHEIGHT, pdisp->height)); /* w, h */ #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 */ + 0, MAX(0, (SCREENHEIGHT-pdisp->height)/2), /* x, y */ + move, MIN(SCREENHEIGHT, pdisp->height)); /* w, h */ #endif MYLCD_UPDATE(); } @@ -2708,7 +2871,7 @@ if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) return change_filename(DIR_NEXT); case JPEG_RIGHT | BUTTON_REPEAT: - move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); + move = MIN(HSCROLL, pdisp->width - pdisp->x - SCREENWIDTH); if (move > 0) { MYXLCD(scroll_left)(move); /* scroll left */ @@ -2716,15 +2879,15 @@ #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 */ + pdisp->x + SCREENWIDTH - move, pdisp->y, pdisp->stride, + SCREENWIDTH - move, MAX(0, (SCREENHEIGHT-pdisp->height)/2), /* x, y */ + move, MIN(SCREENHEIGHT, pdisp->height)); /* w, h */ #else MYXLCD(gray_bitmap_part)( - pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move, + pdisp->bitmap[0], pdisp->x + SCREENWIDTH - 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 */ + SCREENWIDTH - move, MAX(0, (SCREENHEIGHT-pdisp->height)/2), /* x, y */ + move, MIN(SCREENHEIGHT, pdisp->height)); /* w, h */ #endif MYLCD_UPDATE(); } @@ -2748,13 +2911,13 @@ 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 */ + MAX(0, (SCREENWIDTH-pdisp->width)/2), 0, /* x, y */ + MIN(SCREENWIDTH, pdisp->width), move); /* w, h */ #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 */ + MAX(0, (SCREENWIDTH-pdisp->width)/2), 0, /* x, y */ + MIN(SCREENWIDTH, pdisp->width), move); /* w, h */ #endif MYLCD_UPDATE(); } @@ -2762,7 +2925,7 @@ case JPEG_DOWN: case JPEG_DOWN | BUTTON_REPEAT: - move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT); + move = MIN(VSCROLL, pdisp->height - pdisp->y - SCREENHEIGHT); if (move > 0) { MYXLCD(scroll_up)(move); /* scroll up */ @@ -2776,30 +2939,30 @@ */ move++, pdisp->y--; MEMCPY(rgb_linebuf, - rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, - LCD_WIDTH*sizeof (fb_data)); + rb->lcd_framebuffer + (SCREENHEIGHT - move)*SCREENWIDTH, + SCREENWIDTH*sizeof (fb_data)); } 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 */ + pdisp->y + SCREENHEIGHT - move, pdisp->stride, + MAX(0, (SCREENWIDTH-pdisp->width)/2), SCREENHEIGHT - move, /* x, y */ + MIN(SCREENWIDTH, pdisp->width), move); /* w, h */ if (jpeg_settings.dither_mode == DITHER_DIFFUSION) { /* Cover the first row drawn with previous image data. */ - MEMCPY(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, + MEMCPY(rb->lcd_framebuffer + (SCREENHEIGHT - move)*SCREENWIDTH, rgb_linebuf, - LCD_WIDTH*sizeof (fb_data)); + SCREENWIDTH*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 */ + pdisp->y + SCREENHEIGHT - move, pdisp->stride, + MAX(0, (SCREENWIDTH-pdisp->width)/2), SCREENHEIGHT - move, /* x, y */ + MIN(SCREENWIDTH, pdisp->width), move); /* w, h */ #endif MYLCD_UPDATE(); } @@ -2857,19 +3020,61 @@ #ifdef USEGSLIB grey_show(false); /* switch off greyscale overlay */ #endif - if (show_menu() == 1) - return PLUGIN_OK; +// if (show_menu() == 1) +// return PLUGIN_OK; + menu_return = show_menu(); + if (menu_return == 1) + { + return PLUGIN_OK; + } + if (menu_return == 3) + { + rb->lcd_clear_display(); + rb->lcd_puts(0,1,"Rotate current image"); + //rb->lcd_puts_scroll(0,2,(char*)filename); + rb->lcd_puts(0,4,">> = Yes"); + rb->lcd_puts(0,5,"Any other = No"); + rb->lcd_update(); + button = rb->button_get(true); + switch(button) + { + case JPEG_RIGHT: + rb->lcd_clear_display(); + rb->lcd_puts(0,1,"Rotation Changed"); + //rb->lcd_puts_scroll(0,2,(char*)filename); + //rb->splashf(HZ*2, "rotate screen = %d", rotate_screen); + if (rotate_screen == false){ + rotate_screen = true; + SCREENWIDTH = LCD_HEIGHT; + SCREENHEIGHT = LCD_WIDTH; + }else{ + rotate_screen = false; + SCREENWIDTH = LCD_WIDTH; + SCREENHEIGHT = LCD_HEIGHT; + } + //rb->splashf(HZ*2, "rotate screen = %d", rotate_screen); + rb->button_clear_queue(); + return change_filename(DIR_NONE); + break; + default: + rb->button_clear_queue(); + return change_filename(DIR_NONE); + break; + } + break; + } + #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)); + MAX(0, (SCREENWIDTH - pdisp->width) / 2), + MAX(0, (SCREENHEIGHT - pdisp->height) / 2), + MIN(SCREENWIDTH, pdisp->width), + MIN(SCREENHEIGHT, pdisp->height)); MYLCD_UPDATE(); #endif break; @@ -2894,17 +3099,17 @@ rb->yield(); /* be nice to the other threads */ if(!running_slideshow) { - rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0, + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, SCREENHEIGHT-8, SCREENWIDTH, 8, total, 0, current, HORIZONTAL); - rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); + rb->lcd_update_rect(0, SCREENHEIGHT-8, SCREENWIDTH, 8); } #ifndef USEGSLIB else { /* in slideshow mode, keep gui interference to a minimum */ - rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0, + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, SCREENHEIGHT-4, SCREENWIDTH, 4, total, 0, current, HORIZONTAL); - rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4); + rb->lcd_update_rect(0, SCREENHEIGHT-4, SCREENWIDTH, 4); } #endif } @@ -2947,8 +3152,8 @@ { int downscale = 1; - while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale - || p_jpg->y_size > LCD_HEIGHT*downscale)) + while (downscale < 8 && (p_jpg->x_size > SCREENWIDTH*downscale + || p_jpg->y_size > SCREENHEIGHT*downscale)) { downscale *= 2; } @@ -3047,7 +3252,7 @@ { 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_putsxy((SCREENWIDTH - w)/2, SCREENHEIGHT - h, print); rb->lcd_update(); } @@ -3061,12 +3266,12 @@ int x, y; /* plain center to available width/height */ - x = cx - MIN(LCD_WIDTH, p_disp->width) / 2; - y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2; + x = cx - MIN(SCREENWIDTH, p_disp->width) / 2; + y = cy - MIN(SCREENHEIGHT, p_disp->height) / 2; /* limit against upper image size */ - x = MIN(p_disp->width - LCD_WIDTH, x); - y = MIN(p_disp->height - LCD_HEIGHT, y); + x = MIN(p_disp->width - SCREENWIDTH, x); + y = MIN(p_disp->height - SCREENHEIGHT, y); /* limit against negative side */ x = MAX(0, x); @@ -3080,8 +3285,8 @@ /* calculate the view center based on the bitmap position */ void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy) { - *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2; - *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2; + *p_cx = p_disp->x + MIN(SCREENWIDTH, p_disp->width) / 2; + *p_cy = p_disp->y + MIN(SCREENHEIGHT, p_disp->height) / 2; } @@ -3271,17 +3476,17 @@ 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)); + MAX(0, (SCREENWIDTH - p_disp->width) / 2), + MAX(0, (SCREENHEIGHT - p_disp->height) / 2), + MIN(SCREENWIDTH, p_disp->width), + MIN(SCREENHEIGHT, p_disp->height)); #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)); + MAX(0, (SCREENWIDTH - p_disp->width) / 2), + MAX(0, (SCREENHEIGHT - p_disp->height) / 2), + MIN(SCREENWIDTH, p_disp->width), + MIN(SCREENHEIGHT, p_disp->height)); #endif MYLCD_UPDATE(); @@ -3375,7 +3580,7 @@ #ifdef USEGSLIB if (!grey_init(rb, buf, buf_size, GREY_ON_COP, - LCD_WIDTH, LCD_HEIGHT, &greysize)) + SCREENWIDTH, SCREENHEIGHT, &greysize)) { rb->splash(HZ, "grey buf error"); return PLUGIN_ERROR; Index: apps/bitmaps/native/rockboxlogo.176x54x16.bmp =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream