More color adjustments. Better translation to and from native colors with even distribution of levels. Macros for extracting native depth components and packing them.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11227 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index 32b392c..08c05d9 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -56,8 +56,7 @@
/* list of primary colors */
#define SB_PRIM 0
#define SB_FILL 1
-#define SB_MAX 2
-static const unsigned short prim_rgb[][3] =
+static const fb_data prim_rgb[][3] =
{
/* Foreground colors for sliders */
{
@@ -71,39 +70,32 @@
LCD_RGBPACK( 0, 85, 0),
LCD_RGBPACK( 0, 0, 85),
},
- /* maximum values for components */
- {
- LCD_MAX_RED,
- LCD_MAX_GREEN,
- LCD_MAX_BLUE
- }
+};
+
+/* maximum values for components */
+static const unsigned char rgb_max[3] =
+{
+ LCD_MAX_RED,
+ LCD_MAX_GREEN,
+ LCD_MAX_BLUE
};
/* Unpacks the color value into native rgb values and 24 bit rgb values */
static void unpack_rgb(struct rgb_pick *rgb)
{
- unsigned color = rgb->color;
-#if LCD_PIXELFORMAT == RGB565SWAPPED
- color = swap16(color);
-#endif
+ unsigned color = _LCD_UNSWAP_COLOR(rgb->color);
rgb->red = _RGB_UNPACK_RED(color);
rgb->green = _RGB_UNPACK_GREEN(color);
rgb->blue = _RGB_UNPACK_BLUE(color);
- rgb->r = (color & 0xf800) >> 11;
- rgb->g = (color & 0x07e0) >> 5;
- rgb->b = (color & 0x001f);
+ rgb->r = _RGB_UNPACK_RED_LCD(color);
+ rgb->g = _RGB_UNPACK_GREEN_LCD(color);
+ rgb->b = _RGB_UNPACK_BLUE_LCD(color);
}
/* Packs the native rgb colors into a color value */
-static void pack_rgb(struct rgb_pick *rgb)
+static inline void pack_rgb(struct rgb_pick *rgb)
{
- unsigned color = (rgb->r & 0x1f) << 11 |
- (rgb->g & 0x3f) << 5 |
- (rgb->b & 0x1f);
-#if LCD_PIXELFORMAT == RGB565SWAPPED
- color = swap16(color);
-#endif
- rgb->color = color;
+ rgb->color = LCD_RGBPACK_LCD(rgb->r, rgb->g, rgb->b);
}
/* Returns LCD_BLACK if the color is above a threshold brightness
@@ -265,7 +257,7 @@
text_top + display->char_height / 4,
slider_width,
display->char_height / 2,
- prim_rgb[SB_MAX][i],
+ rgb_max[i],
0,
rgb->rgb_val[i],
sb_flags);
@@ -343,22 +335,29 @@
color is a pointer to the colour (in native format) to modify
set banned_color to -1 to allow all
***********/
-bool set_color(struct screen *display, char *title, int* color, int banned_color)
+bool set_color(struct screen *display, char *title, unsigned *color,
+ unsigned banned_color)
{
- int exit = 0, button, slider = 0;
- int i;
+ int exit = 0, slider = 0;
struct rgb_pick rgb;
- (void)display;
rgb.color = *color;
while (!exit)
{
+ int button;
+
unpack_rgb(&rgb);
- FOR_NB_SCREENS(i)
+ if (display != NULL)
{
- draw_screen(&screens[i], title, &rgb, slider);
+ draw_screen(display, title, &rgb, slider);
+ }
+ else
+ {
+ int i;
+ FOR_NB_SCREENS(i)
+ draw_screen(&screens[i], title, &rgb, slider);
}
button = get_action(CONTEXT_SETTINGS_COLOURCHOOSER, TIMEOUT_BLOCK);
@@ -377,7 +376,7 @@
case ACTION_SETTINGS_INC:
case ACTION_SETTINGS_INCREPEAT:
- if (rgb.rgb_val[slider] < prim_rgb[SB_MAX][slider])
+ if (rgb.rgb_val[slider] < rgb_max[slider])
rgb.rgb_val[slider]++;
pack_rgb(&rgb);
break;
@@ -390,7 +389,8 @@
break;
case ACTION_STD_OK:
- if (banned_color != -1 && (unsigned)banned_color == rgb.color)
+ if (banned_color != (unsigned)-1 &&
+ banned_color == rgb.color)
{
gui_syncsplash(HZ*2, true, str(LANG_COLOR_UNACCEPTABLE));
break;
diff --git a/apps/gui/color_picker.h b/apps/gui/color_picker.h
index f520083..3bd2325 100644
--- a/apps/gui/color_picker.h
+++ b/apps/gui/color_picker.h
@@ -20,6 +20,7 @@
#ifdef HAVE_LCD_COLOR /* this file is a bit useless on non color lcds.. */
-bool set_color(struct screen *display,char *title, int* color, int banned_color);
+bool set_color(struct screen *display, char *title, unsigned *color,
+ unsigned banned_color);
#endif
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c
index 19376bf..3044e8e 100644
--- a/apps/recorder/bmp.c
+++ b/apps/recorder/bmp.c
@@ -63,11 +63,11 @@
} STRUCT_PACKED;
struct rgb_quad { /* Little endian */
- unsigned char blue;
- unsigned char green;
+ unsigned char blue;
+ unsigned char green;
unsigned char red;
unsigned char reserved;
-} STRUCT_PACKED;
+} STRUCT_PACKED;
/* big endian functions */
static short readshort(short *value) {
@@ -96,8 +96,8 @@
}
#if LCD_DEPTH == 16
-/* Cheapo 24 -> 16 bit dither */
-static unsigned short dither_24_to_16(struct rgb_quad rgb, int row, int col)
+/* 24 -> lcd depth dither */
+static fb_data dither_24_to_lcd(struct rgb_quad rgb, int row, int col)
{
static const unsigned char dith[][16] =
{
@@ -115,22 +115,17 @@
},
};
- const int elm = (row & 3) + ((col & 3) << 2);
- unsigned short color;
+ const unsigned elm = (row & 3) + ((col & 3) << 2);
+ unsigned b, g, r;
- unsigned b = ((unsigned)rgb.blue + dith[0][elm]) >> 3;
- if (b > 0x1f) b = 0x1f;
- unsigned g = ((unsigned)rgb.green + dith[1][elm]) >> 2;
- if (g > 0x3f) g = 0x3f;
- unsigned r = ((unsigned)rgb.red + dith[0][elm]) >> 3;
- if (r > 0x1f) r = 0x1f;
+ b = ((unsigned)rgb.blue + dith[0][elm]) >> (8-LCD_BLUE_BITS);
+ if (b > LCD_MAX_BLUE) b = LCD_MAX_BLUE;
+ g = ((unsigned)rgb.green + dith[1][elm]) >> (8-LCD_GREEN_BITS);
+ if (g > LCD_MAX_GREEN) g = LCD_MAX_GREEN;
+ r = ((unsigned)rgb.red + dith[0][elm]) >> (8-LCD_RED_BITS);
+ if (r > LCD_MAX_RED) r = LCD_MAX_RED;
- color = (unsigned short)(b | (g << 5) | (r << 11));
-
-#if LCD_PIXELFORMAT == RGB565SWAPPED
- color = swap16(color);
-#endif
- return color;
+ return LCD_RGBPACK_LCD(r, g, b);
}
#endif /* LCD_DEPTH == 16 */
@@ -179,7 +174,7 @@
/* Exit if file opening failed */
if (fd < 0) {
DEBUGF("error - can't open '%s' open returned: %d\n", filename, fd);
- return (fd * 10) - 1;
+ return (fd * 10) - 1;
}
/* read fileheader */
@@ -188,7 +183,7 @@
close(fd);
return (ret * 10 - 2);
}
-
+
if(ret != sizeof(struct Fileheader)) {
DEBUGF("error - can't read Fileheader structure.");
close(fd);
@@ -250,7 +245,7 @@
}
/* 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));
@@ -278,7 +273,7 @@
if(brightness(palette[0]) < brightness(palette[1]))
invert_pixel = 1;
}
-
+
/* Search to the beginning of the image data */
lseek(fd, (off_t)readlong(&fh.OffBits), SEEK_SET);
@@ -286,15 +281,15 @@
if(format == FORMAT_NATIVE)
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;
-
+
/* read one row */
ret = read(fd, bmpbuf, PaddedWidth);
if (ret != PaddedWidth) {
@@ -326,7 +321,7 @@
/* 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));
@@ -337,7 +332,7 @@
/* 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));
@@ -409,8 +404,8 @@
for (col = 0; col < width; col++, p++) {
struct rgb_quad rgb = palette[*p];
dest[width * (height - row - 1) + col] = dither ?
- dither_24_to_16(rgb, row, col) :
- LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
+ dither_24_to_lcd(rgb, row, col) :
+ (fb_data)LCD_RGBPACK(rgb.red, rgb.green, rgb.blue);
}
}
#endif
@@ -474,8 +469,8 @@
/* RGB24 -> RGB16 */
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]);
+ dither_24_to_lcd(*(struct rgb_quad *)p, row, col) :
+ (fb_data)LCD_RGBPACK(p[2], p[1], p[0]);
}
}
#endif
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 35bdccb..eabe153 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -409,7 +409,7 @@
{
bool res;
- res = set_color(&screens[SCREEN_MAIN],str(LANG_FOREGROUND_COLOR),
+ res = set_color(NULL,str(LANG_FOREGROUND_COLOR),
&global_settings.fg_color,global_settings.bg_color);
screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
@@ -421,7 +421,7 @@
{
bool res;
- res = set_color(&screens[SCREEN_MAIN],str(LANG_BACKGROUND_COLOR),
+ res = set_color(NULL,str(LANG_BACKGROUND_COLOR),
&global_settings.bg_color,global_settings.fg_color);
screens[SCREEN_MAIN].set_background(global_settings.bg_color);
@@ -1699,7 +1699,7 @@
static bool unplug_autoresume(void)
{
- return set_bool( str(LANG_UNPLUG_DISABLE_AUTORESUME),
+ return set_bool( str(LANG_UNPLUG_DISABLE_AUTORESUME),
&global_settings.unplug_autoresume );
}
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 4949f51..22ae5a3 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -161,37 +161,58 @@
#endif
#ifdef HAVE_LCD_COLOR
-#if LCD_DEPTH == 16
+#if LCD_PIXELFORMAT == RGB565 || LCD_PIXELFORMAT == RGB565SWAPPED
#define LCD_MAX_RED 31
#define LCD_MAX_GREEN 63
#define LCD_MAX_BLUE 31
-#define _RGB_UNPACK_RED(x) ((((x) >> 8) & 0xf8) | ((x) >> 13))
-#define _RGB_UNPACK_GREEN(x) ((((x) >> 3) & 0xfc) | (((x) >> 9) & 0x03))
-#define _RGB_UNPACK_BLUE(x) ((((x) << 3) & 0xf8) | (((x) >> 2) & 0x07))
-#define _RGBPACK(r, g, b) ( ((((r) * (31*257) + (127*257)) >> 16) << 11) \
- |((((g) * (63*257) + (127*257)) >> 16) << 5) \
- | (((b) * (31*257) + (127*257)) >> 16))
-/* Note: ((x * 257) >> 16) almost equals (x / 255), but it avoids the division,
- * so it's faster when the macro is used for variable r, g, b in the source. */
+#define LCD_RED_BITS 5
+#define LCD_GREEN_BITS 6
+#define LCD_BLUE_BITS 5
+
+/* pack/unpack native RGB values */
+#define _RGBPACK_LCD(r, g, b) ( ((r) << 11) | ((g) << 5) | (b) )
+#define _RGB_UNPACK_RED_LCD(x) ( (((x) >> 11) ) )
+#define _RGB_UNPACK_GREEN_LCD(x) ( (((x) >> 5) & 0x3f) )
+#define _RGB_UNPACK_BLUE_LCD(x) ( (((x) ) & 0x1f) )
+
+/* pack/unpack 24-bit RGB values */
+#define _RGBPACK(r, g, b) _RGBPACK_LCD((r) >> 3, (g) >> 2, (b) >> 3)
+#define _RGB_UNPACK_RED(x) ( (((x) >> 8) & 0xf8) | (((x) >> 11) & 0x07) )
+#define _RGB_UNPACK_GREEN(x) ( (((x) >> 3) & 0xfc) | (((x) >> 5) & 0x03) )
+#define _RGB_UNPACK_BLUE(x) ( (((x) << 3) & 0xf8) | (((x) ) & 0x07) )
+
#if (LCD_PIXELFORMAT == RGB565SWAPPED)
-#define LCD_RGBPACK(r, g, b) ( ((_RGBPACK((r), (g), (b)) & 0xff00) >> 8) \
- |((_RGBPACK((r), (g), (b)) & 0x00ff) << 8))
-#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(swap16(x))
-#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(swap16(x))
-#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x))
+/* RGB3553 */
+#define _LCD_UNSWAP_COLOR(x) swap16(x)
+#define LCD_RGBPACK_LCD(r, g, b) ( (((r) << 3) ) | \
+ (((g) >> 3) ) | \
+ (((g) & 0x07) << 13) | \
+ (((b) << 8) ) )
+#define LCD_RGBPACK(r, g, b) ( (((r) >> 3) << 3) | \
+ (((g) >> 5) ) | \
+ (((g) & 0x1c) << 11) | \
+ (((b) >> 3) << 8) )
+/* swap color once - not currenly used in static inits */
+#define _SWAPUNPACK(x, _unp_) \
+ ({ typeof (x) _x_ = swap16(x); _unp_(_x_); })
+#define RGB_UNPACK_RED(x) _SWAPUNPACK((x), _RGB_UNPACK_RED)
+#define RGB_UNPACK_GREEN(x) _SWAPUNPACK((x), _RGB_UNPACK_GREEN)
+#define RGB_UNPACK_BLUE(x) _SWAPUNPACK((x), _RGB_UNPACK_BLUE)
+#define RGB_UNPACK_RED_LCD(x) _SWAPUNPACK((x), _RGB_UNPACK_RED_LCD)
+#define RGB_UNPACK_GREEN_LCD(x) _SWAPUNPACK((x), _RGB_UNPACK_GREEN_LCD)
+#define RGB_UNPACK_BLUE_LCD(x) _SWAPUNPACK((x), _RGB_UNPACK_BLUE_LCD)
#else
-#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b))
-#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x)
-#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x)
-#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
+/* RGB565 */
+#define _LCD_UNSWAP_COLOR(x) (x)
+#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b))
+#define LCD_RGBPACK_LCD(r, g, b) _RGBPACK_LCD((r), (g), (b))
+#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x)
+#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x)
+#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
+#define RGB_UNPACK_RED_LCD(x) _RGB_UNPACK_RED(x)
+#define RGB_UNPACK_GREEN_LCD(x) _RGB_UNPACK_GREEN(x)
+#define RGB_UNPACK_BLUE_LCD(x) _RGB_UNPACK_BLUE(x)
#endif
-#elif LCD_DEPTH == 18
-#define LCD_MAX_RED 63
-#define LCD_MAX_GREEN 63
-#define LCD_MAX_BLUE 63
-#define LCD_RGBPACK(r, g, b) ( ((((r) * (63*257) + (127*257)) >> 16) << 12) \
- |((((g) * (63*257) + (127*257)) >> 16) << 6) \
- | (((b) * (63*257) + (127*257)) >> 16))
#else
/* other colour depths */
#endif