Index: apps/plugin.h
===================================================================
RCS file: /cvsroot/rockbox/apps/plugin.h,v
retrieving revision 1.198
diff -u -r1.198 plugin.h
--- apps/plugin.h	31 Oct 2006 11:17:00 -0000	1.198
+++ apps/plugin.h	2 Nov 2006 09:35:52 -0000
@@ -539,7 +539,11 @@
 #endif
 #ifdef HAVE_LCD_BITMAP
     int (*read_bmp_file)(char* filename, struct bitmap *bm, int maxsize,
-                         int format);
+                         int format,
+                         int dst_maxwidth,
+                         int dst_width_resize,   // BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE
+                         int dst_maxheight,
+                         int dst_height_resize); // BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE
     void (*screen_dump_set_hook)(void (*hook)(int fh));
 #endif
     int (*show_logo)(void);
Index: apps/gui/gwps-common.c
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/gwps-common.c,v
retrieving revision 1.64
diff -u -r1.64 gwps-common.c
--- apps/gui/gwps-common.c	30 Oct 2006 00:23:30 -0000	1.64
+++ apps/gui/gwps-common.c	2 Nov 2006 09:35:52 -0000
@@ -208,7 +208,9 @@
                 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, BMP_RESIZE_NONE,
+                                    0, BMP_RESIZE_NONE);
                         
                 if (ret > 0)
                 {
@@ -322,7 +324,9 @@
                         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, BMP_RESIZE_NONE,
+                                            0, BMP_RESIZE_NONE);
                         
                         if (ret > 0)
                         {
Index: apps/gui/gwps.h
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/gwps.h,v
retrieving revision 1.38
diff -u -r1.38 gwps.h
--- apps/gui/gwps.h	30 Oct 2006 00:23:32 -0000	1.38
+++ apps/gui/gwps.h	2 Nov 2006 09:35:52 -0000
@@ -345,7 +345,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
Index: apps/plugins/rockpaint.c
===================================================================
RCS file: /cvsroot/rockbox/apps/plugins/rockpaint.c,v
retrieving revision 1.10
diff -u -r1.10 rockpaint.c
--- apps/plugins/rockpaint.c	26 Oct 2006 13:38:00 -0000	1.10
+++ apps/plugins/rockpaint.c	2 Nov 2006 09:35:52 -0000
@@ -2905,7 +2905,9 @@
     bool ret;
     bm.data = (char*)save_buffer;
     ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ),
