Add: Allow logo in 16bit or 32bit color BMP

Change-Id: Ife719d3d567df4c98d40ddfe67c6952fa2929fec
Signed-off-by: Ye Gaoyang <gaoyang.ye@rock-chips.com>
This commit is contained in:
Ye Gaoyang 2018-09-26 09:17:18 +08:00 committed by Jianhong Chen
parent 565ab70da6
commit 39965620e8
2 changed files with 119 additions and 24 deletions

81
drivers/video/drm/bmp_helper.c Executable file → Normal file
View File

@ -4,6 +4,8 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <command.h>
#include <log.h>
#include <config.h>
#include <common.h>
#include <malloc.h>
@ -141,9 +143,30 @@ static void decode_rle8_bitmap(void *psrc, void *pdst, uint16_t *cmap,
}
}
static void dump_bmp_dib_head(void *bmp_addr)
{
struct bmp_image *bmp = bmp_addr;
debug("########## BMP DIB_HEAD ##########\n"
"Width : %u\n"
"Height : %u\n"
"Bpp : %u\n"
"Compression method : %u\n"
"Image size : %u\n"
"Colors in palette : %u\n"
"##################################\n",
bmp->header.width,
bmp->header.height,
bmp->header.bit_count,
bmp->header.compression,
bmp->header.image_size,
bmp->header.colors_used);
}
int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
{
int stride, padded_width, bpp, i, width, height;
int i, j;
int stride, padded_width, bpp, width, height;
struct bmp_image *bmp = bmp_addr;
uint8_t *src = bmp_addr;
uint8_t *dst = pdst;
@ -153,9 +176,10 @@ int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
if (!bmp || !(bmp->header.signature[0] == 'B' &&
bmp->header.signature[1] == 'M')) {
printf("cat not find bmp file\n");
printf("Error: Invalid bmp file.\n");
return -1;
}
dump_bmp_dib_head(bmp);
width = get_unaligned_le32(&bmp->header.width);
height = get_unaligned_le32(&bmp->header.height);
bpp = get_unaligned_le16(&bmp->header.bit_count);
@ -172,8 +196,8 @@ int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
switch (bpp) {
case 8:
if (dst_bpp != 16) {
printf("can't support covert bmap to bit[%d]\n",
dst_bpp);
printf("Error: Target pixel's bpp is not 16bit.\n");
return -1;
}
cmap = malloc(sizeof(cmap) * 256);
@ -193,7 +217,6 @@ int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
decode_rle8_bitmap(src, dst, cmap, width, height,
bpp, 0, 0, flip);
} else {
int j;
stride = width * 2;
if (flip)
@ -211,9 +234,35 @@ int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
}
free(cmap);
break;
case 16:
if (get_unaligned_le32(&bmp->header.compression)) {
printf("Error: Failed to decompression bmp file.\n");
return -1;
}
stride = ALIGN(width * bpp / 8, 4);
if (flip)
src += stride * (height - 1);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
ushort color = (src[1] << 8) | src[0];
color = (((color & 0x7c00) << 1) |
((color & 0x03e0) << 1) |
(color & 0x001f));
*(uint16_t *)dst = color;
src += 2;
dst += 2;
}
src += (padded_width - width);
if (flip)
src -= stride * 2;
}
break;
case 24:
if (get_unaligned_le32(&bmp->header.compression)) {
printf("can't not support compression for 24bit bmap");
printf("Error: Failed to decompression bmp file.\n");
return -1;
}
stride = ALIGN(width * 3, 4);
@ -228,10 +277,26 @@ int bmpdecoder(void *bmp_addr, void *pdst, int dst_bpp)
src -= stride * 2;
}
break;
case 16:
case 32:
if (get_unaligned_le32(&bmp->header.compression)) {
printf("Error: Failed to decompression bmp file.\n");
return -1;
}
stride = ALIGN(width * 4, 4);
if (flip)
src += stride * (height - 1);
for (i = 0; i < height; i++) {
memcpy(dst, src, 4 * width);
dst += stride;
src += stride;
if (flip)
src -= stride * 2;
}
break;
default:
printf("unsupport bit=%d now\n", bpp);
printf("Error: Can't decode this bmp file with bit=%d\n", bpp);
return -1;
}

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <asm/unaligned.h>
#include <config.h>
#include <common.h>
@ -28,6 +29,7 @@
#include "rockchip_connector.h"
#include "rockchip_phy.h"
#include "rockchip_panel.h"
#include "rockchip_vop.h"
#include <dm.h>
#include <dm/of_access.h>
#include <dm/ofnode.h>
@ -163,9 +165,40 @@ static unsigned long get_display_size(void)
return memory_end - memory_start;
}
static bool can_direct_logo(int bpp)
/**
* vop_support_ymirror - ensure whethere vop support the feature of ymirror.
* @logo: the pointer to the logo information.
*
*/
static bool vop_support_ymirror(struct logo_info *logo)
{
return bpp == 24 || bpp == 32;
bool ret;
struct display_state *state;
struct vop_data *vop_data;
ret = false;
state = container_of(logo, struct display_state, logo);
if (state->crtc_state.crtc->data) {
vop_data = (struct vop_data *)state->crtc_state.crtc->data;
printf("VOP hardware version v%d.%d, ",
VOP_MAJOR(vop_data->version),
VOP_MINOR(vop_data->version));
/*
* if the version of VOP is higher than v3.0,
* which means that the VOP support ymirror,
* so it isn't need to mirror image by ourself.
*/
if (vop_data->version >= VOP_VERSION(3, 0)) {
printf("Support mirror mode.\n");
ret = true;
} else {
printf("Not support mirror mode.\n");
}
} else {
printf("Error: CRTC drivers is not ready.\n");
}
return ret;
}
@ -323,7 +356,7 @@ static int connector_panel_init(struct display_state *state)
dsp_lut_node = dev_read_subnode(dev, "dsp-lut");
if (!ofnode_valid(dsp_lut_node)) {
debug("%s can not find dsp-lut node\n", __func__);
printf("%s can not find dsp-lut node\n", __func__);
return 0;
}
@ -931,7 +964,6 @@ static int display_logo(struct display_state *state)
printf("can't support bmp bits[%d]\n", logo->bpp);
return -EINVAL;
}
crtc_state->rb_swap = logo->bpp != 32;
hdisplay = conn_state->mode.hdisplay;
vdisplay = conn_state->mode.vdisplay;
crtc_state->src_w = logo->width;
@ -1117,20 +1149,17 @@ static int load_bmp_logo(struct logo_info *logo, const char *bmp_name)
logo->bpp = get_unaligned_le16(&header->bit_count);
logo->width = get_unaligned_le32(&header->width);
logo->height = get_unaligned_le32(&header->height);
size = get_unaligned_le32(&header->file_size);
if (!can_direct_logo(logo->bpp)) {
if (size > MEMORY_POOL_SIZE) {
printf("failed to use boot buf as temp bmp buffer\n");
ret = -ENOMEM;
goto free_header;
}
pdst = get_display_buffer(size);
} else {
pdst = get_display_buffer(size);
dst = pdst;
size = get_unaligned_le32(&header->file_size);
if (size > MEMORY_POOL_SIZE) {
printf("failed to use boot buf as temp bmp buffer\n");
ret = -ENOMEM;
goto free_header;
}
pdst = get_display_buffer(size);
dst = pdst;
len = rockchip_read_resource_file(pdst, bmp_name, 0, size);
if (len != size) {
printf("failed to load bmp %s\n", bmp_name);
@ -1138,7 +1167,7 @@ static int load_bmp_logo(struct logo_info *logo, const char *bmp_name)
goto free_header;
}
if (!can_direct_logo(logo->bpp)) {
if (!vop_support_ymirror(logo)) {
int dst_size;
/*
* TODO: force use 16bpp if bpp less than 16;
@ -1151,6 +1180,7 @@ static int load_bmp_logo(struct logo_info *logo, const char *bmp_name)
ret = -ENOMEM;
goto free_header;
}
memset(dst, 0, dst_size);
if (bmpdecoder(pdst, dst, logo->bpp)) {
printf("failed to decode bmp %s\n", bmp_name);
ret = -EINVAL;