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:
parent
565ab70da6
commit
39965620e8
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue