xref: /OK3568_Linux_fs/external/rockit/mpi/example/common/test_comm_bmp.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2021 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include "test_comm_bmp.h"
23 
24 OSD_COMP_INFO s_OSDCompInfo[OSD_COLOR_FMT_BUTT] = {{0, 4, 4, 4},   /*RGB444*/
25                                                     {4, 4, 4, 4},   /*ARGB4444*/
26                                                     {4, 4, 4, 4},   /*BGRA4444*/
27                                                     {0, 5, 5, 5},   /*RGB555*/
28                                                     {0, 5, 6, 5},   /*RGB565*/
29                                                     {1, 5, 5, 5},   /*ARGB1555*/
30                                                     {1, 5, 5, 5},   /*BGRA5551*/
31                                                     {0, 8, 8, 8},   /*RGB888*/
32                                                     {0, 8, 8, 8},   /*BGR888*/
33                                                     {8, 8, 8, 8},   /*ARGB8888*/
34                                                     {8, 8, 8, 8}    /*BGRA8888*/
35                                                     };
OSD_MAKECOLOR_ARGB(RK_U8 r,RK_U8 g,RK_U8 b,OSD_COMP_INFO compinfo)36 inline RK_U32 OSD_MAKECOLOR_ARGB(RK_U8 r, RK_U8 g, RK_U8 b, OSD_COMP_INFO compinfo) {
37     RK_U8 r1, g1, b1;
38     RK_U32 pixel = 0;
39     RK_U32 tmp = compinfo.alen - 1;
40     RK_U8 alen = compinfo.alen;
41 
42     r1 = g1 = b1 = 0;
43     r1 = r >> (8 - compinfo.rlen);
44     g1 = g >> (8 - compinfo.glen);
45     b1 = b >> (8 - compinfo.blen);
46     while (alen) {
47         pixel |= (1 << tmp);
48         tmp--;
49         alen--;
50     }
51 
52     pixel |= (r1 << compinfo.alen | (g1 << (compinfo.rlen + compinfo.alen))
53                    | (b1 << (compinfo.rlen + compinfo.glen + compinfo.alen)));
54     return pixel;
55 }
56 
OSD_MAKECOLOR_BGRA(RK_U8 r,RK_U8 g,RK_U8 b,OSD_COMP_INFO compinfo)57 inline RK_U32 OSD_MAKECOLOR_BGRA(RK_U8 r, RK_U8 g, RK_U8 b, OSD_COMP_INFO compinfo) {
58     RK_U8 r1, g1, b1;
59     RK_U32 pixel = 0;
60     RK_U32 tmp = compinfo.alen + compinfo.rlen + compinfo.glen + compinfo.blen - 1;
61     RK_U8 alen = compinfo.alen;
62 
63     r1 = g1 = b1 = 0;
64     r1 = r >> (8 - compinfo.rlen);
65     g1 = g >> (8 - compinfo.glen);
66     b1 = b >> (8 - compinfo.blen);
67     while (alen) {
68         pixel |= (1 << tmp);
69         tmp--;
70         alen--;
71     }
72 
73     pixel |= ((r1 << (compinfo.blen + compinfo.glen)) | (g1 << compinfo.blen) | b1);
74     return pixel;
75 }
76 
TEST_COMM_GetBmpInfo(const char * filename,OSD_BITMAPFILEHEADER * pBmpFileHeader,OSD_BITMAPINFO * pBmpInfo)77 RK_S32 TEST_COMM_GetBmpInfo(
78         const char *filename, OSD_BITMAPFILEHEADER *pBmpFileHeader, OSD_BITMAPINFO *pBmpInfo) {
79     FILE *pFile;
80 
81     RK_U16 bfType;
82 
83     if (NULL == filename) {
84         printf("OSD_LoadBMP: filename=NULL\n");
85         return -1;
86     }
87 
88     if ((pFile = fopen(filename, "rb")) == NULL) {
89         printf("Open file faild:%s!\n", filename);
90         return -1;
91     }
92 
93     (void)fread(&bfType, 1, sizeof(bfType), pFile);
94     if (bfType != 0x4d42) {
95         printf("not bitmap file\n");
96         fclose(pFile);
97         return -1;
98     }
99 
100     (void)fread(pBmpFileHeader, 1, sizeof(OSD_BITMAPFILEHEADER), pFile);
101     (void)fread(pBmpInfo, 1, sizeof(OSD_BITMAPINFO), pFile);
102     fclose(pFile);
103 
104     return 0;
105 }
106 
load_bmp_ex(const char * filename,OSD_LOGO_T * pVideoLogo,OSD_COLOR_FMT_E enFmt)107 RK_S32 load_bmp_ex(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt) {
108     FILE *pFile;
109     RK_U16 i, j;
110 
111     RK_U32  w, h;
112     RK_U16  Bpp;
113 
114     OSD_BITMAPFILEHEADER  bmpFileHeader;
115     OSD_BITMAPINFO        bmpInfo;
116 
117     RK_U8 *pOrigBMPBuf;
118     RK_U8 *pRGBBuf;
119     RK_U32 stride;
120     RK_U8  r, g, b;
121     RK_U8 *pStart;
122     RK_U16 *pDst;
123     RK_U32 *pu32Dst;
124 
125     if (NULL == filename) {
126         printf("load_bmp_ex: filename=NULL\n");
127         return -1;
128     }
129 
130     if (TEST_COMM_GetBmpInfo(filename, &bmpFileHeader, &bmpInfo) < 0) {
131         return -1;
132     }
133 
134     Bpp = bmpInfo.bmiHeader.biBitCount/8;
135     if (Bpp < 2) {
136         /* only support 1555.8888  888 bitmap */
137         printf("bitmap format not supported!\n");
138         return -1;
139     }
140 
141     if (bmpInfo.bmiHeader.biCompression != 0) {
142         printf("not support compressed bitmap file!\n");
143         return -1;
144     }
145 
146     if (bmpInfo.bmiHeader.biHeight < 0) {
147         printf("bmpInfo.bmiHeader.biHeight < 0\n");
148         return -1;
149     }
150 
151     if ((pFile = fopen(filename, "rb")) == NULL) {
152         printf("Open file faild:%s!\n", filename);
153         return -1;
154     }
155 
156     pVideoLogo->width = (RK_U16)bmpInfo.bmiHeader.biWidth;
157     pVideoLogo->height = (RK_U16)((bmpInfo.bmiHeader.biHeight > 0) ?
158                              bmpInfo.bmiHeader.biHeight : (-bmpInfo.bmiHeader.biHeight));
159     w = pVideoLogo->width;
160     h = pVideoLogo->height;
161 
162     stride = w * Bpp;
163 
164     if (stride % 4) {
165         stride = (stride & 0xfffc) + 4;
166     }
167 
168     /* RGB8888 or RGB1555 */
169     pOrigBMPBuf = reinterpret_cast<RK_U8 *>(malloc(h * stride));
170     if (NULL == pOrigBMPBuf) {
171         printf("not enough memory to malloc!\n");
172         fclose(pFile);
173         return -1;
174     }
175 
176     pRGBBuf = pVideoLogo->pRGBBuffer;
177 
178     fseek(pFile, bmpFileHeader.bfOffBits, 0);
179     if (fread(pOrigBMPBuf, 1, h*stride, pFile) != (h * stride)) {
180         printf("fread (%d*%d)error!line:%d\n", h, stride, __LINE__);
181         return -1;
182     }
183 
184     if (enFmt >= OSD_COLOR_FMT_RGB888) {
185         pVideoLogo->stride = pVideoLogo->width * 4;
186     } else {
187         pVideoLogo->stride = pVideoLogo->width * 2;
188     }
189 
190     for (i = 0; i < h; i++) {
191         for (j = 0; j < w; j++) {
192             if (Bpp == 3) {
193                 switch (enFmt) {
194                     case OSD_COLOR_FMT_RGB444:
195                     case OSD_COLOR_FMT_RGB555:
196                     case OSD_COLOR_FMT_RGB565:
197                     case OSD_COLOR_FMT_ARGB1555:
198                     case OSD_COLOR_FMT_ARGB4444:
199                         /* start color convert */
200                         pStart = pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp;
201                         pDst = reinterpret_cast<RK_U16*>(pRGBBuf + i*pVideoLogo->stride + j*2);
202                         b = *(pStart);
203                         g = *(pStart + 1);
204                         r = *(pStart + 2);
205                         *pDst = (RK_U16)OSD_MAKECOLOR_ARGB(r, g, b, s_OSDCompInfo[enFmt]);
206                         break;
207                     case OSD_COLOR_FMT_BGRA5551:
208                     case OSD_COLOR_FMT_BGRA4444:
209                         /* start color convert */
210                         pStart = pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp;
211                         pDst = reinterpret_cast<RK_U16*>(pRGBBuf + i*pVideoLogo->stride + j*2);
212                         b = *(pStart);
213                         g = *(pStart + 1);
214                         r = *(pStart + 2);
215                         *pDst = (RK_U16)OSD_MAKECOLOR_BGRA(r, g, b, s_OSDCompInfo[enFmt]);
216                         break;
217                     case OSD_COLOR_FMT_BGR888:
218                     case OSD_COLOR_FMT_BGRA8888:
219                         memcpy(pRGBBuf + i*pVideoLogo->stride + j*4, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
220                         *(pRGBBuf + i*pVideoLogo->stride + j*4 + 3) = 0xff; /*alpha*/
221                         break;
222                     case OSD_COLOR_FMT_RGB888:
223                     case OSD_COLOR_FMT_ARGB8888:
224                         /* start color convert */
225                         pStart = pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp;
226                         pu32Dst = reinterpret_cast<RK_U32*>(pRGBBuf + i*pVideoLogo->stride + j*4);
227                         b = *(pStart);
228                         g = *(pStart + 1);
229                         r = *(pStart + 2);
230                         *pu32Dst = OSD_MAKECOLOR_ARGB(r, g, b, s_OSDCompInfo[enFmt]);
231                         break;
232                     default:
233                         printf("file(%s), line(%d), no such format!\n", __FILE__, __LINE__);
234                         break;
235                 }
236             } else if ((Bpp == 2) || (Bpp == 4)) {
237                 memcpy(pRGBBuf + i*pVideoLogo->stride + j*Bpp, pOrigBMPBuf + ((h-1)-i)*stride+j*Bpp, Bpp);
238             }
239         }
240     }
241 
242     free(pOrigBMPBuf);
243     pOrigBMPBuf = NULL;
244 
245     fclose(pFile);
246     return 0;
247 }
248 
get_ext_name(char * filename)249 char *get_ext_name(char *filename) {
250     char *pret = NULL;
251     RK_U32 fnLen;
252 
253     if (NULL == filename) {
254         printf("filename can't be null!");
255         return NULL;
256     }
257 
258     fnLen = strlen(filename);
259     while (fnLen) {
260         pret = filename + fnLen;
261         if (*pret == '.')
262             return (pret+1);
263 
264         fnLen--;
265     }
266 
267     return pret;
268 }
269 
load_image_ex(const char * filename,OSD_LOGO_T * pVideoLogo,OSD_COLOR_FMT_E enFmt)270 RK_S32 load_image_ex(const char *filename, OSD_LOGO_T *pVideoLogo, OSD_COLOR_FMT_E enFmt) {
271     char *ext = get_ext_name(const_cast<char *>(filename));
272 
273     if (strcmp(ext, "bmp") == 0) {
274         if (0 != load_bmp_ex(filename, pVideoLogo, enFmt)) {
275             printf("OSD_LoadBMP error!\n");
276             return -1;
277         }
278     } else {
279         printf("not supported image file!\n");
280         return -1;
281     }
282 
283     return 0;
284 }
285 
TEST_COMM_CreateSurfaceByBitmap(const char * pstFileName,OSD_SURFACE_S * pstSurface,RK_U8 * pu8Virt)286 RK_S32 TEST_COMM_CreateSurfaceByBitmap(
287         const char *pstFileName, OSD_SURFACE_S *pstSurface, RK_U8 *pu8Virt) {
288     OSD_LOGO_T stLogo;
289     stLogo.pRGBBuffer = pu8Virt;
290     if (load_image_ex(pstFileName, &stLogo, pstSurface->enColorFmt) < 0) {
291         printf("load bmp error!\n");
292         return -1;
293     }
294 
295     pstSurface->u16Height = stLogo.height;
296     pstSurface->u16Width = stLogo.width;
297     pstSurface->u16Stride = stLogo.stride;
298 
299     return 0;
300 }
301 
302 
303