diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/gui/gwps-common.c rockbox/apps/gui/gwps-common.c
--- rockbox_orig/apps/gui/gwps-common.c	2006-07-27 07:41:27.812689600 +0900
+++ rockbox/apps/gui/gwps-common.c	2006-07-27 06:49:17.831998400 +0900
@@ -289,7 +289,7 @@
                 data->progressbar.bm.data=data->img_buf_ptr;
                 ret = read_bmp_file(imgname, &data->progressbar.bm,
                                     data->img_buf_free,
-                                    FORMAT_ANY|FORMAT_TRANSPARENT);
+                                    FORMAT_ANY|FORMAT_TRANSPARENT, 0, 0);
                         
                 if (ret > 0)
                 {
@@ -403,7 +403,7 @@
                         data->img[n].bm.data = data->img_buf_ptr;
                         ret = read_bmp_file(imgname, &data->img[n].bm,
                                             data->img_buf_free,
-                                            FORMAT_ANY|FORMAT_TRANSPARENT);
+                                            FORMAT_ANY|FORMAT_TRANSPARENT, 0, 0);
                         
                         if (ret > 0)
                         {
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/gui/gwps.h rockbox/apps/gui/gwps.h
--- rockbox_orig/apps/gui/gwps.h	2006-07-27 07:41:27.852747200 +0900
+++ rockbox/apps/gui/gwps.h	2006-07-27 06:49:17.842012800 +0900
@@ -324,7 +324,7 @@
 #ifdef HAVE_LCD_BITMAP
 #define MAX_IMAGES (26*2) /* a-z and A-Z */
 #define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
-                   + (2*LCD_HEIGHT*LCD_WIDTH/8))
+                   + (2*LCD_HEIGHT*LCD_WIDTH/2))
 #define WPS_MAX_LINES (LCD_HEIGHT/5+1)
 #define FORMAT_BUFFER_SIZE 3072
 #else
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/plugin.h rockbox/apps/plugin.h
--- rockbox_orig/apps/plugin.h	2006-07-22 19:57:59.000000000 +0900
+++ rockbox/apps/plugin.h	2006-07-27 06:49:09.740363200 +0900
@@ -467,7 +467,7 @@
 #endif
 #ifdef HAVE_LCD_BITMAP
     int (*read_bmp_file)(char* filename, struct bitmap *bm, int maxsize,
-                         int format);
+                         int format, int xsize, int ysize);    // if xsize=0 or ysize=0, load original size
     void (*screen_dump_set_hook)(void (*hook)(int fh));
 #endif
     int (*show_logo)(void);
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/plugins/SOURCES rockbox/apps/plugins/SOURCES
--- rockbox_orig/apps/plugins/SOURCES	2006-07-22 19:58:02.000000000 +0900
+++ rockbox/apps/plugins/SOURCES	2006-07-27 06:49:09.760392000 +0900
@@ -17,6 +17,7 @@
 stopwatch.c
 vbrfix.c
 viewer.c
