diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2006-10-11 01:26:09 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2006-10-11 01:26:09 +0000 |
commit | 76a6aaa2785cff2c4da277898bf01c712328258e (patch) | |
tree | ff6f06e583b3c5d56d12aebf9e47d3ff3eb1989e | |
parent | 38168222ae965438704968a106cb08e6ab069145 (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.c | 3 | ||||
-rw-r--r-- | apps/recorder/bmp.c | 70 | ||||
-rw-r--r-- | firmware/export/lcd.h | 1 |
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) |