-                              FORMAT_NATIVE );
+                              FORMAT_NATIVE,
+                              COLS, BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE,
+                              ROWS, BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE);
     if( bm.width < COLS )
     {
         int l;
Index: apps/plugins/lib/bmp.h
===================================================================
RCS file: /cvsroot/rockbox/apps/plugins/lib/bmp.h,v
retrieving revision 1.1
diff -u -r1.1 bmp.h
--- apps/plugins/lib/bmp.h	19 Jul 2006 19:44:44 -0000	1.1
+++ apps/plugins/lib/bmp.h	2 Nov 2006 09:35:52 -0000
@@ -21,6 +21,7 @@
 
 #include "lcd.h"
 #include "plugin.h"
+#include "recorder/bmp.h"
 
 /**
  * Save bitmap to file
Index: apps/recorder/backdrop.c
===================================================================
RCS file: /cvsroot/rockbox/apps/recorder/backdrop.c,v
retrieving revision 1.3
diff -u -r1.3 backdrop.c
--- apps/recorder/backdrop.c	11 Oct 2006 01:26:08 -0000	1.3
+++ apps/recorder/backdrop.c	2 Nov 2006 09:35:52 -0000
@@ -34,10 +34,12 @@
     struct bitmap bm;
     int ret;
 
-    /* load the image */
+    /* load the image (try to auto resize to LCD size) */
     bm.data=(char*)backdrop_buffer;
     ret = read_bmp_file(filename, &bm, sizeof(main_backdrop),
-                        FORMAT_NATIVE | FORMAT_DITHER);
+                        FORMAT_NATIVE | FORMAT_DITHER,
+                        LCD_WIDTH, BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE,
+                        LCD_HEIGHT, BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE);
 
     if ((ret > 0) && (bm.width == LCD_WIDTH) && (bm.height == LCD_HEIGHT))
     {
Index: apps/recorder/bmp.c
===================================================================
RCS file: /cvsroot/rockbox/apps/recorder/bmp.c,v
retrieving revision 1.34
diff -u -r1.34 bmp.c
--- apps/recorder/bmp.c	15 Oct 2006 17:51:00 -0000	1.34
+++ apps/recorder/bmp.c	2 Nov 2006 09:44:52 -0000
@@ -130,37 +130,224 @@
 #endif /* LCD_DEPTH == 16 */
 
 
+/* maximum bitmap width which can be read: */
+#define MAX_WIDTH 1024
+/* Buffer for one line */
+static unsigned char bmpbuf[MAX_WIDTH*sizeof(struct rgb_quad)];
+
+
+/******************************************************************************
+ * set_bmp_pixel()
+ *
+ * puts a pixel from BMP source (bmpbuf) to destination (bitmap).
+ *
+ *****************************************************************************/
+static void set_bmp_pixel(int depth,
+                          int format,
+                          int invert_pixel,
+                          bool dither,
+                          struct rgb_quad *palette,
+                          unsigned char *bmpbuf,
+                          int src_col,
+                          unsigned char *bitmap,
+                          int dst_row,
+                          int dst_col,
+                          int dst_w,
+                          int dst_h)
+{
+#if LCD_DEPTH > 1
+    fb_data *dest = (fb_data *)bitmap;
+#endif
+    unsigned char *p;
+    int ret;
+#if LCD_DEPTH != 16
+    /* make the compiler happy (dither currently only used for DEPTH == 16) */
+    dither = dither;
+#endif
+
+    switch (depth) {
+        case 1:
+#if LCD_DEPTH > 1
+            if (format == FORMAT_MONO) {
+#endif
+                /* Mono -> Mono */
+                ret = getpix(src_col, bmpbuf) ^ invert_pixel;
+                if (ret) {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        |= 1 << ((dst_h - dst_row - 1) % 8);
+                } else {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        &= ~ 1 << ((dst_h - dst_row - 1) % 8);
+                }
+#if LCD_DEPTH > 1
+            } else {
+#endif
+#if LCD_DEPTH == 2
+#if LCD_PIXELFORMAT == VERTICAL_PACKING
+                /* Mono -> 2gray (iriver H1xx) */
+                ret = getpix(src_col, bmpbuf) ^ invert_pixel;
+                if (ret) {
+                    dest[((dst_h - dst_row - 1) / 4) * dst_w + dst_col] |=
+                        0xC0 >> (2 * (~(dst_h - dst_row - 1) & 3));
+                }
+#else
+                /* Mono -> 2gray (ipod) */
+                ret = getpix(src_col, bmpbuf) ^ invert_pixel;
+                if (ret) {
+                    dest[(dst_h - dst_row - 1) * dst_w + dst_col/4] |=
+                        0xC0 >> (2 * (dst_col & 3));
+                }
+#endif
+#elif LCD_DEPTH == 16
+                /* Mono -> RGB16 */
+                ret = getpix(src_col, bmpbuf);
+                unsigned short rgb16 = LCD_RGBPACK(palette[ret].red,
+                                                   palette[ret].green,
+                                                   palette[ret].blue);
+                dest[dst_w * (dst_h - dst_row - 1) + dst_col] = rgb16;
+#endif
+#if LCD_DEPTH > 1
+            }
+#endif
+        break; /* case 1 */
+
+        case 8:
+            p = bmpbuf + src_col;
+#if LCD_DEPTH > 1
+            if (format == FORMAT_MONO) {
+#endif
+                /* 8-bit RGB24 palette -> mono */
+                struct rgb_quad rgb = palette[*p];
+                ret = brightness(rgb);
+                if (ret > 96) {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        &= ~ 1 << ((dst_h - dst_row - 1) % 8);
+                } else {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        |= 1 << ((dst_h - dst_row - 1) % 8);
+                }
+#if LCD_DEPTH > 1
+            } else {
+#endif
+#if LCD_DEPTH == 2
+#if LCD_PIXELFORMAT == VERTICAL_PACKING
+                /* 8-bit RGB24 palette -> 2gray (iriver H1xx) */
+                struct rgb_quad rgb = palette[*p];
+                ret = brightness(rgb);
+                dest[((dst_h - dst_row - 1)/4) * dst_w + dst_col] |=
+                    (~ret & 0xC0) >> (2 * (~(dst_h - dst_row - 1) & 3));
+#else
+                /* 8-bit RGB24 palette -> 2gray (ipod) */
+                struct rgb_quad rgb = palette[*p];
+                ret = brightness(rgb);
+
+                dest[(dst_h - dst_row - 1) * dst_w + dst_col/4] |=
+                    (~ret & 0xC0) >> (2 * (dst_col & 3));
+#endif
+#elif LCD_DEPTH == 16
+                /* 8-bit RGB24 palette -> RGB16 */
+                struct rgb_quad rgb = palette[*p];
+                dest[dst_w * (dst_h - dst_row - 1) + dst_col] = dither ?
+                    dither_24_to_lcd(rgb, dst_row, dst_col) :
+                    LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
+#endif
+#if LCD_DEPTH > 1
+            }
+#endif
+        break; /* case 8 */
+
+        case 24:
+            p = bmpbuf + 3 * src_col;
+#if LCD_DEPTH > 1
+            if (format == FORMAT_MONO) {
+#endif
+            /* RGB24 -> mono */
+                struct rgb_quad rgb;
+                rgb.red = p[2];
+                rgb.green = p[1];
+                rgb.blue = p[0];
+                ret = brightness(rgb);
+                if (ret > 96) {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        &= ~ 1 << ((dst_h - dst_row - 1) % 8);
+                } else {
+                    bitmap[dst_w * ((dst_h - dst_row - 1) / 8) + dst_col]
+                        |= 1 << ((dst_h - dst_row - 1) % 8);
+                }
+#if LCD_DEPTH > 1
+            } else {
+#endif
+#if LCD_DEPTH == 2
+#if LCD_PIXELFORMAT == VERTICAL_PACKING
+                /* RGB24 -> 2gray (iriver H1xx) */
+                struct rgb_quad rgb;
+                rgb.red = p[2];
+                rgb.green = p[1];
+                rgb.blue = p[0];
+                ret = brightness(rgb);
+
+                dest[((dst_h - dst_row - 1)/4) * dst_w + dst_col] |=
+                    (~ret & 0xC0) >> (2 * (~(dst_h - dst_row - 1) & 3));
+#else
+                /* RGB24 -> 2gray (ipod) */
+                struct rgb_quad rgb;
+                rgb.red = p[2];
+                rgb.green = p[1];
+                rgb.blue = p[0];
+                ret = brightness(rgb);
+
+                dest[(dst_h - dst_row - 1) * dst_w + dst_col/4] |=
+                    (~ret & 0xC0) >> (2 * (dst_col & 3));
+#endif
+#elif LCD_DEPTH == 16
+                /* RGB24 -> RGB16 */
+                dest[dst_w * (dst_h - dst_row - 1) + dst_col] = dither ?
+                    dither_24_to_lcd(*(struct rgb_quad *)p, dst_row, dst_col) :
+                    LCD_RGBPACK(p[2], p[1], p[0]);
+#endif
+#if LCD_DEPTH > 1
+            }
+#endif
+        break; /* case 24 */
+    } /* END switch(depth) */
+}
+
+
 /******************************************************************************
  * read_bmp_file()
  *
- * Reads a monochrome BMP file and puts the data in rockbox format in *bitmap.
+ * Reads a BMP file and puts the data in rockbox format in *bitmap.
  *
  *****************************************************************************/
 int read_bmp_file(char* filename,
                   struct bitmap *bm,
                   int maxsize,
-                  int format)
+                  int format,
+                  int dst_maxwidth,
+                  int dst_width_resize,
+                  int dst_maxheight,
+                  int dst_height_resize)
 {
     struct Fileheader fh;
-    int width, height, PaddedWidth, PaddedHeight, dst_width;
-    int fd, row, col, ret;
+    int src_w, src_h, SrcPaddedWidth;
+    int dst_w, dst_h, DstPaddedHeight, DstPaddedWidth;
+    int fact;
+    int fd, row, ret;
     struct rgb_quad palette[256];
     int invert_pixel = 0;
     int numcolors;
     int depth;
     int totalsize;
     char *bitmap = bm->data;
-    unsigned char bmpbuf[LCD_WIDTH*sizeof(struct rgb_quad)]; /* Buffer for one line */
+    bool dither = false;
 #if LCD_DEPTH != 1
     bool transparent = false;
-#if LCD_DEPTH == 16
-    /* Should adapt dithering to all native depths */
-    bool dither = false;
+    /* currently dithering only works for LCD_DEPTH == 16
+     * --> should adapt dithering to all native depths */
     if(format & FORMAT_DITHER) {
         dither = true;
         format &= ~FORMAT_DITHER;
     }
-#endif
     if(format & FORMAT_TRANSPARENT) {
         transparent = true;
         format &= ~FORMAT_TRANSPARENT;
@@ -173,8 +360,8 @@
 
     /* Exit if file opening failed */
     if (fd < 0) {
-        DEBUGF("error - can't open '%s' open returned: %d\n", filename, fd);
-        return (fd * 10) - 1;
+        DEBUGF("read_bmp_file: error - can't open '%s' open returned: %d\n", filename, fd);
+        return (fd * 10) - 1; 
     }
 
     /* read fileheader */
@@ -185,35 +372,84 @@
     }
 
     if(ret != sizeof(struct Fileheader)) {
-        DEBUGF("error - can't read Fileheader structure.");
+        DEBUGF("read_bmp_file: error - can't read Fileheader structure.");
         close(fd);
         return -3;
     }
 
+    /* read the source dimensions */
+    src_w = readlong(&fh.Width);
+    src_h = readlong(&fh.Height);
+
+    /* Exit if too wide */
+    if (src_w > MAX_WIDTH) {
+        DEBUGF("read_bmp_file: error - Bitmap is too wide (%d pixels, max is %d)\n",
+               src_w, MAX_WIDTH);
+        close(fd);
+        return -5;
+    }
+
+    depth = readshort(&fh.BitCount);
+
+    /* Calculate resize factors and image size */
+    {
+        int fact_w = -1;
+        int fact_h = -1;
+        if (dst_maxwidth > 0)
+            fact_w = (src_w * 1000) / dst_maxwidth;
+        if (fact_w > 1000 && !(dst_width_resize & BMP_RESIZE_DECREASE)) {
+            /* no decrease allowed */
+            fact_w = -1;
+        }
+        if (fact_w < 1000 && !(dst_width_resize & BMP_RESIZE_INCREASE)) {
+            /* no increase allowed */
+            fact_w = -1;
+        }
+
+        if (dst_maxheight > 0)
+            fact_h = (src_h * 1000) / dst_maxheight;
+        if (fact_h > 1000 && !(dst_height_resize & BMP_RESIZE_DECREASE)) {
+            /* no decrease allowed */
+            fact_h = -1;
+        }
+        if (fact_h < 1000 && !(dst_height_resize & BMP_RESIZE_INCREASE)) {
+            /* no increase allowed */
+            fact_h = -1;
+        }
+
+        fact = MAX(fact_h, fact_w);
+        if (fact > 0) {
+            dst_w = (src_w * 1000) / fact;
+            dst_h = (src_h * 1000) / fact;
+        } else {
+            /* don't resize */
+            fact = 1000;
+            dst_w = src_w;
+            dst_h = src_h;
+        }
+    }
+
+    DEBUGF("read_bmp_file: src_w/h=%d/%d, dst_w/h=%d/%d (fact=%d)\n",
+           src_w, src_h, dst_w, dst_h, fact);
+
     /* 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_w > LCD_WIDTH) {
+        DEBUGF("read_bmp_file: error - Bitmap is too wide (%d pixels, max is %d)\n",
+               dst_w, 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_h > LCD_HEIGHT) {
+        DEBUGF("read_bmp_file: error - Bitmap is too high (%d pixels, max is %d)\n",
+               dst_h, LCD_HEIGHT);
         close(fd);
         return -6;
     }
 
-    /* Calculate image size */
-    height = readlong(&fh.Height);
-    width = readlong(&fh.Width);
-    depth = readshort(&fh.BitCount);
-
     /* 4-byte boundary aligned */
-    PaddedWidth = ((width * depth + 31) / 8) & ~3;
-
+    SrcPaddedWidth = ((src_w * depth + 31) / 8) & ~3;
 #if LCD_DEPTH > 1
         if(format == FORMAT_ANY) {
             if(depth == 1)
@@ -223,32 +459,32 @@
         }
 #endif
 
-    /* PaddedHeight is for rockbox format. */
+    /* DstPaddedHeight/Width is for rockbox format. */
     if(format == FORMAT_MONO) {
-        PaddedHeight = (height + 7) / 8;
-        dst_width = width;
-        totalsize = PaddedHeight * dst_width;
+        DstPaddedHeight = (dst_h + 7) / 8;
+        DstPaddedWidth = dst_w;
+        totalsize = DstPaddedHeight * DstPaddedWidth;
     } else {
 #if LCD_DEPTH == 2
 #if LCD_PIXELFORMAT == VERTICAL_PACKING
-        PaddedHeight = (height + 3) / 4;
-        dst_width = width;
+        DstPaddedHeight = (dst_h + 3) / 4;
+        DstPaddedWidth = dst_w;
 #else
-        PaddedHeight = height;
-        dst_width = (width + 3) / 4;
+        DstPaddedHeight = dst_h;
+        DstPaddedWidth = (dst_w + 3) / 4;
 #endif
 #else
-        PaddedHeight = height;
-        dst_width = width;
+        DstPaddedHeight = dst_h;
+        DstPaddedWidth = dst_w;
 #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));
+        DEBUGF("read_bmp_file: error - Bitmap is too large to fit the supplied buffer: "
+               "%d bytes.%d:%d\n", (DstPaddedHeight * DstPaddedWidth),
+               totalsize, maxsize);
         close(fd);
         return -7;
     }
@@ -262,7 +498,7 @@
         if(read(fd, palette, numcolors * sizeof(struct rgb_quad))
            != numcolors * (int)sizeof(struct rgb_quad))
         {
-            DEBUGF("error - Can't read bitmap's color palette\n");
+            DEBUGF("read_bmp_file: error - Can't read bitmap's color palette\n");
             close(fd);
             return -8;
         }
@@ -282,211 +518,72 @@
         memset(bitmap, 0, totalsize);
 #endif
 
-#if LCD_DEPTH > 1
-    fb_data *dest = (fb_data *)bitmap;
-#endif
-
     /* loop to read rows and put them to buffer */
-    for (row = 0; row < height; row++) {
-        unsigned char *p;
-
+    for (row = 0; row < src_h; row++) {
         /* read one row */
-        ret = read(fd, bmpbuf, PaddedWidth);
-        if (ret != PaddedWidth) {
-            DEBUGF("error reading image, read returned: %d expected was: "
-                   "%d\n", ret, PaddedWidth);
+        ret = read(fd, bmpbuf, SrcPaddedWidth);
+        if (ret != SrcPaddedWidth) {
+            DEBUGF("read_bmp_file: error reading image, read returned: %d expected was: "
+                   "%d\n", ret, SrcPaddedWidth);
             close(fd);
             return -9;
         }
 
-        switch(depth) {
-        case 1:
-#if LCD_DEPTH > 1
-            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);
-                    }
-                }
-#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));
-                }
-            }
-#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));
-                }
-            }
-#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;
-#if LCD_DEPTH > 1
-            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);
-                    } 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++;
-                }
-            }
-#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++;
-                }
-            }
-#endif
-#elif LCD_DEPTH == 16
-            } else {
-                /* 8-bit RGB24 palette -> RGB16 */
-                for (col = 0; col < width; col++, p++) {
-                    struct rgb_quad rgb = palette[*p];
-                    dest[width * (height - row - 1) + col] = dither ?
-                        dither_24_to_lcd(rgb, row, col) :
-                        (fb_data)LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
+        if (fact > 1000) {
+            /* decrease
+             * -> put only every "fact" row to the dest buffer */
+            if ((row % (fact / 1000)) == 0) {
+                int dst_row = (row * 1000) / fact;
+                int dst_col;
+
+                for (dst_col = 0; dst_col < dst_w; dst_col++) {
+                    int src_col = (dst_col * fact) / 1000;
+
+                    set_bmp_pixel(depth, format, invert_pixel, dither,
+                                  palette, bmpbuf, src_col,
+                                  bitmap, dst_row, dst_col, dst_w, dst_h);
                 }
             }
-#endif
-            break;
-
-        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);
+        } else
+        if (fact < 1000) {
+            /* increase
+             * -> duplicate src-pixel for not existing dst-rows/cols */
+            int dst_row, dst_col;
+            int src_col;
+
+            for (dst_row = row * 1000 / fact;
+                 dst_row < (row + 1) * 1000 / fact; dst_row++) {
+                for (src_col = 0; src_col < src_w; src_col++) {
+                    for (dst_col = src_col * 1000 / fact;
+                         dst_col < (src_col + 1) * 1000 / fact; dst_col++) {
+                        set_bmp_pixel(depth, format, invert_pixel, dither,
+                                      palette, bmpbuf, src_col,
+                                      bitmap, dst_row, dst_col, dst_w, dst_h);
                     }
-                    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;
                 }
             }
-#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;
-                }
+        } else {
+            /* same size -> just transport the pixels */
+            int dst_col;
+            for (dst_col = 0; dst_col < dst_w; dst_col++) {
+                set_bmp_pixel(depth, format, invert_pixel, dither,
+                              palette, bmpbuf, dst_col,
+                              bitmap, row, dst_col, dst_w, dst_h);
             }
-#endif
-#elif LCD_DEPTH == 16
-            } else {
-                /* RGB24 -> RGB16 */
-                for (col = 0; col < width; col++, p += 3) {
-                    dest[width * (height - row - 1) + col] = dither ?
-                        dither_24_to_lcd(*(struct rgb_quad *)p, row, col) :
-                        (fb_data)LCD_RGBPACK(p[2], p[1], p[0]);
-                }
-            }
-#endif
-            break;
         }