+bmpviewer.c
 
 #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) && !defined(SIMULATOR)
 wavplay.c
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/plugins/bmpviewer.c rockbox/apps/plugins/bmpviewer.c
--- rockbox_orig/apps/plugins/bmpviewer.c	1970-01-01 09:00:00.000000000 +0900
+++ rockbox/apps/plugins/bmpviewer.c	2006-07-27 06:49:09.780420800 +0900
@@ -0,0 +1,238 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: bmpwiewer.c,v 0.1 2006-07-23 20:11:02 takka Exp $
+ *
+ * Copyright (C) 2006 takka <takka@tfact.net>
+ * Based on parts of rockpaint 1.1, Copyright (C) 2005 dionoea
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+
+#include "plugin.h"
+#include "errno.h"
+
+PLUGIN_HEADER
+
+/***********************************************************************
+ * Buttons
+ ***********************************************************************/
+
+#if ( CONFIG_KEYPAD == IRIVER_H300_PAD ) || ( CONFIG_KEYPAD == IRIVER_H100_PAD )
+#define BMPVIEWER_QUIT      BUTTON_OFF
+#define BMPVIEWER_DRAW      BUTTON_SELECT
+#define BMPVIEWER_MENU      BUTTON_ON
+#define BMPVIEWER_TOOLBAR   BUTTON_REC
+#define BMPVIEWER_TOOLBAR2  BUTTON_MODE
+#define BMPVIEWER_UP        BUTTON_UP
+#define BMPVIEWER_DOWN      BUTTON_DOWN
+#define BMPVIEWER_LEFT      BUTTON_LEFT
+#define BMPVIEWER_RIGHT     BUTTON_RIGHT
+
+#elif ( CONFIG_KEYPAD == IPOD_4G_PAD ) || ( CONFIG_KEYPAD == IPOD_3G_PAD )
+#define BMPVIEWER_QUIT      ( ~BUTTON_MAIN )
+#define BMPVIEWER_DRAW      BUTTON_SELECT
+#define BMPVIEWER_MENU      ( BUTTON_SELECT | BUTTON_MENU )
+#define BMPVIEWER_TOOLBAR   ( BUTTON_MENU | BUTTON_LEFT )
+#define BMPVIEWER_TOOLBAR2  ( BUTTON_MENU | BUTTON_RIGHT )
+#define BMPVIEWER_UP        BUTTON_MENU
+#define BMPVIEWER_DOWN      BUTTON_PLAY
+#define BMPVIEWER_LEFT      BUTTON_LEFT
+#define BMPVIEWER_RIGHT     BUTTON_RIGHT
+
+#elif ( CONFIG_KEYPAD == IAUDIO_X5_PAD )
+#define BMPVIEWER_QUIT      BUTTON_POWER
+#define BMPVIEWER_DRAW      BUTTON_SELECT
+#define BMPVIEWER_MENU      BUTTON_PLAY
+#define BMPVIEWER_TOOLBAR   BUTTON_REC
+#define BMPVIEWER_TOOLBAR2  ( BUTTON_REC | BUTTON_LEFT )
+#define BMPVIEWER_UP        BUTTON_UP
+#define BMPVIEWER_DOWN      BUTTON_DOWN
+#define BMPVIEWER_LEFT      BUTTON_LEFT
+#define BMPVIEWER_RIGHT     BUTTON_RIGHT
+
+#else
+#error "Please define keys for this keypad"
+#endif
+
+/***********************************************************************
+ * Program Colors
+ ***********************************************************************/
+
+#define ROWS    LCD_HEIGHT
+#define COLS    LCD_WIDTH
+
+static void restore_screen(void);
+static void clear_drawing(void);
+static void init_buffer(void);
+static int load_bitmap( char *filename, int x, int y );
+extern int errno;
+
+/***********************************************************************
+ * Global variables
+ ***********************************************************************/
+
+#if !defined(SIMULATOR) || defined(__MINGW32__) || defined(__CYGWIN__)
+int errno;
+#endif
+
+static struct plugin_api* rb;
+static bool quit=false;
+static fb_data save_buffer[ ROWS*COLS ];
+
+/* Current filename */
+static char filename[MAX_PATH+1];
+
+/***********************************************************************
+ * Misc routines
+ ***********************************************************************/
+static bool rockpaint_loop( void )
+{
+    int button=0;
+    int x = COLS;
+    int y = ROWS;
+
+    while (!quit) {
+        button = rb->button_get(true);
+
+        switch(button)
+        {
+            case BMPVIEWER_QUIT:
+                rb->lcd_set_drawmode(DRMODE_SOLID);
+                return PLUGIN_OK;
+            case BMPVIEWER_DOWN:
+                y -= 5;
+                if ( y < 5 ) y = 5;
+//                clear_drawing();
+                init_buffer();
+                load_bitmap( filename, x, y);
+                restore_screen();
+                rb->lcd_update();
+                break;
+            case BMPVIEWER_UP:
+                y += 5;
+                if ( y > ROWS ) y = ROWS;
+//                clear_drawing();
+                init_buffer();
+                load_bitmap( filename, x, y);
+                restore_screen();
+                rb->lcd_update();
+                break;
+            case BMPVIEWER_LEFT:
+                x -= 5;
+                if ( x < 5 ) x = 5;
+//                clear_drawing();
+                init_buffer();
+                load_bitmap( filename, x, y);
+                restore_screen();
+                rb->lcd_update();
+                break;
+            case BMPVIEWER_RIGHT:
+                x += 5;
+                if ( x > COLS ) x = COLS;
+//                clear_drawing();
+                init_buffer();
+                load_bitmap( filename, x, y);
+                restore_screen();
+                rb->lcd_update();
+                break;
+            default:
+                if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
+                    return PLUGIN_USB_CONNECTED;
+                break;
+        }
+    }
+
+    return PLUGIN_OK;
+}
+
+static int load_bitmap( char *file, int x, int y )
+{
+    struct bitmap bm;
+    bool ret;
+    bm.data = (char*)save_buffer;
+    ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ),
+                              FORMAT_NATIVE, x, y);
+    if( bm.width < COLS )
+    {
+        int l;
+        for( l = bm.height-1; l > 0; l-- )
+        {
+            rb->memmove( save_buffer+l*COLS, save_buffer+l*bm.width,
+                         sizeof( fb_data )*bm.width );
+        }
+        for( l = 0; l < bm.height; l++ )
+        {
+            rb->memset( save_buffer+l*COLS+bm.width, 0,
+                        sizeof( fb_data )*(COLS-bm.width) );
+        }
+        rb->memset( save_buffer+COLS*bm.height, 0,
+                    sizeof( fb_data )*COLS*(ROWS-bm.height) );
+    }
+    return ret;
+}
+
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+    /** must have stuff **/
+    rb = api;
+
+    rb->lcd_clear_display();
+
+    filename[0] = '\0';
+
+    if( parameter )
+    {
+        if( load_bitmap( parameter, COLS, ROWS ) <= 0 )
+        {
+            rb->splash( 1*HZ, true, "Error");
+            clear_drawing();
+        }
+        else
+        {
+            rb->splash( 1*HZ, true, "Image loaded (%s)", parameter );
+            restore_screen();
+            rb->strcpy( filename, parameter );
+        }
+    }
+    else
+    {
+        clear_drawing();
+    }
+    rb->lcd_update();
+
+    return rockpaint_loop();
+}
+
+static void clear_drawing(void)
+{
+    init_buffer();
+    rb->lcd_set_foreground( LCD_DEFAULT_BG );
+    rb->lcd_fillrect( 0, 0, COLS, ROWS );
+    rb->lcd_update();
+}
+
+static void init_buffer(void)
+{
+    int i;
+    fb_data color = LCD_DEFAULT_BG;
+    for( i = 0; i < ROWS*COLS; i++ )
+    {
+        save_buffer[i] = 0;
+    }
+}
+
+static void restore_screen(void)
+{
+    rb->lcd_bitmap( save_buffer, 0, 0, COLS, ROWS );
+}
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/plugins/rockpaint.c rockbox/apps/plugins/rockpaint.c
--- rockbox_orig/apps/plugins/rockpaint.c	2006-07-24 15:06:23.000000000 +0900
+++ rockbox/apps/plugins/rockpaint.c	2006-07-27 06:49:09.790435200 +0900
@@ -2786,7 +2786,7 @@
     bool ret;
     bm.data = (char*)save_buffer;
     ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ),
