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:
parent
7058752789
commit
e0710b2af1
5 changed files with 110 additions and 93 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue