int video_display_bitmap( ulong bmp_image, int x, int y )
{
vidinfo_t *info = NULL;
#if defined CONFIG_AML_VOUT
//rrrr
info = vout_get_current_vinfo();
#endif
ushort *cmap_base = NULL;
unsigned long byte_width;
ushort i, j;
uchar *fb;
bmp_image_t *bmp = (bmp_image_t *)bmp_image;
uchar *bmap;
ushort padded_line;
unsigned long width, height;
#ifdef CONFIG_OSD_SCALE_ENABLE
//ttttt
unsigned long pheight = fb_gdev.fb_height;
unsigned long pwidth = fb_gdev.fb_width;
#else
unsigned long pheight = info->vl_row;
unsigned long pwidth = info->vl_col;
#endif
unsigned colors, bpix, bmp_bpix;
int lcd_line_length = (pwidth * NBITS(info->vl_bpix)) / 8;
char *layer_str = NULL;
int osd_index = -1;
printf( "info->vl_bpix = %d\n", info->vl_bpix );
printf( "pwidth = %ld\n", pwidth );
printf( "lcd_line_length = %d\n", lcd_line_length );
printf( "bmp1 = %p\n", bmp );
printf( "bmp2 = %p\n", bmp );
layer_str = getenv("display_layer");
printf( "layer_str = %s\n", layer_str );
if (strcmp(layer_str, "osd0") == 0)
osd_index = 0;
else if (strcmp(layer_str, "osd1") == 0)
osd_index = 1;
printf( "layer_str = %s\n", layer_str );
printf( "bmp->header.signature[0] = %p\n", &bmp->header.signature[0] );
printf( "bmp->header.signature[1] = %p\n", &bmp->header.signature[1] );
printf( "bmp->header.signature[0] = %c\n", bmp->header.signature[0] );
printf( "bmp->header.signature[0] = %C\n", bmp->header.signature[0] );
if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
osd_loge("no valid bmp image at 0x%lx\n", bmp_image);
return 1;
}
width = le32_to_cpu(bmp->header.width);
height = le32_to_cpu(bmp->header.height);
bmp_bpix = le16_to_cpu(bmp->header.bit_count);
colors = 1 << bmp_bpix;
bpix = NBITS(info->vl_bpix);
if ((x == -1) && (y == -1)) {
if ((width > pwidth) || (height > pheight)) {
x = 0;
y = 0;
} else {
x = (pwidth - width) / 2;
y = (pheight - height) / 2;
}
}
if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 24) &&
(bpix != 32)) {
osd_loge("%d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, bmp_bpix);
return 1;
}
/* We support displaying 8bpp BMPs on 16bpp LCDs */
//if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {
osd_loge("%d bit/pixel mode2, but BMP has %d bit/pixel\n",
bpix,
le16_to_cpu(bmp->header.bit_count));
// return 1;
//}
osd_logd("Display-bmp: %d x %d with %d colors\n",
(int)width, (int)height, (int)colors);
/*
* BMP format for Monochrome assumes that the state of a
* pixel is described on a per Bit basis, not per Byte.
* So, in case of Monochrome BMP we should align widths
* on a byte boundary and convert them from Bit to Byte
* units.
* Probably, PXA250 and MPC823 process 1bpp BMP images in
* their own ways, so make the converting to be MCC200
* specific.
*/
padded_line = (width & 0x3) ? ((width & ~0x3) + 4) : (width);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
if (x == BMP_ALIGN_CENTER)
x = max(0, (pwidth - width) / 2);
else if (x < 0)
x = max(0, pwidth - width + x + 1);
if (y == BMP_ALIGN_CENTER)
y = max(0, (info->vl_row - height) / 2);
else if (y < 0)
y = max(0, info->vl_row - height + y + 1);
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
if ((x + width) > pwidth)
width = pwidth - x;
if ((y + height) > pheight)
height = pheight - y;
osd_enable_hw(osd_index, 1);
bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
fb = (uchar *)(info->vd_base +
(y + height - 1) * lcd_line_length + x * fb_gdev.gdfBytesPP);
osd_logd("fb=0x%p; bmap=0x%p, width=%ld, height= %ld, lcd_line_length=%d, padded_line=%d\n",
fb, bmap, width, height, lcd_line_length, padded_line);
printf("fb=0x%p; bmap=0x%p, width=%ld, height= %ld, lcd_line_length=%d, padded_line=%d\n",
fb, bmap, width, height, lcd_line_length, padded_line);
printf( "bmp_bpix = %d\n", bmp_bpix );
switch (bmp_bpix) {
case 8:
if (bpix != 16)
byte_width = width;
else
byte_width = width * 2;
for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) {
if (bpix != 16)
*(fb++) = *(bmap++);
else {
*(uint16_t *)fb = cmap_base[*(bmap++)];
fb += sizeof(uint16_t) / sizeof(*fb);
}
}
bmap += (width - padded_line);
fb -= (byte_width + lcd_line_length);
}
break;
case 16:
for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) {
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
}
bmap += (padded_line - width) * 2;
fb -= (width * 2 + lcd_line_length);
}
break;
case 24:
for( i = 0; i < height; ++i) {
//printf( "height = %ld\n", height );
for( j=0; j < width; j++) {
if( i>900 && i<1080 ){
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
}else if( i>700 && i<=900 ){
*(fb++) = 0xff;
bmap++;
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
}else if( i>500 && i<=700 ){
*(fb++) = *(bmap++);
*(fb++) = 0xff;
bmap++;
*(fb++) = *(bmap++);
}else if( i>250 && i<=500 ){
*(fb++) = 0xff;
bmap++;
*(fb++) = *(bmap++);
*(fb++) = 0xff;
bmap++;
}else{
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
*(fb++) = 0xff;
bmap++;
}
}
bmap += (padded_line - width);
//行扫描 略过填充像素点
fb -= (width * 3 + lcd_line_length);
//显存指向下一行的开头位置 width * 3 = lcd_line_length
//先回退到上一行的开始位置 再加一行的大小 即定位到下一行的开始位置
}
break;
case 32:
for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) {
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
}
bmap += (padded_line - width);
fb -= (width * 4 + lcd_line_length);
}
break;
default:
osd_loge("error: gdev.bpp %d, but bmp.bpp %d\n", fb_gdev.gdfBytesPP, bmp_bpix);
return (-1);
}
#if 0
flush_cache((unsigned long)info->vd_base,
info->vl_col * info->vl_row * info->vl_bpix / 8);
#else
flush_cache((unsigned long)info->vd_base,
pheight * pwidth * info->vl_bpix / 8);
//刷显存数据
#endif
return (0);
}