-                              FORMAT_NATIVE );
+                              FORMAT_NATIVE, COLS, ROWS);
     if( bm.width < COLS )
     {
         int l;
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/plugins/viewers.config rockbox/apps/plugins/viewers.config
--- rockbox_orig/apps/plugins/viewers.config	2006-07-22 19:58:02.000000000 +0900
+++ rockbox/apps/plugins/viewers.config	2006-07-27 06:49:09.820478400 +0900
@@ -21,5 +21,6 @@
 wav,viewers/mp3_encoder, 00 00 00 00 00 00
 wav,viewers/wavplay,60 7F 05 35 3F 00
 bmp,rocks/rockpaint, 01 10 01 10 01 10
+bmp,viewers/bmpviewer, 01 10 01 10 01 10
 m2v,viewers/mpegplayer,5D 7F 5D 7F 5D 7F
 iriver,viewers/iriver_flash,2A 7F 41 41 7F 2A

diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/recorder/backdrop.c rockbox/apps/recorder/backdrop.c
--- rockbox_orig/apps/recorder/backdrop.c	2006-05-21 20:00:02.000000000 +0900
+++ rockbox/apps/recorder/backdrop.c	2006-07-27 06:49:09.830492800 +0900
@@ -36,7 +36,7 @@
 
     /* load the image */
     bm.data=(char*)backdrop_buffer;
-    ret = read_bmp_file(filename, &bm, sizeof(main_backdrop), FORMAT_NATIVE);
+    ret = read_bmp_file(filename, &bm, sizeof(main_backdrop), FORMAT_NATIVE, LCD_WIDTH, LCD_HEIGHT);    // auto resize LCD size
 
     if ((ret > 0) && (bm.width == LCD_WIDTH) && (bm.height == LCD_HEIGHT))
     {
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/recorder/bmp.c rockbox/apps/recorder/bmp.c
--- rockbox_orig/apps/recorder/bmp.c	2006-04-25 00:52:05.000000000 +0900
+++ rockbox/apps/recorder/bmp.c	2006-07-27 07:33:22.965513600 +0900
@@ -41,6 +41,10 @@
 #pragma pack (push, 2)
 #endif
 
+#define RED 2
+#define GREEN 1
+#define BLUE 0
+
 /* Struct from original code. */
 struct Fileheader {
     unsigned short Type;        /* signature - 'BM' */
@@ -94,6 +98,7 @@
     return (bmpbuf[a] & (1 << b)) != 0;
 }
 
+    unsigned char bmpbuf[1024*sizeof(struct rgb_quad)]; /* Buffer for one line */
 
 /******************************************************************************
  * read_bmp_file()
@@ -104,10 +109,12 @@
 int read_bmp_file(char* filename,
                   struct bitmap *bm,
                   int maxsize,
-                  int format)
+                  int format,
+                  int dst_x,
+                  int dst_y)
 {
     struct Fileheader fh;
-    int width, height, PaddedWidth, PaddedHeight, dst_width;
+    int src_x, src_y, SrcPaddedWidth, DstPaddedHeight, DstPaddedWidth;
     int fd, row, col, ret;
     struct rgb_quad palette[256];
     int invert_pixel = 0;
@@ -115,8 +122,26 @@
     int depth;
     int totalsize;
     char *bitmap = bm->data;
-    
-    unsigned char bmpbuf[LCD_WIDTH*sizeof(struct rgb_quad)]; /* Buffer for one line */
+    int delta_x;
+    int delta_y;
+    int ratio_x;
+    int ratio_y;
+    int ratio;
+    int trans_x;
+    int trans_x1;
+    int trans_x2;
+    int trans_y;
+    int trans_y1;
+    int trans_y2;
+    int write_flag;
+    int count_y;
+    int loop_y;
+    int color_buf[LCD_WIDTH][3] = { {0, 0, 0} };
+    int buf_blue, buf_green, buf_red, loop_x, x_position;
+    struct rgb_quad rgb;
+    struct rgb_quad rgb_work;
+    unsigned char *buf_pointer;
+    int threshold;
 
 #if LCD_DEPTH == 1
     format = FORMAT_MONO;
@@ -152,29 +177,65 @@
     }
 
     /* Exit if too wide */
-    if (readlong(&fh.Width) > LCD_WIDTH) {
-        DEBUGF("error - Bitmap is too wide (%d pixels, max is %d)\n",
-                        readlong(&fh.Width), LCD_WIDTH);
+    if (dst_x > LCD_WIDTH) {
+        DEBUGF("error - X size is too wide (%d pixels, max is %d)\n",
+                        dst_x, LCD_WIDTH);
         close(fd);
         return -5;
     }
 
     /* Exit if too high */
-    if (readlong(&fh.Height) > LCD_HEIGHT) {
-        DEBUGF("error - Bitmap is too high (%d pixels, max is %d)\n",
-                        readlong(&fh.Height), LCD_HEIGHT);
+    if (dst_y > LCD_HEIGHT) {
+        DEBUGF("error - Y size is too high (%d pixels, max is %d)\n",
+                        dst_y, LCD_HEIGHT);
         close(fd);
         return -6;
     }
 
     /* Calculate image size */
-    height = readlong(&fh.Height);
-    width = readlong(&fh.Width);
+    src_y = readlong(&fh.Height);
+    src_x = readlong(&fh.Width);
     depth = readshort(&fh.BitCount);
 
-    /* 4-byte boundary aligned */
-    PaddedWidth = ((width * depth + 31) / 8) & ~3;
+    /* Exit if too wide(bmp file) */
+    if (src_x > 1024) {
+        DEBUGF("error - Bitmap is too wide (%d pixels, max is 1024)\n",src_x);
+        close(fd);
+        return -5;
+    }
 
+    if ((dst_x == 0) || (dst_y == 0)) {
+        dst_x = src_x;
+        dst_y = src_y;
+    }
+
+    delta_x = 0;
+    delta_y = 0;
+    count_y = 0;
+
+    ratio_x = 1024 * dst_x / src_x;    /* x ratio (fixed zero point) */
+    ratio_y = 1024 * dst_y / src_y;    /* y ratio (fixed zero point) */
+    ratio = (ratio_x<ratio_y?ratio_x:ratio_y); /* ratio = min(x_ratio,y_ratio) */           
+    trans_x = ratio * src_x / 1024;
+    trans_y = ratio * src_y / 1024; DEBUGF("%d\n",ratio);
+    trans_x1 = dst_x - trans_x;
+    if (trans_x1 == 0) {
+      trans_x2 = LCD_WIDTH+1;
+    } else {
+      trans_x1 /= 2;
+      trans_x2 = trans_x1 + trans_x -1;
+    }
+    trans_y1 = dst_y - trans_y;
+    if (trans_y1 == 0) {
+      trans_y2 = LCD_HEIGHT+1;
+    } else {
+      trans_y1 /= 2;
+      trans_y2 = trans_y1 + trans_y -1;
+    }
+
+    /* 4-byte boundary aligned */
+    /* src 1 Line bytes */
+    SrcPaddedWidth = ((src_x * depth + 31) / 8) & ~3;
 #if LCD_DEPTH > 1
         if(format == FORMAT_ANY) {
             if(depth == 1)
@@ -183,33 +244,39 @@
                 format = FORMAT_NATIVE;
         }
 #endif
+    if (depth == 1) {
+        threshold = 0;
+    } else {
+        threshold = 96;
+    }
 
-    /* PaddedHeight is for rockbox format. */
+    /* DstPaddedHeight is for rockbox format Height Bytes*/
+    /* DstPaddedWidth is for rockbox format Width Bytes*/
     if(format == FORMAT_MONO) {
-        PaddedHeight = (height + 7) / 8;
-        dst_width = width;
-        totalsize = PaddedHeight * dst_width;
+        DstPaddedHeight = (dst_y + 7) / 8;
+        DstPaddedWidth = dst_x;
+        totalsize = DstPaddedHeight * DstPaddedWidth;
     } else {
 #if LCD_DEPTH == 2
 #if LCD_PIXELFORMAT == VERTICAL_PACKING
-        PaddedHeight = (height + 3) / 4;
-        dst_width = width;
+        DstPaddedHeight = (dst_y + 3) / 4;
+        DstPaddedWidth = dst_x;
 #else
-        PaddedHeight = height;
-        dst_width = (width + 3) / 4;
+        DstPaddedHeight = dst_y;
+        DstPaddedWidth = (dst_x + 3) / 4;
 #endif
 #else
-        PaddedHeight = height;
-        dst_width = width;
+        DstPaddedHeight = dst_y;
+        DstPaddedWidth = dst_x;
 #endif
-        totalsize = PaddedHeight * dst_width * sizeof(fb_data);
+        totalsize = DstPaddedHeight * DstPaddedWidth * sizeof(fb_data);
     }
 
     /* Check if this fits the buffer */
     
     if (totalsize > maxsize) {
         DEBUGF("error - Bitmap is too large to fit the supplied buffer: "
-               "%d bytes.\n", (PaddedHeight * dst_width));
+               "%d bytes.%d:%d\n", (DstPaddedHeight * DstPaddedWidth),totalsize,maxsize);
         close(fd);
         return -7;
     }
@@ -248,203 +315,186 @@
 #endif
     
     /* loop to read rows and put them to buffer */
-    for (row = 0; row < height; row++) {
-        unsigned char *p;
-        
-        /* read one row */
-        ret = read(fd, bmpbuf, PaddedWidth);
-        if (ret != PaddedWidth) {
-            DEBUGF("error reading image, read returned: %d expected was: "
-                   "%d\n", ret, PaddedWidth);
-            close(fd);
-            return -9;
-        }
+    delta_y = 0;
+    count_y = 0;
+    write_flag = 1;
+    loop_y = 1;
+    /* read one row */
+    ret = read(fd, bmpbuf, SrcPaddedWidth); /* src_y++ */
+    if (ret != SrcPaddedWidth) {
+        DEBUGF("error reading image, read returned: %d expected was: "
+               "%d\n", ret, SrcPaddedWidth);
+        close(fd);
+        return -9;
+    }
 
-        switch(depth) {
-        case 1:
+/* src_x,src_y -> dst_x,dst_y ( used bresenham Algorithm ) */
+    for (row = 0; row < dst_y; row++ ) { /* dst_y Loop */
+            buf_pointer = bmpbuf;
+            delta_x = 0;
+            buf_blue = 0;
+            buf_green = 0;
+            buf_red = 0;
+            loop_x = 1;
+            x_position = 0;
+            for (col = 0; col < dst_x ; col++) { /* dst_x Loop */
+                if ((trans_x1 <= col) && (col <= trans_x2 ) && (trans_y1 <= row) && (row <= trans_y2 )) {
+                    switch(depth) {
+                        case 1:
+                        /* Format Mono */
+                            ret = getpix(x_position, bmpbuf);
+                            rgb_work = palette[ret];
+                            break;
+                        case 8:
+                        /* Format 8-bit RGB24 palette */
+                            rgb_work = palette[*buf_pointer];
+                            break;
+                        case 24:
+                        /* Format RGB24 */
+                            rgb_work.red = buf_pointer[RED];
+                            rgb_work.green = buf_pointer[GREEN];
+                            rgb_work.blue = buf_pointer[BLUE];
+                            break;
+                    }
+                    color_buf[col][RED] += (rgb_work.red + buf_red) / loop_x;
+                    color_buf[col][GREEN] += (rgb_work.green + buf_green) / loop_x;
+                    color_buf[col][BLUE] += (rgb_work.blue + buf_blue) / loop_x;
+                    if (write_flag == 1) {
+                        rgb.red = color_buf[col][RED] / loop_y;
+                        rgb.green = color_buf[col][GREEN] / loop_y;
+                        rgb.blue = color_buf[col][BLUE] / loop_y;
 #if LCD_DEPTH > 1
-            if(format == FORMAT_MONO) {
+                        if(format == FORMAT_MONO) {
 #endif
-                /* Mono -> Mono */
-                for (col = 0; col < width; col++) {
-                    ret = getpix(col, bmpbuf) ^ invert_pixel;
-                    if (ret) {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            |= 1 << ((height - row - 1) % 8);
-                    } else {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            &= ~ 1 << ((height - row - 1) % 8);
-                    }
-                }
+/* mono */
+                            ret = brightness(rgb);
+                            if (ret > threshold) {
+                                bitmap[dst_x * ((dst_y - row - 1) / 8) + col]
+                                    &= ~ 1 << ((dst_y - row - 1) % 8);
+                            } else {
+                                bitmap[dst_x * ((dst_y - row - 1) / 8) + col]
+                                    |= 1 << ((dst_y - row - 1) % 8);
+                            }
+#if LCD_DEPTH > 1
+                        } else {
 #if LCD_DEPTH == 2
 #if LCD_PIXELFORMAT == VERTICAL_PACKING
-            } else {
-                /* Mono -> 2gray (iriver H1xx) */
-                for (col = 0; col < width; col++) {
-                    ret = getpix(col, bmpbuf) ^ invert_pixel;
-                    
-                    if (ret)
-                        dest[((height - row - 1)/4) * width + col] |=
-                            0xC0 >> (2 * (~(height - row - 1) & 3));
-                }
-            }
+/* 2gray (iriver H1xx) */
+                            ret = brightness(rgb);
+                            dest[((dst_y - row - 1)/4) * dst_x + col] |=
+                                (~ret & 0xC0) >> (2 * (~(dst_y - row - 1) & 3));
 #else
-            } else {
-                /* Mono -> 2gray (ipod) */
-                for (col = 0; col < width; col++) {
-                    ret = getpix(col, bmpbuf) ^ invert_pixel;
-                    
-                    if (ret)
-                        dest[(height - row - 1) * dst_width + col/4] |=
-                            0xC0 >> (2 * (col & 3));
-                }
-            }
+/* 2gray (ipod) */
+                            ret = brightness(rgb);
+                            dest[(dst_y - row - 1) * dst_x + col/4] |=
+                                (~ret & 0xC0) >> (2 * (col & 3));
 #endif
 #elif LCD_DEPTH == 16
-            } else {
-                /* Mono -> RGB16 */
-                for (col = 0; col < width; col++) {
-                    ret = getpix(col, bmpbuf);
-                    unsigned short rgb16 = LCD_RGBPACK(palette[ret].red,
-                                                       palette[ret].green,
-                                                       palette[ret].blue);
-                    dest[width * (height - row - 1) + col] = rgb16;
-                }
-            }
-#endif
-            break;
-
-
-        case 8:
-            p = bmpbuf;
+/* RGB16 */
+                            dest[dst_x * (dst_y - row - 1) + col] =
+                                LCD_RGBPACK(rgb.red,rgb.green,rgb.blue);
+#endif
+                        }
+#endif
+                        color_buf[col][BLUE] = 0;
+                        color_buf[col][GREEN] = 0;
+                        color_buf[col][RED] = 0;
+                    }
+                    delta_x += src_x;
+                    loop_x = 1;
+                    buf_blue = 0;
+                    buf_green = 0;
+                    buf_red = 0;
+                    while ( delta_x >= trans_x ) {
+                        switch(depth) {
+                            case 1:
+                            /* Format Mono */
+                                x_position++;                      /* src_x + 1 */
+                                ret = getpix(x_position, bmpbuf);
+                                rgb_work = palette[ret];
+                                break;
+                            case 8:
+                            /* Format 8-bit RGB24 palette */
+                                buf_pointer++;                     /* src_x + 1 */
+                                rgb_work = palette[*buf_pointer];
+                                break;
+                            case 24:
+                            /* Format RGB24 */
+                                buf_pointer += 3;                  /* src_x + 1 */
+                                rgb_work.red = buf_pointer[RED];
+                                rgb_work.green = buf_pointer[GREEN];
+                                rgb_work.blue = buf_pointer[BLUE];
+                                break;
+                        }
+                        buf_red += rgb_work.red;
+                        buf_green += rgb_work.green;
+                        buf_blue += rgb_work.blue;
+                        loop_x++;
+                        delta_x -= trans_x;
+                    }
+                } else {
 #if LCD_DEPTH > 1
-            if(format == FORMAT_MONO) {
+                    if(format == FORMAT_MONO) {
 #endif
-                /* 8-bit RGB24 palette -> mono */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb = palette[*p];
-                    ret = brightness(rgb);
-                    if (ret > 96) {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            &= ~ 1 << ((height - row - 1) % 8);
+/* Mono -> mono */
+                        bitmap[dst_x * ((dst_y - row - 1) / 8) + col]
+                            &= ~ 1 << ((dst_y - row - 1) % 8);
+#if LCD_DEPTH > 1
                     } else {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            |= 1 << ((height - row - 1) % 8);
-                    }
-                    p++;
-                }
 #if LCD_DEPTH == 2
 #if LCD_PIXELFORMAT == VERTICAL_PACKING
-            } else {
-                /* 8-bit RGB24 palette -> 2gray (iriver H1xx) */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb = palette[*p];
-                    ret = brightness(rgb);
-
-                    dest[((height - row - 1)/4) * width + col] |=
-                        (~ret & 0xC0) >> (2 * (~(height - row - 1) & 3));
-                    p++;
-                }
-            }
+/* Mono -> 2gray (iriver H1xx) */
+                        dest[((dst_y - row - 1)/4) * dst_x + col] |=
+                            0x00 >> (2 * (~(dst_y - row - 1) & 3));
 #else
-            } else {
-                /* 8-bit RGB24 palette -> 2gray (ipod) */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb = palette[*p];
-                    ret = brightness(rgb);
-
-                    dest[(height - row - 1) * dst_width + col/4] |=
-                        (~ret & 0xC0) >> (2 * (col & 3));
-                    p++;
-                }
-            }
+/* Mono -> 2gray (ipod) */
+                        dest[(dst_y - row - 1) * dst_x + col/4] |=
+                            0x00 >> (2 * (col & 3));
 #endif
 #elif LCD_DEPTH == 16
-            } else {
-                /* 8-bit RGB24 palette -> RGB16 */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb = palette[*p];
-                    unsigned short rgb16 =
-                        LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
-                    dest[width * (height - row - 1) + col] = rgb16;
-                    p++;
+/* Mono -> RGB16 */
+                        dest[dst_x * (dst_y - row - 1) + col] = TRANSPARENT_COLOR;
+#endif
+                    }
+#endif
                 }
             }
