summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-10-11 01:26:09 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-10-11 01:26:09 +0000
commit76a6aaa2785cff2c4da277898bf01c712328258e (patch)
treeff6f06e583b3c5d56d12aebf9e47d3ff3eb1989e
parent38168222ae965438704968a106cb08e6ab069145 (diff)
Added dithering for 24 bit backdrops on 16 bit displays. FORMAT_DITHER should be specified to dither a bitmap when loading. Feel free to flame me if I got the RGB565SWAPPED thing wrong.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11180 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/recorder/backdrop.c3
-rw-r--r--apps/recorder/bmp.c70
-rw-r--r--firmware/export/lcd.h1
3 files changed, 56 insertions, 18 deletions
diff --git a/apps/recorder/backdrop.c b/apps/recorder/backdrop.c
index d230a6ec5a..374dba9f4b 100644
--- a/apps/recorder/backdrop.c
+++ b/apps/recorder/backdrop.c
@@ -36,7 +36,8 @@ bool load_backdrop(char* filename, fb_data* backdrop_buffer)
/* 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 | FORMAT_DITHER);
if ((ret > 0) && (bm.width == LCD_WIDTH) && (bm.height == LCD_HEIGHT))
{
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c
index 9d0968a03b..b490158b2c 100644
--- a/apps/recorder/bmp.c
+++ b/apps/recorder/bmp.c
@@ -94,6 +94,39 @@ inline int getpix(int px, unsigned char *bmpbuf) {
return (bmpbuf[a] & (1 << b)) != 0;
}
+#if LCD_DEPTH == 16
+/* Cheapo 24 -> 16 bit dither */
+#if LCD_PIXELFORMAT == RGB565SWAPPED
+#define RGBSWAPPED(rgb) swap16(rgb)
+#else
+#define RGBSWAPPED(rgb) rgb
+#endif
+static unsigned short dither_24_to_16(struct rgb_quad rgb, int row, int col)
+{
+ static const unsigned char dith[2][16] = {
+ { /* 5 bit */
+ 0,6,1,7,
+ 4,2,5,3,
+ 1,7,0,6,
+ 5,3,4,2
+ },
+ { /* 6 bit */
+ 0,3,0,3,
+ 2,1,2,1,
+ 0,3,0,3,
+ 2,1,2,1
+ }
+ };
+
+ const int elm = (row & 3) + ((col & 3) << 2);
+ short b = 31*((unsigned short)rgb.blue + dith[0][elm]) >> 8;
+ short g = 63*((unsigned short)rgb.green + dith[1][elm]) >> 8;
+ short r = 31*((unsigned short)rgb.red + dith[0][elm]) >> 8;
+
+ return RGBSWAPPED(b | (g << 5) | (r << 11));
+}
+#endif /* LCD_DEPTH == 16 */
+
/******************************************************************************
* read_bmp_file()
@@ -115,21 +148,25 @@ int read_bmp_file(char* filename,
int depth;
int totalsize;
char *bitmap = bm->data;
-
unsigned char bmpbuf[LCD_WIDTH*sizeof(struct rgb_quad)]; /* Buffer for one line */
-
-#if LCD_DEPTH == 1
- format = FORMAT_MONO;
-#else
- bool transparent;
-
+#if LCD_DEPTH != 1
+ bool transparent = false;
+#if LCD_DEPTH == 16
+ /* Should adapt dithering to all native depths */
+ bool dither = false;
+ if(format & FORMAT_DITHER) {
+ dither = true;
+ format &= ~FORMAT_DITHER;
+ }
+#endif
if(format & FORMAT_TRANSPARENT) {
transparent = true;
format &= ~FORMAT_TRANSPARENT;
}
+#else
+ format = FORMAT_MONO;
#endif
-
-
+
fd = open(filename, O_RDONLY);
/* Exit if file opening failed */
@@ -362,12 +399,11 @@ int read_bmp_file(char* filename,
#elif LCD_DEPTH == 16
} else {
/* 8-bit RGB24 palette -> RGB16 */
- for (col = 0; col < width; col++) {
+ for (col = 0; col < width; col++, p++) {
struct rgb_quad rgb = palette[*p];
- unsigned short rgb16 =
+ dest[width * (height - row - 1) + col] = dither ?
+ dither_24_to_16(rgb, row, col) :
LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
- dest[width * (height - row - 1) + col] = rgb16;
- p++;
}
}
#endif
@@ -429,10 +465,10 @@ int read_bmp_file(char* filename,
#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;
+ for (col = 0; col < width; col++, p += 3) {
+ dest[width * (height - row - 1) + col] = dither ?
+ dither_24_to_16(*(struct rgb_quad *)p, row, col) :
+ LCD_RGBPACK(p[2], p[1], p[0]);
}
}
#endif
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index b74a9d30c7..7fe76a5366 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -246,6 +246,7 @@ enum
};
#define FORMAT_TRANSPARENT 0x40000000
+#define FORMAT_DITHER 0x20000000
#define TRANSPARENT_COLOR LCD_RGBPACK(255,0,255)