Index: apps/plugins/jpeg/yuv2rgb.c =================================================================== --- apps/plugins/jpeg/yuv2rgb.c (revision 21362) +++ apps/plugins/jpeg/yuv2rgb.c (working copy) @@ -7,9 +7,10 @@ * \/ \/ \/ \/ \/ * $Id$ * -* JPEG image viewer -* (This is a real mess if it has to be coded in one single C file) -* +* Colour Conversion and Rotation +* +* Landscape rotation addition by GRaTT +* code by Rene Peinthor and Adam Geshlin with modifications made by GRaTT * File scrolling addition (C) 2005 Alexander Spyridakis * Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon * Heavily borrowed from the IJG implementation (C) Thomas G. Lane @@ -236,7 +237,175 @@ [DITHER_DIFFUSION] = pixel_fsdither_to_lcd, }, }; - + +/* Rotate Function */ + +#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. */ +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 */ + int colour_mode) +{ + 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; + +/******************* Center rotated image in screen *************************/ + if (width > LCD_HEIGHT) + width = LCD_HEIGHT; + if (width < LCD_HEIGHT) + _x = (LCD_HEIGHT - width)/2; + + if (height > LCD_WIDTH) + height = LCD_WIDTH; + if (height < LCD_WIDTH) + _y = (LCD_WIDTH - height)/2; +/************** end of Center rotated image in screen ***********************/ + + width = (width + 1) & ~1; + + dst = rb->lcd_framebuffer + _x * LCD_WIDTH + (LCD_WIDTH - _y) - 1; + dst_end = dst - (height - 1); + +/** black and white pict will crash the sim *****************************/ +#ifdef SIMULATOR + if (!csub_y) /* if not colour */ + { + rb->splash(HZ, "File not supported"); + }else{ +#endif + if (colour_mode == COLOURMODE_GRAY){ +#ifdef SIMULATOR + //rb->splash(HZ, "Grayscale not fully supported in simulator"); +#endif + csub_y = 0; + } + 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 */ +/** Grayscale work around on simulator *****************/ +#ifdef SIMULATOR + if (csub_y == 0){ + usrc = src[1] + (stride/csub_x) * (csub_y) + + (src_x/csub_x); + vsrc = src[2] + (stride/csub_x) * (csub_y) + + (src_x/csub_x); + } + else + { +#endif + 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); +#ifdef SIMULATOR + } +#endif + + 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); +#ifdef SIMULATOR + }/* if not colour */ +#endif +} + /** * Draw a partial YUV colour bitmap * @@ -246,120 +415,102 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y, int src_x, int src_y, int stride, int x, int y, int width, int height, - int colour_mode, int dither_mode) + int colour_mode, int dither_mode, int rotate_screen) { - fb_data *dst, *dst_end; - fb_data (*pixel_func)(void); - struct rgb_pixel px; + + if(rotate_screen) + { + rotate(src, csub_x, csub_y, + src_x, src_y, stride, + x, y, width, height, colour_mode); + } + 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 < 0) - width += x, x = 0; /* Clip left */ - if (width <= 0) - return; /* nothing left to do */ + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - 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 < 0) - height += y, y = 0; /* Clip top */ - if (height <= 0) - return; /* nothing left to do */ + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; /* Clip bottom */ + if (y < 0) + height += y, y = 0; /* Clip top */ + if (height <= 0) + return; /* nothing left to do */ - pixel = &px; + pixel = &px; - dst = rb->lcd_framebuffer + LCD_WIDTH * y + x; - dst_end = dst + LCD_WIDTH * height; + dst = rb->lcd_framebuffer + LCD_WIDTH * y + x; + dst_end = dst + LCD_WIDTH * height; - if (colour_mode == COLOURMODE_GRAY) - csub_y = 0; /* Ignore Cb, Cr */ + if (colour_mode == COLOURMODE_GRAY) + csub_y = 0; /* Ignore Cb, Cr */ - pixel_func = pixel_funcs[colour_mode] + pixel_func = pixel_funcs[colour_mode] [dither_mode]; - if (dither_mode == DITHER_DIFFUSION) - { - /* Reset error terms. */ - px.e = rgb_err_buffers; - px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0; - rb->memset(px.e, 0, 3*sizeof (struct rgb_err)); - } - - do - { - fb_data *dst_row, *row_end; - const unsigned char *ysrc; - px.inc = 1; - if (dither_mode == DITHER_DIFFUSION) { - /* Use R->L scan on odd lines */ - px.inc -= (src_y & 1) << 1; - px.epos = x + 1; - - if (px.inc < 0) - px.epos += width - 1; + /* Reset error terms. */ + px.e = rgb_err_buffers; + px.ce[RED] = px.ce[GRN] = px.ce[BLU] = 0; + rb->memset(px.e, 0, 3*sizeof (struct rgb_err)); } - if (px.inc == 1) + do { - /* Scan is L->R */ - dst_row = dst; - row_end = dst_row + width; - px.col = src_x; - } - else - { - /* Scan is R->L */ - row_end = dst - 1; - dst_row = row_end + width; - px.col = src_x + width - 1; - } + fb_data *dst_row, *row_end; + const unsigned char *ysrc; + px.inc = 1; - ysrc = src[0] + stride * src_y + px.col; - px.row = src_y; + if (dither_mode == DITHER_DIFFUSION) + { + /* Use R->L scan on odd lines */ + px.inc -= (src_y & 1) << 1; + px.epos = x + 1; - /* Do one row of pixels */ - if (csub_y) /* colour */ - { - /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ - const unsigned char *usrc, *vsrc; + if (px.inc < 0) + px.epos += width - 1; + } - usrc = src[1] + (stride/csub_x) * (src_y/csub_y) - + (px.col/csub_x); - vsrc = src[2] + (stride/csub_x) * (src_y/csub_y) - + (px.col/csub_x); - int xphase = px.col % csub_x; - int xphase_reset = px.inc * csub_x; - int y, v, u, rv, guv, bu; + if (px.inc == 1) + { + /* Scan is L->R */ + dst_row = dst; + row_end = dst_row + width; + px.col = src_x; + } + else + { + /* Scan is R->L */ + row_end = dst - 1; + dst_row = row_end + width; + px.col = src_x + width - 1; + } - v = *vsrc - 128; - vsrc += px.inc; - u = *usrc - 128; - usrc += px.inc; - rv = RVFAC*v; - guv = GUFAC*u + GVFAC*v; - bu = BUFAC*u; + ysrc = src[0] + stride * src_y + px.col; + px.row = src_y; - while (1) + /* Do one row of pixels */ + if (csub_y) /* colour */ { - y = YFAC*(*ysrc); - ysrc += px.inc; - px.r = y + rv; - px.g = y + guv; - px.b = y + bu; + /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ + const unsigned char *usrc, *vsrc; - *dst_row = pixel_func(); - dst_row += px.inc; + usrc = src[1] + (stride/csub_x) * (src_y/csub_y) + + (px.col/csub_x); + vsrc = src[2] + (stride/csub_x) * (src_y/csub_y) + + (px.col/csub_x); + int xphase = px.col % csub_x; + int xphase_reset = px.inc * csub_x; + int y, v, u, rv, guv, bu; - if (dst_row == row_end) - break; - - xphase += px.inc; - if ((unsigned)xphase < (unsigned)csub_x) - continue; - - /* fetch new chromas */ v = *vsrc - 128; vsrc += px.inc; u = *usrc - 128; @@ -368,24 +519,52 @@ guv = GUFAC*u + GVFAC*v; bu = BUFAC*u; - xphase -= xphase_reset; + while (1) + { + y = YFAC*(*ysrc); + ysrc += px.inc; + px.r = y + rv; + px.g = y + guv; + px.b = y + bu; + + *dst_row = pixel_func(); + dst_row += px.inc; + + if (dst_row == row_end) + break; + + xphase += px.inc; + if ((unsigned)xphase < (unsigned)csub_x) + continue; + + /* fetch new chromas */ + v = *vsrc - 128; + vsrc += px.inc; + u = *usrc - 128; + usrc += px.inc; + rv = RVFAC*v; + guv = GUFAC*u + GVFAC*v; + bu = BUFAC*u; + + xphase -= xphase_reset; + } } - } - else /* monochrome */ - { - do + else /* monochrome */ { - /* Set all components the same for dithering purposes */ - px.g = px.r = px.b = YFAC*(*ysrc); - *dst_row = pixel_func(); - ysrc += px.inc; - dst_row += px.inc; + do + { + /* Set all components the same for dithering purposes */ + px.g = px.r = px.b = YFAC*(*ysrc); + *dst_row = pixel_func(); + ysrc += px.inc; + dst_row += px.inc; + } + while (dst_row != row_end); } - while (dst_row != row_end); + + src_y++; + dst += LCD_WIDTH; } - - src_y++; - dst += LCD_WIDTH; + while (dst < dst_end); } - while (dst < dst_end); } Index: apps/plugins/jpeg/jpeg.c =================================================================== --- apps/plugins/jpeg/jpeg.c (revision 21362) +++ apps/plugins/jpeg/jpeg.c (working copy) @@ -75,8 +75,13 @@ /******************************* Globals ***********************************/ +/* screenwidth/height for zoom in landscape mode */ +static int screenwidth = LCD_WIDTH; +static int screenheight = LCD_HEIGHT; +static int rotate_screen = false; /* rotate screen */ +static int auto_rotate_enabled = false; /* auto rotate screen */ static int slideshow_enabled = false; /* run slideshow */ -static int running_slideshow = false; /* loading image because of slideshw */ +static int running_slideshow = false; /* loading image because of slideshow */ #ifndef SIMULATOR static int immediate_ata_off = false; /* power down disk after loading */ #endif @@ -255,7 +260,7 @@ /* 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_NEXT */ { do { @@ -266,6 +271,11 @@ curfile++; }while(file_pt[curfile] == '\0' && count < entries); } + /* not required now maybe required later */ + /* else */ /* DIR_NONE */ + /* { */ + + /* } */ if(count == entries && file_pt[curfile] == '\0') { @@ -352,6 +362,8 @@ enum menu_id { MIID_RETURN = 0, + MIID_ROTATE, + MIID_AUTO_ROTATE_MODE, MIID_TOGGLE_SS_MODE, MIID_CHANGE_SS_MODE, #if PLUGIN_BUFFER_SIZE >= MIN_MEM @@ -363,8 +375,10 @@ MIID_QUIT, }; + + MENUITEM_STRINGLIST(menu, "Jpeg Menu", NULL, - "Return", "Toggle Slideshow Mode", + "Return", "Toggle Portrait/Landscape view", "Toggle Auto Rotate Mode", "Toggle Slideshow Mode", "Change Slideshow Time", #if PLUGIN_BUFFER_SIZE >= MIN_MEM "Show Playback Menu", @@ -378,13 +392,25 @@ { "Disable", -1 }, { "Enable", -1 }, }; - + static const struct opt_items auto_rotate[2] = { + { "Disable", -1 }, + { "Enable", -1 }, + }; + + result=rb->do_menu(&menu, NULL, NULL, false); switch (result) { case MIID_RETURN: break; + case MIID_ROTATE: + return 3; + break; + case MIID_AUTO_ROTATE_MODE: + rb->set_option("Toggle Auto Rotate", &auto_rotate_enabled, INT, + auto_rotate , 2, NULL); + break; case MIID_TOGGLE_SS_MODE: rb->set_option("Toggle Slideshow", &slideshow_enabled, INT, slideshow , 2, NULL); @@ -462,7 +488,8 @@ 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); + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); #else MYXLCD(gray_bitmap_part)( pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move, @@ -491,7 +518,8 @@ 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); + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); #else MYXLCD(gray_bitmap_part)( pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, @@ -527,7 +555,8 @@ 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); + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); #else MYXLCD(gray_bitmap_part)( pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, @@ -567,7 +596,8 @@ 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); + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); if (jpeg_settings.dither_mode == DITHER_DIFFUSION) { @@ -593,6 +623,7 @@ { int button; int lastbutton = 0; + int menu_return = 0; while (true) { @@ -674,6 +705,24 @@ #endif return ZOOM_OUT; break; + +#ifdef JPEG_ROTATE + case JPEG_ROTATE: + if (!rotate_screen) + { + rotate_screen = true; + screenwidth = LCD_HEIGHT; + screenheight = LCD_WIDTH; + } + else + { + rotate_screen = false; + screenwidth = LCD_WIDTH; + screenheight = LCD_HEIGHT; + } + return change_filename(DIR_NONE); + break; +#endif #ifdef JPEG_RC_MENU case JPEG_RC_MENU: #endif @@ -681,8 +730,45 @@ #ifdef USEGSLIB grey_show(false); /* switch off greyscale overlay */ #endif - if (show_menu() == 1) + menu_return = show_menu(); + if (menu_return == 1) + { return PLUGIN_OK; + } + if (menu_return == 3) + { + rb->lcd_clear_display(); + rb->lcd_puts(0,1,"Toggle Portrait/landscape"); + 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(); + if (!rotate_screen) + { + rotate_screen = true; + screenwidth = LCD_HEIGHT; + screenheight = LCD_WIDTH; + } + else + { + rotate_screen = false; + screenwidth = LCD_WIDTH; + screenheight = LCD_HEIGHT; + } + 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 */ @@ -694,7 +780,8 @@ 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); + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); MYLCD_UPDATE(); #endif break; @@ -719,17 +806,35 @@ 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, + /* flip scroll bar when in landscape mode */ + if(rotate_screen){ + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], 0, 2, 4, LCD_HEIGHT-4, total, 0, + current, VERTICAL); + rb->lcd_update_rect(0, 2, 4, LCD_HEIGHT-4); + } + else + { + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0, current, HORIZONTAL); - rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); + rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4); + } } #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, - current, HORIZONTAL); - rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4); + /* flip scroll bar when in landscape mode */ + if(rotate_screen){ + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], 0, 2, 2, LCD_HEIGHT-4, total, 0, + current, VERTICAL); + rb->lcd_update_rect(0, 2, 2, LCD_HEIGHT-4); + } + else + { + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, LCD_HEIGHT-4, LCD_WIDTH, 4, total, 0, + current, HORIZONTAL); + rb->lcd_update_rect(0, LCD_HEIGHT-4, LCD_WIDTH, 4); + } } #endif } @@ -772,8 +877,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; } @@ -842,7 +947,7 @@ { rb->snprintf(print, sizeof(print), "decoding %d*%d", p_jpg->x_size/ds, p_jpg->y_size/ds); - rb->lcd_puts(0, 3, print); + rb->lcd_puts(2, 3, print); rb->lcd_update(); } @@ -886,12 +991,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); @@ -905,8 +1010,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; } @@ -1017,11 +1122,11 @@ rb->lcd_clear_display(); rb->snprintf(print, sizeof(print), "%s:", rb->strrchr(filename,'/')+1); - rb->lcd_puts(0, 0, print); + rb->lcd_puts(2, 0, print); rb->lcd_update(); rb->snprintf(print, sizeof(print), "loading %d bytes", filesize); - rb->lcd_puts(0, 1, print); + rb->lcd_puts(2, 1, print); rb->lcd_update(); } @@ -1031,7 +1136,7 @@ if(!running_slideshow) { rb->snprintf(print, sizeof(print), "decoding markers"); - rb->lcd_puts(0, 2, print); + rb->lcd_puts(2, 2, print); rb->lcd_update(); } #ifndef SIMULATOR @@ -1057,10 +1162,33 @@ default_huff_tbl(&jpg); /* use default */ build_lut(&jpg); /* derive Huffman and other lookup-tables */ + if(auto_rotate_enabled) + { + int lcd_diff, jpeg_diff; + + lcd_diff = LCD_HEIGHT - LCD_WIDTH; + jpeg_diff = jpg.y_size - jpg.x_size; + + if((jpeg_diff < 0 && lcd_diff > 0) || + (jpeg_diff > 0 && lcd_diff < 0)) + { + rotate_screen = true; + screenwidth = LCD_HEIGHT; + screenheight = LCD_WIDTH; + } + else + { + rotate_screen = false; + screenwidth = LCD_WIDTH; + screenheight = LCD_HEIGHT; + } + } + + 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_puts(2, 2, print); rb->lcd_update(); } ds_max = max_downscale(&jpg); /* check display constraint */ @@ -1088,7 +1216,7 @@ { rb->snprintf(print, sizeof(print), "showing %dx%d", p_disp->width, p_disp->height); - rb->lcd_puts(0, 3, print); + rb->lcd_puts(2, 3, print); rb->lcd_update(); } MYLCD(clear_display)(); @@ -1096,18 +1224,19 @@ 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); + MAX(0, (screenwidth - p_disp->width) / 2), + MAX(0, (screenheight - p_disp->height) / 2), + MIN(screenwidth, p_disp->width), + MIN(screenheight, p_disp->height), + jpeg_settings.colour_mode, jpeg_settings.dither_mode, + rotate_screen); #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(); @@ -1199,7 +1328,7 @@ #ifdef USEGSLIB if (!grey_init(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/plugins/jpeg/yuv2rgb.h =================================================================== --- apps/plugins/jpeg/yuv2rgb.h (revision 21362) +++ apps/plugins/jpeg/yuv2rgb.h (working copy) @@ -46,6 +46,6 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y, int src_x, int src_y, int stride, int x, int y, int width, int height, - int colour_mode, int dither_mode); - + int colour_mode, int dither_mode, + int rotate_screen); #endif Index: apps/plugins/jpeg/jpeg.h =================================================================== --- apps/plugins/jpeg/jpeg.h (revision 21362) +++ apps/plugins/jpeg/jpeg.h (working copy) @@ -115,6 +115,7 @@ #define JPEG_LEFT BUTTON_LEFT #define JPEG_RIGHT BUTTON_RIGHT #define JPEG_MENU BUTTON_MENU +#define JPEG_ROTATE BUTTON_POWER #define JPEG_NEXT (BUTTON_A | BUTTON_RIGHT) #define JPEG_PREVIOUS (BUTTON_A | BUTTON_LEFT)