Files

348 lines
8.6 KiB
C

/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* drivers/display/minui/bmp.c
*
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
*
*/
#include "bmp.h"
#include "minui_log.h"
//#define BMP1_DISPLAY 1
static int BMP_to_ARGB8888(const gfxbitmap *getmap, unsigned char *out_buffer)
{
unsigned char *pget;
unsigned char *pput;
int i;
int width;
int height;
if (!getmap || !getmap->pstart || !out_buffer) {
ui_loge("BMP_to_ARGB8888 parameter err!\n");
return -1;
}
pget = getmap->pstart;
pput = out_buffer;
width = getmap->wwidth;
height = getmap->wheight;
pget += getmap->wwidth * (getmap->wheight - 1) * 4;
for (i = 0; i < height; i++) {
memcpy(pput, pget, width * 4);
pput += width * 4;
pget -= width * 4;
}
return 0;
}
static int BMP24_to_ARGB8888(const gfxbitmap *getmap, unsigned char *out_buffer)
{
unsigned char *pget;
unsigned char *pput;
int i,j;
int width;
int height;
int rowsize = 0;
unsigned char *ptemp;
if (!getmap || !getmap->pstart || !out_buffer) {
ui_loge("BMP24_to_ARGB8888 parameter err!\n");
return -1;
}
pget = getmap->pstart;
pput = out_buffer;
width = getmap->wwidth;
height = getmap->wheight;
rowsize = 4 * (int)((getmap->wwidth * 24 + 31) / 32);
pget += rowsize * (getmap->wheight - 1);
for (i = 0; i < height; i++) {
ptemp = pget;
for (j = 0; j < width; j++) {
*(pput++) = *ptemp++;
*(pput++) = *ptemp++;
*(pput++) = *ptemp++;
*(pput++) = 0xFF;
}
pget -= rowsize;
}
return 0;
}
static int BMP16_to_ARGB8888(const gfxbitmap *getmap, unsigned char *out_buffer)
{
unsigned char *pget;
unsigned char *pput;
int i,j;
int width;
int height;
int rowsize = 0;
unsigned char *ptemp;
if (!getmap || !getmap->pstart || !out_buffer) {
ui_loge("BMP24_to_ARGB8888 parameter err!\n");
return -1;
}
pget = getmap->pstart;
pput = out_buffer;
width = getmap->wwidth;
height = getmap->wheight;
rowsize = 4 * (int)((getmap->wwidth * 16 + 31) / 32);
pget += rowsize * (getmap->wheight - 1);
for (i = 0; i < height; i++) {
ptemp = pget;
for (j = 0; j < width; j++) {
*(pput++) = (*ptemp & 0x1F) << 3;
*(pput++) = (((*(ptemp + 1) & 0x7) << 3) | ((*ptemp & 0xE0) >> 5)) << 2;
*(pput++) = ((*(ptemp + 1) & 0xF8) >> 3) << 3;
*(pput++) = 0xFF;
ptemp += 2;
}
pget -= rowsize;
}
return 0;
}
#ifdef BMP1_DISPLAY
static int BMP1_to_ARGB8888(const gfxbitmap *getmap, unsigned char *out_buffer)
{
unsigned char *pget;
unsigned char *pput;
unsigned char *pbmpbuf = NULL;
int i,j;
int rowsize = 0;
int width;
int height;
unsigned int usForeColor;
unsigned int usBackColor;
if (!getmap || !getmap->pstart || !out_buffer) {
ui_loge("BMP1_to_ARGB8888 parameter err!\n");
return -1;
}
pget = getmap->pstart;
pput = out_buffer;
width = getmap->wwidth;
height = getmap->wheight;
usForeColor = getmap->fgcolor;
usBackColor = getmap->bgcolor;
rowsize = 4 * (int)((getmap->wwidth + 31) / 32);
pbmpbuf = getmap->pstart + rowsize * (getmap->wheight - 1);
pget += getmap->wwidth * getmap->wheight;
for (i = 0; i < height; i ++) {
for (j = 0; j < width; j++) {
if (((0x01 << (7 - (j & 0x07))) & pbmpbuf[j >> 3]) != 0) {
/* it is foreground */
*(pput++) = usForeColor & 0xFF;
*(pput++) = (usForeColor >> 8) & 0xFF;
*(pput++) = (usForeColor >> 16) & 0xFF;
*(pput++) = 0xFF;
} else {
/* it is background */
*(pput++) = usBackColor & 0xFF;
*(pput++) = (usBackColor >> 8) & 0xFF;
*(pput++) = (usBackColor >> 16) & 0xFF;
*(pput++) = 0xFF;
}
}
pbmpbuf -= rowsize;
}
return 0;
}
#endif
static int BMP1_to_ARGB8(const gfxbitmap *getmap, unsigned char *out_buffer)
{
unsigned char *pget;
unsigned char *pput;
unsigned char *pbmpbuf = NULL;
int i,j;
int rowsize = 0;
int width;
int height;
if (!getmap || !getmap->pstart || !out_buffer) {
ui_loge("BMP1_to_ARGB8888 parameter err!\n");
return -1;
}
pget = getmap->pstart;
pput = out_buffer;
width = getmap->wwidth;
height = getmap->wheight;
rowsize = 4 * (int)((getmap->wwidth + 31) / 32);
pbmpbuf = getmap->pstart + rowsize * (getmap->wheight - 1);
ui_logd("width=%d,height=%d, rowsize=%d\n", width, height, rowsize);
pget += getmap->wwidth * getmap->wheight;
for (i = 0; i < height; i ++) {
for (j = 0; j < width; j++) {
if (((0x01 << (7 - (j & 0x07))) & pbmpbuf[j >> 3]) != 0) {
/* it is foreground */
*(pput++) = 0xff;
} else {
/* it is background */
*(pput++) = 0x0;
}
}
pbmpbuf -= rowsize;
}
return 0;
}
int load_bmp(bmpinfo *pbmpinfo, unsigned char *out_buffer)
{
int iret = 0;
gfxbitmap tgfxbmp;
if (!pbmpinfo) {
ui_loge("pbmpinfo is NULL.\n");
return -1;
}
ui_logd("[disp_bmp]: pbmpinfo 0x%p, Width %d, Height %d!\n",
pbmpinfo, pbmpinfo->width, pbmpinfo->height);
memset(&tgfxbmp, 0, sizeof(tgfxbmp));
tgfxbmp.bgcolor = pbmpinfo->bgcolor;
tgfxbmp.fgcolor = pbmpinfo->fgcolor;
tgfxbmp.pstart = pbmpinfo->bmpbuf;
tgfxbmp.wheight = pbmpinfo->height;
tgfxbmp.wwidth = pbmpinfo->width;
ui_logd("pbmpinfo->bmpformat=%d\n",pbmpinfo->bmpformat);
switch (pbmpinfo->bmpformat) {
case 1:
#ifdef BMP1_DISPLAY
iret = BMP1_to_ARGB8888(&tgfxbmp, out_buffer);
#else
iret = BMP1_to_ARGB8(&tgfxbmp, out_buffer);
#endif
break;
case 16:
iret = BMP16_to_ARGB8888(&tgfxbmp, out_buffer);
break;
case 24:
iret = BMP24_to_ARGB8888(&tgfxbmp, out_buffer);
break;
case 32:
iret = BMP_to_ARGB8888(&tgfxbmp, out_buffer);
break;
}
return iret;
}
long load_pic_from_partition(const char *pic_name)
{
char str[128] = {0};
int ret = 0;
if (pic_name == NULL) {
ui_loge("wrong pic_name.\n");
return -1;
}
sprintf(str, "imgread pic logo %s $loadaddr", pic_name);
ret = run_command(str, 0);
if (ret != 0) {
ui_loge("run_command fail.\n");
return -2;
}
sprintf(str, "%s_offset", pic_name);
return getenv_ulong(str, 16, 0);
}
int read_bmp(const char *filename, BITMAPINFOHEADER *pstbmpinfoheader, unsigned char **buffer)
{
unsigned short bftype = 0x4d42;
BITMAPFILEHEADER stbmpfileheader = {0};
BITMAPINFOHEADER stbmpinfoheader = {0};
unsigned char *data_buffer = NULL;
long bmp_addr;
bmp_addr = load_pic_from_partition(filename);
if (bmp_addr <= 0) {
ui_loge("load_pic_from_partition fail.\n");
return -1;
}
bftype = le16_to_cpu(*(unsigned short *)(bmp_addr));
if (bftype != 0x4d42) {
ui_loge("bftype=0x%x failed\n", bftype);
return -1;
}
stbmpfileheader = *(BITMAPFILEHEADER *)(bmp_addr + sizeof(bftype));
stbmpinfoheader = *(BITMAPINFOHEADER *)(bmp_addr +
sizeof(bftype) + sizeof(stbmpfileheader));
stbmpinfoheader.biwidth = le32_to_cpu(stbmpinfoheader.biwidth);
stbmpinfoheader.biheight = le32_to_cpu(stbmpinfoheader.biheight);
stbmpinfoheader.bibitcount = le16_to_cpu(stbmpinfoheader.bibitcount);
stbmpfileheader.bfsize = le32_to_cpu(stbmpfileheader.bfsize);
stbmpfileheader.bfoffbits = le32_to_cpu(stbmpfileheader.bfoffbits);
data_buffer = (unsigned char *)(bmp_addr + stbmpfileheader.bfoffbits);
memcpy(pstbmpinfoheader, &stbmpinfoheader, sizeof(stbmpinfoheader));
*buffer = data_buffer;
ui_logd("bfsize=%d,bfoffbits=%d, data_buffer = 0x%p\n",
stbmpfileheader.bfsize,
stbmpfileheader.bfoffbits,
data_buffer);
ui_logd("BmpHeader:biwidth=%d, biheight=%d,bibitcount=%d\n",
stbmpinfoheader.biwidth,
stbmpinfoheader.biheight,
stbmpinfoheader.bibitcount);
return 0;
}
int read_bmp_from_addr(long bmp_addr, BITMAPINFOHEADER *pstbmpinfoheader, unsigned char **buffer)
{
unsigned short bftype = 0x4d42;
BITMAPFILEHEADER stbmpfileheader = {0};
BITMAPINFOHEADER stbmpinfoheader = {0};
unsigned char *data_buffer = NULL;
if (bmp_addr <= 0) {
ui_loge("load_pic_from_partition fail.\n");
return -1;
}
bftype = le16_to_cpu(*(unsigned short *)(bmp_addr));
if (bftype != 0x4d42) {
ui_loge("bftype=0x%x failed\n", bftype);
return -1;
}
stbmpfileheader = *(BITMAPFILEHEADER *)(bmp_addr + sizeof(bftype));
stbmpinfoheader = *(BITMAPINFOHEADER *)(bmp_addr +
sizeof(bftype) + sizeof(stbmpfileheader));
stbmpinfoheader.biwidth = le32_to_cpu(stbmpinfoheader.biwidth);
stbmpinfoheader.biheight = le32_to_cpu(stbmpinfoheader.biheight);
stbmpinfoheader.bibitcount = le16_to_cpu(stbmpinfoheader.bibitcount);
stbmpfileheader.bfsize = le32_to_cpu(stbmpfileheader.bfsize);
stbmpfileheader.bfoffbits = le32_to_cpu(stbmpfileheader.bfoffbits);
data_buffer = (unsigned char *)(bmp_addr + stbmpfileheader.bfoffbits);
memcpy(pstbmpinfoheader, &stbmpinfoheader, sizeof(stbmpinfoheader));
*buffer = data_buffer;
ui_logd("bfsize=%d,bfoffbits=%d, data_buffer = 0x%p\n",
stbmpfileheader.bfsize,
stbmpfileheader.bfoffbits,
data_buffer);
ui_logd("BmpHeader:biwidth=%d, biheight=%d,bibitcount=%d\n",
stbmpinfoheader.biwidth,
stbmpinfoheader.biheight,
stbmpinfoheader.bibitcount);
return 0;
}