Index: apps/plugins/jpeg.c =================================================================== --- apps/plugins/jpeg.c (revision 18811) +++ apps/plugins/jpeg.c (working copy) @@ -300,7 +300,7 @@ #define MEMCPY(d,s,c) rb->memcpy(d,s,c) #define INLINE static inline #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */ - +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 +2233,141 @@ }, }; +/*******************************************************************************************/ +/************** 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_LCD_WIDTH LCD_HEIGHT +#define R_LCD_HEIGHT LCD_WIDTH +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 > R_LCD_WIDTH) + width = R_LCD_WIDTH; /* if width of pict is bigger than LCD_HEIGHT */ + if (width < R_LCD_WIDTH) + _x = (R_LCD_WIDTH - 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 > R_LCD_HEIGHT) + height = R_LCD_HEIGHT; /* if height is bigger than LCD_HEIGHT */ + if (height < R_LCD_HEIGHT) + _y = (R_LCD_HEIGHT - 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 * 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,6 +2378,14 @@ 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; @@ -2384,10 +2527,8 @@ } while (dst < dst_end); } - #endif /* HAVE_LCD_COLOR */ - /* support function for qsort() */ static int compare(const void* p1, const void* p2) { @@ -2458,7 +2599,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 +2611,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"); @@ -2559,6 +2706,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 +2723,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 +2752,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 +2818,7 @@ int scroll_bmp(struct t_disp* pdisp) { int lastbutton = 0; + int menu_return = 0; while (true) { @@ -2857,9 +3011,47 @@ #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; + }else{ + rotate_screen = false; + } + //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 Index: apps/bitmaps/native/rockboxlogo.176x54x16.bmp =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream