@ -642,6 +642,138 @@ static void splash_align_axis(int *axis, unsigned long panel_size,
}
# endif
# ifdef CONFIG_LCD_BMP_RLE8
# define BMP_RLE8_ESCAPE 0
# define BMP_RLE8_EOL 0
# define BMP_RLE8_EOBMP 1
# define BMP_RLE8_DELTA 2
static void draw_unencoded_bitmap ( ushort * * fbp , uchar * bmap , ushort * cmap ,
int cnt )
{
while ( cnt > 0 ) {
* ( * fbp ) + + = cmap [ * bmap + + ] ;
cnt - - ;
}
}
static void draw_encoded_bitmap ( ushort * * fbp , ushort c , int cnt )
{
ushort * fb = * fbp ;
int cnt_8copy = cnt > > 3 ;
cnt - = cnt_8copy < < 3 ;
while ( cnt_8copy > 0 ) {
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
* fb + + = c ;
cnt_8copy - - ;
}
while ( cnt > 0 ) {
* fb + + = c ;
cnt - - ;
}
( * fbp ) = fb ;
}
/*
* Do not call this function directly , must be called from
* lcd_display_bitmap .
*/
static void lcd_display_rle8_bitmap ( bmp_image_t * bmp , ushort * cmap , uchar * fb ,
int x_off , int y_off )
{
uchar * bmap ;
ulong width , height ;
ulong cnt , runlen ;
int x , y ;
int decode = 1 ;
width = le32_to_cpu ( bmp - > header . width ) ;
height = le32_to_cpu ( bmp - > header . height ) ;
bmap = ( uchar * ) bmp + le32_to_cpu ( bmp - > header . data_offset ) ;
x = 0 ;
y = height - 1 ;
while ( decode ) {
if ( bmap [ 0 ] = = BMP_RLE8_ESCAPE ) {
switch ( bmap [ 1 ] ) {
case BMP_RLE8_EOL :
/* end of line */
bmap + = 2 ;
x = 0 ;
y - - ;
/* 16bpix, 2-byte per pixel, width should *2 */
fb - = ( width * 2 + lcd_line_length ) ;
break ;
case BMP_RLE8_EOBMP :
/* end of bitmap */
decode = 0 ;
break ;
case BMP_RLE8_DELTA :
/* delta run */
x + = bmap [ 2 ] ;
y - = bmap [ 3 ] ;
/* 16bpix, 2-byte per pixel, x should *2 */
fb = ( uchar * ) ( lcd_base + ( y + y_off - 1 )
* lcd_line_length + ( x + x_off ) * 2 ) ;
bmap + = 4 ;
break ;
default :
/* unencoded run */
runlen = bmap [ 1 ] ;
bmap + = 2 ;
if ( y < height ) {
if ( x < width ) {
if ( x + runlen > width )
cnt = width - x ;
else
cnt = runlen ;
draw_unencoded_bitmap (
( ushort * * ) & fb ,
bmap , cmap , cnt ) ;
}
x + = runlen ;
}
bmap + = runlen ;
if ( runlen & 1 )
bmap + + ;
}
} else {
/* encoded run */
if ( y < height ) {
runlen = bmap [ 0 ] ;
if ( x < width ) {
/* aggregate the same code */
while ( bmap [ 0 ] = = 0xff & &
bmap [ 2 ] ! = BMP_RLE8_ESCAPE & &
bmap [ 1 ] = = bmap [ 3 ] ) {
runlen + = bmap [ 2 ] ;
bmap + = 2 ;
}
if ( x + runlen > width )
cnt = width - x ;
else
cnt = runlen ;
draw_encoded_bitmap ( ( ushort * * ) & fb ,
cmap [ bmap [ 1 ] ] , cnt ) ;
}
x + = runlen ;
}
bmap + = 2 ;
}
}
}
# endif
# if defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
# define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++)
# else
@ -781,6 +913,18 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
switch ( bmp_bpix ) {
case 1 : /* pass through */
case 8 :
# ifdef CONFIG_LCD_BMP_RLE8
if ( le32_to_cpu ( bmp - > header . compression ) = = BMP_BI_RLE8 ) {
if ( bpix ! = 16 ) {
/* TODO implement render code for bpix != 16 */
printf ( " Error: only support 16 bpix " ) ;
return 1 ;
}
lcd_display_rle8_bitmap ( bmp , cmap_base , fb , x , y ) ;
break ;
}
# endif
if ( bpix ! = 16 )
byte_width = width ;
else