-    }
+    } /* END for (row = 0; row < src_h; row++) */
 
     close(fd);
 
     /* returning image size: */
-    bm->width = width;
-    bm->height = height;
+    bm->width = dst_w;
+    bm->height = dst_h;
 #if LCD_DEPTH > 1
     bm->format = format;
 #endif
 
-DEBUGF("totalsize: %d\n", totalsize);
+    DEBUGF("read_bmp_file: totalsize=%d, width=%d, height=%d\n",
+           totalsize, dst_w, dst_h);
+
     return totalsize; /* return the used buffer size. */
 }
Index: apps/recorder/bmp.h
===================================================================
RCS file: /cvsroot/rockbox/apps/recorder/bmp.h,v
retrieving revision 1.3
diff -u -r1.3 bmp.h
--- apps/recorder/bmp.h	28 Jan 2006 12:12:42 -0000	1.3
+++ apps/recorder/bmp.h	2 Nov 2006 09:35:52 -0000
@@ -22,6 +22,10 @@
 #include "config.h"
 #include "lcd.h"
 
+#define BMP_RESIZE_NONE     0
+#define BMP_RESIZE_INCREASE 8
+#define BMP_RESIZE_DECREASE 16
+
 /*********************************************************************
  * read_bmp_file()
  *
@@ -32,5 +36,9 @@
 int read_bmp_file(char* filename,
                   struct bitmap *bm,
                   int maxsize,
-                  int format);
+                  int format,
+                  int dst_maxwidth,
+                  int dst_width_resize,   // BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE
+                  int dst_maxheight,
+                  int dst_height_resize); // BMP_RESIZE_INCREASE | BMP_RESIZE_DECREASE
 #endif
