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