multimedia/device/mpp/sample/common/loadbmp.c

628 lines
15 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "loadbmp.h"
OSD_COMP_INFO s_OSDCompInfo[OSD_COLOR_FMT_BUTT] = {{0, 4, 4, 4}, /*RGB444*/
{4, 4, 4, 4}, /*ARGB4444*/
{0, 5, 5, 5}, /*RGB555*/
{0, 5, 6, 5}, /*RGB565*/
{1, 5, 5, 5}, /*ARGB1555*/
{0, 0, 0, 0}, /*RESERVED*/
{0, 8, 8, 8}, /*RGB888*/
{8, 8, 8, 8} /*ARGB8888*/
};
inline HI_U16 OSD_MAKECOLOR_U16(HI_U8 r, HI_U8 g, HI_U8 b, OSD_COMP_INFO compinfo)
{
HI_U8 r1, g1, b1;
HI_U16 pixel = 0;
HI_U32 tmp = 15;
r1 = g1 = b1 = 0;
r1 = r >> (8 - compinfo.rlen);
g1 = g >> (8 - compinfo.glen);
b1 = b >> (8 - compinfo.blen);
while(compinfo.alen)
{
pixel |= (1 << tmp);
tmp --;
compinfo.alen--;
}
pixel |= (r1 | (g1 << compinfo.blen) | (b1 << (compinfo.blen + compinfo.glen)));
return pixel;
}
HI_S32 GetBmpInfo(const char *filename, OSD_BITMAPFILEHEADER *pBmpFileHeader
,OSD_BITMAPINFO *pBmpInfo)
{
FILE *pFile;
HI_U16 bfType;
if(NULL == filename)
{
printf("OSD_LoadBMP: filename=NULL\n");
return -1;
}
if( (pFile = fopen((char *)filename, "rb")) == NULL)
{
printf("Open file faild:%s!\n", filename);
return -1;
}
(void)fread(&bfType, 1, sizeof(bfType), pFile);
if(bfType != 0x4d42)
{
printf("not bitmap file\n");
fclose(pFile);
return -1;
}
(void)fread(pBmpFileHeader, 1, sizeof(OSD_BITMAPFILEHEADER), pFile);
(void)fread(pBmpInfo, 1, sizeof(OSD_BITMAPINFO), pFile);
fclose(pFile);
return 0;
}
int LoadBMP(const char *filename, OSD_LOGO_T *pVideoLogo)
{
FILE *pFile;
HI_U16 i,j;
HI_U32 w,h;
HI_U16 Bpp;
HI_U16 dstBpp;
OSD_BITMAPFILEHEADER bmpFileHeader;
OSD_BITMAPINFO bmpInfo;
HI_U8 *pOrigBMPBuf;
HI_U8 *pRGBBuf;
HI_U32 stride;
if(NULL == filename)
{
printf("OSD_LoadBMP: filename=NULL\n");
return -1;
}
if(GetBmpInfo(filename,&bmpFileHeader,&bmpInfo)<0)
{
return -1;
}
Bpp = bmpInfo.bmiHeader.biBitCount/8;
if(Bpp < 2)
{
/* only support 1555.8888 888 bitmap */
printf("bitmap format not supported!\n");
return -1;
}
if(bmpInfo.bmiHeader.biCompression != 0)
{
printf("not support compressed bitmap file!\n");
return -1;
}
if(bmpInfo.bmiHeader.biHeight < 0)
{
printf("bmpInfo.bmiHeader.biHeight < 0\n");
return -1;
}
if( (pFile = fopen((char *)filename, "rb")) == NULL)
{
printf("Open file faild:%s!\n", filename);
return -1;
}
pVideoLogo->width = (HI_U16)bmpInfo.bmiHeader.biWidth;
pVideoLogo->height = (HI_U16)((bmpInfo.bmiHeader.biHeight>0)?bmpInfo.bmiHeader.biHeight:(-bmpInfo.bmiHeader.biHeight));
w = pVideoLogo->width;
h = pVideoLogo->height;
stride = w*Bpp;
#if 1
if(stride%4)
{
stride = (stride & 0xfffc) + 4;
}
#endif
/* RGB8888 or RGB1555 */
pOrigBMPBuf = (HI_U8 *)malloc(h*stride);
if(NULL == pOrigBMPBuf)
{
printf("not enough memory to malloc!\n");
fclose(pFile);
return -1;
}
pRGBBuf = pVideoLogo->pRGBBuffer;
fseek(pFile, bmpFileHeader.bfOffBits, 0);
if(fread(pOrigBMPBuf, 1, h*stride, pFile) != (h*stride) )
{
printf("fread error!line:%d\n",__LINE__);
perror("fread:");
}
if(Bpp > 2)
{
dstBpp = 4;
}
else
{
dstBpp = 2;
}
if(0 == pVideoLogo->stride)
{
pVideoLogo->stride = pVideoLogo->width * dstBpp;
}
for(i=0; i<h; i++)
{
for(j=0; j<w; j++)
{
memcpy(pRGBBuf + i*pVideoLogo->stride + j*dstBpp, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
if(dstBpp == 4)
{
//*(pRGBBuf + i*pVideoLogo->stride + j*dstbpp + 3) = random()&0xff; /*alpha*/
*(pRGBBuf + i*pVideoLogo->stride + j*dstBpp + 3) = 0x80; /*alpha*/
}
}
}
free(pOrigBMPBuf);
pOrigBMPBuf = NULL;
fclose(pFile);
return 0;
}
int LoadBMPEx(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt)
{
FILE *pFile;
HI_U16 i,j;
HI_U32 w,h;
HI_U16 Bpp;
OSD_BITMAPFILEHEADER bmpFileHeader;
OSD_BITMAPINFO bmpInfo;
HI_U8 *pOrigBMPBuf;
HI_U8 *pRGBBuf;
HI_U32 stride;
HI_U8 r, g, b;
HI_U8 *pStart;
HI_U16 *pDst;
if(NULL == filename)
{
printf("OSD_LoadBMP: filename=NULL\n");
return -1;
}
if(GetBmpInfo(filename,&bmpFileHeader,&bmpInfo)<0)
{
return -1;
}
Bpp = bmpInfo.bmiHeader.biBitCount/8;
if(Bpp < 2)
{
/* only support 1555.8888 888 bitmap */
printf("bitmap format not supported!\n");
return -1;
}
if(bmpInfo.bmiHeader.biCompression != 0)
{
printf("not support compressed bitmap file!\n");
return -1;
}
if(bmpInfo.bmiHeader.biHeight < 0)
{
printf("bmpInfo.bmiHeader.biHeight < 0\n");
return -1;
}
if( (pFile = fopen((char *)filename, "rb")) == NULL)
{
printf("Open file faild:%s!\n", filename);
return -1;
}
pVideoLogo->width = (HI_U16)bmpInfo.bmiHeader.biWidth;
pVideoLogo->height = (HI_U16)((bmpInfo.bmiHeader.biHeight>0)?bmpInfo.bmiHeader.biHeight:(-bmpInfo.bmiHeader.biHeight));
w = pVideoLogo->width;
h = pVideoLogo->height;
stride = w*Bpp;
#if 1
if(stride%4)
{
stride = (stride&0xfffc) + 4;
}
#endif
/* RGB8888 or RGB1555 */
pOrigBMPBuf = (HI_U8 *)malloc(h*stride);
if(NULL == pOrigBMPBuf)
{
printf("not enough memory to malloc!\n");
fclose(pFile);
return -1;
}
pRGBBuf = pVideoLogo->pRGBBuffer;
fseek(pFile, bmpFileHeader.bfOffBits, 0);
if(fread(pOrigBMPBuf, 1, h*stride, pFile) != (h*stride) )
{
printf("fread (%d*%d)error!line:%d\n",h,stride,__LINE__);
perror("fread:");
}
if(enFmt >= OSD_COLOR_FMT_RGB888)
{
pVideoLogo->stride = pVideoLogo->width * 4;
}
else
{
pVideoLogo->stride = pVideoLogo->width * 2;
}
for(i=0; i<h; i++)
{
for(j=0; j<w; j++)
{
if(Bpp == 3)/*.....*/
{
switch(enFmt)
{
case OSD_COLOR_FMT_RGB444:
case OSD_COLOR_FMT_RGB555:
case OSD_COLOR_FMT_RGB565:
case OSD_COLOR_FMT_RGB1555:
case OSD_COLOR_FMT_RGB4444:
/* start color convert */
pStart = pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp;
pDst = (HI_U16*)(pRGBBuf + i*pVideoLogo->stride + j*2);
r = *(pStart);
g = *(pStart + 1);
b = *(pStart + 2);
*pDst = OSD_MAKECOLOR_U16(r, g, b, s_OSDCompInfo[enFmt]);
break;
case OSD_COLOR_FMT_RGB888:
case OSD_COLOR_FMT_RGB8888:
memcpy(pRGBBuf + i*pVideoLogo->stride + j*4, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
*(pRGBBuf + i*pVideoLogo->stride + j*4 + 3) = 0xff; /*alpha*/
break;
default:
printf("file(%s), line(%d), no such format!\n", __FILE__, __LINE__);
break;
}
}
else if((Bpp == 2)||(Bpp == 4))/*..............*/
{
memcpy(pRGBBuf + i*pVideoLogo->stride + j*Bpp, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
}
}
}
free(pOrigBMPBuf);
pOrigBMPBuf = NULL;
fclose(pFile);
return 0;
}
int LoadBMPCanvas(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt)
{
FILE *pFile;
HI_U16 i,j;
HI_U32 w,h;
HI_U16 Bpp;
OSD_BITMAPFILEHEADER bmpFileHeader;
OSD_BITMAPINFO bmpInfo;
HI_U8 *pOrigBMPBuf;
HI_U8 *pRGBBuf;
HI_U32 stride;
HI_U8 r, g, b;
HI_U8 *pStart;
HI_U16 *pDst;
if(NULL == filename)
{
printf("OSD_LoadBMP: filename=NULL\n");
return -1;
}
if(GetBmpInfo(filename,&bmpFileHeader,&bmpInfo)<0)
{
return -1;
}
Bpp = bmpInfo.bmiHeader.biBitCount/8;
if(Bpp < 2)
{
/* only support 1555.8888 888 bitmap */
printf("bitmap format not supported!\n");
return -1;
}
if(bmpInfo.bmiHeader.biCompression != 0)
{
printf("not support compressed bitmap file!\n");
return -1;
}
if(bmpInfo.bmiHeader.biHeight < 0)
{
printf("bmpInfo.bmiHeader.biHeight < 0\n");
return -1;
}
if( (pFile = fopen((char *)filename, "rb")) == NULL)
{
printf("Open file faild:%s!\n", filename);
return -1;
}
w = (HI_U16)bmpInfo.bmiHeader.biWidth;
h = (HI_U16)((bmpInfo.bmiHeader.biHeight>0)?bmpInfo.bmiHeader.biHeight:(-bmpInfo.bmiHeader.biHeight));
stride = w*Bpp;
#if 1
if(stride%4)
{
stride = (stride&0xfffc) + 4;
}
#endif
/* RGB8888 or RGB1555 */
pOrigBMPBuf = (HI_U8 *)malloc(h*stride);
if(NULL == pOrigBMPBuf)
{
printf("not enough memory to malloc!\n");
fclose(pFile);
return -1;
}
pRGBBuf = pVideoLogo->pRGBBuffer;
if(stride > pVideoLogo->stride)
{
printf("Bitmap's stride(%d) is bigger than canvas's stide(%d). Load bitmap error!\n", stride, pVideoLogo->stride);
return -1;
}
if(h > pVideoLogo->height)
{
printf("Bitmap's height(%d) is bigger than canvas's height(%d). Load bitmap error!\n", h, pVideoLogo->height);
return -1;
}
if(w > pVideoLogo->width)
{
printf("Bitmap's width(%d) is bigger than canvas's width(%d). Load bitmap error!\n", w, pVideoLogo->width);
return -1;
}
fseek(pFile, bmpFileHeader.bfOffBits, 0);
if(fread(pOrigBMPBuf, 1, h*stride, pFile) != (h*stride) )
{
printf("fread (%d*%d)error!line:%d\n",h,stride,__LINE__);
perror("fread:");
}
for(i=0; i<h; i++)
{
for(j=0; j<w; j++)
{
if(Bpp == 3)/*.....*/
{
switch(enFmt)
{
case OSD_COLOR_FMT_RGB444:
case OSD_COLOR_FMT_RGB555:
case OSD_COLOR_FMT_RGB565:
case OSD_COLOR_FMT_RGB1555:
case OSD_COLOR_FMT_RGB4444:
/* start color convert */
pStart = pOrigBMPBuf + ((h-1)-i)*stride + j*Bpp;
pDst = (HI_U16*)(pRGBBuf + i*pVideoLogo->stride + j*2);
r = *(pStart);
g = *(pStart + 1);
b = *(pStart + 2);
//printf("Func: %s, line:%d, Bpp: %d, bmp stride: %d, Canvas stride: %d, h:%d, w:%d.\n",
// __FUNCTION__, __LINE__, Bpp, stride, pVideoLogo->stride, i, j);
*pDst = OSD_MAKECOLOR_U16(r, g, b, s_OSDCompInfo[enFmt]);
break;
case OSD_COLOR_FMT_RGB888:
case OSD_COLOR_FMT_RGB8888:
memcpy(pRGBBuf + i*pVideoLogo->stride + j*4, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
*(pRGBBuf + i*pVideoLogo->stride + j*4 + 3) = 0xff; /*alpha*/
break;
default:
printf("file(%s), line(%d), no such format!\n", __FILE__, __LINE__);
break;
}
}
else if((Bpp == 2)||(Bpp == 4))/*..............*/
{
memcpy(pRGBBuf + i*pVideoLogo->stride + j*Bpp, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
}
}
}
free(pOrigBMPBuf);
pOrigBMPBuf = NULL;
fclose(pFile);
return 0;
}
char * GetExtName(char * filename)
{
char *pret = NULL;
HI_U32 fnLen;
if(NULL == filename)
{
printf("filename can't be null!");
return NULL;
}
fnLen = strlen(filename);
while(fnLen)
{
pret = filename + fnLen;
if(*pret == '.')
{ return (pret + 1); }
fnLen--;
}
return pret;
}
int LoadImage(const char *filename, OSD_LOGO_T *pVideoLogo)
{
char * ext = GetExtName((char *)filename);
if(strcmp(ext, "bmp") == 0)
{
if(0 != LoadBMP(filename, pVideoLogo))
{
printf("OSD_LoadBMP error!\n");
return -1;
}
}
else
{
printf("not supported image file!\n");
return -1;
}
return 0;
}
int LoadImageEx(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt)
{
char * ext = GetExtName((char *)filename);
if(strcmp(ext, "bmp") == 0)
{
if(0 != LoadBMPEx(filename, pVideoLogo, enFmt))
{
printf("OSD_LoadBMP error!\n");
return -1;
}
}
else
{
printf("not supported image file!\n");
return -1;
}
return 0;
}
int LoadCanvasEx(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt)
{
char * ext = GetExtName((char *)filename);
if(strcmp(ext, "bmp") == 0)
{
if(0 != LoadBMPCanvas(filename, pVideoLogo, enFmt))
{
printf("OSD_LoadBMP error!\n");
return -1;
}
}
else
{
printf("not supported image file!\n");
return -1;
}
return 0;
}
HI_S32 LoadBitMap2Surface(const HI_CHAR *pszFileName, const OSD_SURFACE_S *pstSurface, HI_U8 *pu8Virt)
{
OSD_LOGO_T stLogo;
stLogo.stride = pstSurface->u16Stride;
stLogo.pRGBBuffer = pu8Virt;
return LoadImage(pszFileName, &stLogo);
}
HI_S32 CreateSurfaceByBitMap(const HI_CHAR *pszFileName, OSD_SURFACE_S *pstSurface, HI_U8 *pu8Virt)
{
OSD_LOGO_T stLogo;
stLogo.pRGBBuffer = pu8Virt;
if(LoadImageEx(pszFileName, &stLogo, pstSurface->enColorFmt) < 0)
{
printf("load bmp error!\n");
return -1;
}
pstSurface->u16Height = stLogo.height;
pstSurface->u16Width = stLogo.width;
pstSurface->u16Stride = stLogo.stride;
return 0;
}
HI_S32 CreateSurfaceByCanvas(const HI_CHAR *pszFileName, OSD_SURFACE_S *pstSurface, HI_U8 *pu8Virt, HI_U32 u32Width, HI_U32 u32Height, HI_U32 u32Stride)
{
OSD_LOGO_T stLogo;
stLogo.pRGBBuffer = pu8Virt;
stLogo.width = u32Width;
stLogo.height = u32Height;
stLogo.stride = u32Stride;
if(LoadCanvasEx(pszFileName, &stLogo, pstSurface->enColorFmt) < 0)
{
printf("load bmp error!\n");
return -1;
}
pstSurface->u16Height = u32Height;
pstSurface->u16Width = u32Width;
pstSurface->u16Stride = u32Stride;
return 0;
}