1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Michael Sevakis 2006-10-15 17:51:00 +00:00
parent 7058752789
commit e0710b2af1
5 changed files with 110 additions and 93 deletions

View file

@ -56,8 +56,7 @@ struct rgb_pick
/* 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 @@ static const unsigned short prim_rgb[][3] =
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 @@ static void draw_screen(struct screen *display, char *title,
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 @@ static void draw_screen(struct screen *display, char *title,
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 @@ bool set_color(struct screen *display, char *title, int* color, int banned_color
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 @@ bool set_color(struct screen *display, char *title, int* color, int banned_color
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;

View file

@ -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

View file

@ -63,11 +63,11 @@ struct Fileheader {
} 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 @@ inline int getpix(int px, unsigned char *bmpbuf) {
}
#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 @@ static unsigned short dither_24_to_16(struct rgb_quad rgb, int row, int col)
},
};
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 @@ int read_bmp_file(char* filename,
/* 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 @@ int read_bmp_file(char* filename,
close(fd);
return (ret * 10 - 2);
}
if(ret != sizeof(struct Fileheader)) {
DEBUGF("error - can't read Fileheader structure.");
close(fd);
@ -250,7 +245,7 @@ int read_bmp_file(char* filename,
}
/* 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 @@ int read_bmp_file(char* filename,
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 @@ int read_bmp_file(char* filename,
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 @@ int read_bmp_file(char* filename,
/* 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 @@ int read_bmp_file(char* filename,
/* 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 @@ int read_bmp_file(char* filename,
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 @@ int read_bmp_file(char* filename,
/* 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

View file

@ -409,7 +409,7 @@ static bool set_fg_color(void)
{
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 @@ static bool set_bg_color(void)
{
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_rw(void)
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 );
}

View file

@ -161,37 +161,58 @@ static inline unsigned lcd_color_to_native(unsigned color)
#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