-#endif
-            break;
+                if (write_flag == 1) {
+                    loop_y = 1;
+                }
 
-        case 24:
-            p = bmpbuf;
-#if LCD_DEPTH > 1
-            if(format == FORMAT_MONO) {
-#endif
-                /* RGB24 -> mono */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb;
-                    rgb.red = p[2];
-                    rgb.green = p[1];
-                    rgb.blue = p[0];
-                    ret = brightness(rgb);
-                    if (ret > 96) {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            &= ~ 1 << ((height - row - 1) % 8);
-                    } else {
-                        bitmap[width * ((height - row - 1) / 8) + col]
-                            |= 1 << ((height - row - 1) % 8);
+        if ((trans_y1 <= row) && (row <= trans_y2)) {
+            if (write_flag == 1) delta_y += src_y;
+            if (delta_y >= trans_y) {
+                count_y++;DEBUGF("count_y:%d\n",count_y);
+                if (count_y < src_y) {
+                    ret = read(fd, bmpbuf, SrcPaddedWidth);        /* src_y++ */
+                    if (ret != SrcPaddedWidth) {
+                        DEBUGF("error reading image, read returned: %d expected was: "
+                               "%d\n", ret, SrcPaddedWidth);
+                        close(fd);
+                        return -9;
                     }
-                    p += 3;
                 }
-#if LCD_DEPTH == 2
-#if LCD_PIXELFORMAT == VERTICAL_PACKING
-            } else {
-                /* RGB24 -> 2gray (iriver H1xx) */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb;
-                    rgb.red = p[2];
-                    rgb.green = p[1];
-                    rgb.blue = p[0];
-                    ret = brightness(rgb);
-
-                    dest[((height - row - 1)/4) * width + col] |=
-                        (~ret & 0xC0) >> (2 * (~(height - row - 1) & 3));
-                    p += 3;
+                delta_y -= trans_y;
+                if (delta_y >= trans_y) {
+                    row--;
+                    loop_y++;
+                    write_flag = 0;
+                } else {
+                    write_flag = 1;
                 }
-            }
-#else
-            } else {
-                /* RGB24 -> 2gray (ipod) */
-                for (col = 0; col < width; col++) {
-                    struct rgb_quad rgb;
-                    rgb.red = p[2];
-                    rgb.green = p[1];
-                    rgb.blue = p[0];
-                    ret = brightness(rgb);
-
-                    dest[(height - row - 1) * dst_width + col/4] |=
-                        (~ret & 0xC0) >> (2 * (col & 3));
-                    p += 3;
-                }
-            }
-#endif
-#elif LCD_DEPTH == 16
             } else {
-                /* RGB24 -> RGB16 */
-                for (col = 0; col < width; col++) {
-                    unsigned short rgb = LCD_RGBPACK(p[2],p[1],p[0]);
-                    dest[width * (height - row - 1) + col] = rgb;
-                    p += 3;
-                }
+                write_flag = 1;
             }
-#endif
-            break;
         }
     }
 
     close(fd);
 
     /* returning image size: */
-    bm->width = width;
-    bm->height = height;
+    bm->width = dst_x;
+    bm->height = dst_y;
 #if LCD_DEPTH > 1
     bm->format = format;
 #endif
diff --strip-trailing-cr --strip-trailing-cr -ruN rockbox_orig/apps/recorder/bmp.h rockbox/apps/recorder/bmp.h
--- rockbox_orig/apps/recorder/bmp.h	2006-01-28 21:12:42.000000000 +0900
+++ rockbox/apps/recorder/bmp.h	2006-07-27 06:49:09.860536000 +0900
@@ -32,5 +32,7 @@
 int read_bmp_file(char* filename,
                   struct bitmap *bm,
                   int maxsize,
-                  int format);
+                  int format,
+                  int xsize,  // if xsize=0 or ysize=0, load original size
+                  int ysize); //
 #endif
