• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "loadbmp_test.h"
17 #include <stdio.h>
18 #include <stdint.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <limits.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include "securec.h"
25 #include "hdf_log.h"
26 #include "display_type.h"
27 
28 #define EOK 0
29 
30 OsdCompInfo g_osdCompInfo[OSD_COLOR_FMT_BUTT] = {
31     {0, 4, 4, 4},   /* RGB444 */
32     {4, 4, 4, 4},   /* ARGB4444 */
33     {0, 5, 5, 5},   /* RGB555 */
34     {0, 5, 6, 5},   /* RGB565 */
35     {1, 5, 5, 5},   /* ARGB1555 */
36     {0, 0, 0, 0},   /* RESERVED */
37     {0, 8, 8, 8},   /* RGB888 */
38     {8, 8, 8, 8}    /* ARGB8888 */
39 };
40 
OsdMakeColorU16(uint8_t r,uint8_t g,uint8_t b,OsdCompInfo compinfo)41 static uint16_t OsdMakeColorU16(uint8_t r, uint8_t g, uint8_t b, OsdCompInfo compinfo)
42 {
43     uint8_t r1;
44     uint8_t g1;
45     uint8_t b1;
46     uint16_t pixel = 0;
47     uint32_t tmp = 15; // 16bit color
48 
49     r1 = g1 = b1 = 0;
50     r1 = r >> (EIGHT_BITS_PER_PIXEL - compinfo.rLen);
51     g1 = g >> (EIGHT_BITS_PER_PIXEL - compinfo.gLen);
52     b1 = b >> (EIGHT_BITS_PER_PIXEL - compinfo.bLen);
53     while (compinfo.aLen != 0) {
54         pixel |= (1 << tmp);
55         tmp--;
56         compinfo.aLen--;
57     }
58 
59     pixel |= (r1 | (g1 << compinfo.bLen) | (b1 << (compinfo.bLen + compinfo.gLen)));
60     return pixel;
61 }
62 
GetBmpInfo(const int8_t * fileName,OsdBitMapFileHeader * bmpFileHeader,OsdBitMapInfo * bmpInfo)63 int32_t GetBmpInfo(const int8_t *fileName, OsdBitMapFileHeader *bmpFileHeader, OsdBitMapInfo *bmpInfo)
64 {
65     FILE *file = NULL;
66     uint16_t bfType = 0;
67     char realPath[PATH_MAX] = {0};
68 
69     if (realpath((char*)fileName, realPath) == NULL) {
70         printf("%s: file %s does not exist\n", __func__, fileName);
71         return DISPLAY_FAILURE;
72     }
73     if ((file = fopen((const char*)realPath, "rb")) == NULL) {
74         HDF_LOGE("%s: Open file failure: %s", __func__, fileName);
75         return DISPLAY_FAILURE;
76     }
77 
78     (void)fread(&bfType, 1, sizeof(bfType), file);
79     if (bfType != BITMAP_FILE) {
80         HDF_LOGE("%s: not bitmap file", __func__);
81         fclose(file);
82         return DISPLAY_FAILURE;
83     }
84 
85     (void)fread(bmpFileHeader, 1, sizeof(OsdBitMapFileHeader), file);
86     (void)fread(bmpInfo, 1, sizeof(OsdBitMapInfo), file);
87     fclose(file);
88 
89     return DISPLAY_SUCCESS;
90 }
91 
CheckBmpInfo(const OsdBitMapInfo * bmpInfo)92 static int32_t CheckBmpInfo(const OsdBitMapInfo *bmpInfo)
93 {
94     uint16_t bpp;
95 
96     bpp = bmpInfo->header.bitCnt / EIGHT_BITS_PER_PIXEL;
97     if (bpp < INVALID_BITS) {
98         /* only support 1555.8888  888 bitmap */
99         HDF_LOGE("%s: bitmap format not supported", __func__);
100         return DISPLAY_FAILURE;
101     }
102 
103     if (bmpInfo->header.compress != 0) {
104         HDF_LOGE("%s: not support compressed bitmap file", __func__);
105         return DISPLAY_FAILURE;
106     }
107     if (bmpInfo->header.height == 0) {
108         HDF_LOGE("%s: bmpInfo.header.height is 0", __func__);
109         return DISPLAY_FAILURE;
110     }
111     return DISPLAY_SUCCESS;
112 }
113 
LoadPicToBuffer(const int8_t * fileName,OsdLogo * videoLogo,OsdColorFmt enFmt,uint8_t ** outBuf,uint32_t * stride)114 static int32_t LoadPicToBuffer(const int8_t *fileName, OsdLogo *videoLogo, OsdColorFmt enFmt,
115                                uint8_t **outBuf, uint32_t *stride)
116 {
117     FILE *file = NULL;
118     OsdBitMapFileHeader bmpFileHeader;
119     OsdBitMapInfo       bmpInfo;
120     uint32_t h;
121     uint64_t byteNum;
122     char realPath[PATH_MAX] = {0};
123 
124     if (GetBmpInfo(fileName, &bmpFileHeader, &bmpInfo) < 0) {
125         return DISPLAY_FAILURE;
126     }
127     if (CheckBmpInfo(&bmpInfo) != DISPLAY_SUCCESS) {
128         /* only support 1555.8888  888 bitmap */
129         HDF_LOGE("%s: bitmap format not supported", __func__);
130         return DISPLAY_FAILURE;
131     }
132     videoLogo->bpp = bmpInfo.header.bitCnt / EIGHT_BITS_PER_PIXEL;
133     if (realpath((char*)fileName, realPath) == NULL) {
134         printf("%s: file %s does not exist\n", __func__, fileName);
135         return DISPLAY_FAILURE;
136     }
137     if ((file = fopen((const char*)realPath, "rb")) == NULL) {
138         HDF_LOGE("%s: Open file failure: %s", __func__, fileName);
139         return DISPLAY_FAILURE;
140     }
141     videoLogo->width = bmpInfo.header.width;
142     videoLogo->height = ((bmpInfo.header.height > 0) ? bmpInfo.header.height :
143                         (-bmpInfo.header.height));
144     *stride = videoLogo->width * videoLogo->bpp;
145     h = videoLogo->height;
146     if ((*stride % FOUR_BITS_PER_PIXEL) != 0) {
147         *stride = (*stride & 0xfffc) + FOUR_BITS_PER_PIXEL;
148     }
149     /* RGB8888 or RGB1555 */
150     *outBuf = (uint8_t*)malloc(videoLogo->height * (*stride));
151     if (*outBuf == NULL) {
152         HDF_LOGE("%s: not enough memory to malloc", __func__);
153         fclose(file);
154         return DISPLAY_FAILURE;
155     }
156     fseek(file, bmpFileHeader.offBits, 0);
157     byteNum = h * (*stride);
158     if (byteNum > UINT32_MAX) {
159         HDF_LOGE("%s: buffer size is beyond param's limit", __func__);
160         fclose(file);
161         free(*outBuf);
162         *outBuf = NULL;
163         return DISPLAY_FAILURE;
164     }
165     if (fread((*outBuf), 1, byteNum, file) != byteNum) {
166         HDF_LOGE("%s: fread %u*%u error", __func__, h, *stride);
167         fclose(file);
168         free(*outBuf);
169         *outBuf = NULL;
170         return DISPLAY_FAILURE;
171     }
172     if (enFmt >= OSD_COLOR_FMT_RGB888) {
173         videoLogo->stride = videoLogo->width * FOUR_BITS_PER_PIXEL;
174     } else {
175         videoLogo->stride = videoLogo->width * TWO_BITS_PER_PIXEL;
176     }
177     fclose(file);
178     return DISPLAY_SUCCESS;
179 }
180 
LoadRgbData(OsdLogo * videoLogo,OsdColorFmt enFmt,uint32_t stride,uint8_t * origBuf)181 static void LoadRgbData(OsdLogo *videoLogo, OsdColorFmt enFmt, uint32_t stride, uint8_t *origBuf)
182 {
183     uint16_t i;
184     uint16_t j;
185     uint8_t *start = NULL;
186     uint16_t *dst = NULL;
187     uint32_t h;
188     OsdColor c;
189 
190     h = videoLogo->height;
191     for (i = 0; i < videoLogo->height; i++) {
192         for (j = 0; j < videoLogo->width; j++) {
193             /* start color convert */
194             start = origBuf + ((h - 1) - i) * stride + j * videoLogo->bpp;
195             dst = (uint16_t*)(videoLogo->picBuffer + i * videoLogo->stride + j * TWO_OFFSET);
196             c.r = *(start);
197             c.g = *(start + ONE_OFFSET);
198             c.b = *(start + TWO_OFFSET);
199             *dst = OsdMakeColorU16(c.r, c.g, c.b, g_osdCompInfo[enFmt]);
200         }
201     }
202 }
203 
LoadData(OsdLogo * videoLogo,OsdColorFmt enFmt,uint32_t stride,uint8_t * origBuf)204 static int32_t LoadData(OsdLogo *videoLogo, OsdColorFmt enFmt, uint32_t stride, uint8_t *origBuf)
205 {
206     int32_t ret;
207     uint16_t i;
208     uint16_t j;
209     uint32_t h;
210 
211     (void)enFmt;
212     h = videoLogo->height;
213     for (i = 0; i < videoLogo->height; i++) {
214         for (j = 0; j < videoLogo->width; j++) {
215             ret = memcpy_s((videoLogo->picBuffer + i * videoLogo->stride + j * FOUR_BITS_PER_PIXEL), videoLogo->len,
216                 (origBuf + ((h - 1) - i) * stride + j * videoLogo->bpp), videoLogo->bpp);
217             if (ret != EOK) {
218                 HDF_LOGE("%s: file: %s, line: %d, memcpy_s failure", __func__, __FILE__, __LINE__);
219                 return DISPLAY_FAILURE;
220             }
221             *(videoLogo->picBuffer + i * videoLogo->stride + j * FOUR_BITS_PER_PIXEL + THREE_BITS_PER_PIXEL) = 0xff;
222         }
223     }
224     return DISPLAY_SUCCESS;
225 }
226 
Copy3BitsByFmt(OsdLogo * videoLogo,OsdColorFmt enFmt,uint32_t stride,uint8_t * origBuf)227 static int32_t Copy3BitsByFmt(OsdLogo *videoLogo, OsdColorFmt enFmt, uint32_t stride, uint8_t *origBuf)
228 {
229     int32_t ret = DISPLAY_SUCCESS;
230 
231     switch (enFmt) {
232         case OSD_COLOR_FMT_RGB444:
233         case OSD_COLOR_FMT_RGB555:
234         case OSD_COLOR_FMT_RGB565:
235         case OSD_COLOR_FMT_RGB1555:
236         case OSD_COLOR_FMT_RGB4444:
237             /* start color convert */
238             LoadRgbData(videoLogo, enFmt, stride, origBuf);
239             break;
240         case OSD_COLOR_FMT_RGB888:
241         case OSD_COLOR_FMT_RGB8888:
242             ret = LoadData(videoLogo, enFmt, stride, origBuf);
243             break;
244         default:
245             HDF_LOGE("%s: file: %s, line: %d, no such format", __func__, __FILE__, __LINE__);
246             return DISPLAY_FAILURE;
247     }
248     return ret;
249 }
250 
Copy2BitsAnd4Bits(OsdLogo * videoLogo,uint32_t stride,uint8_t * origBuf)251 static int32_t Copy2BitsAnd4Bits(OsdLogo *videoLogo, uint32_t stride, uint8_t *origBuf)
252 {
253     int32_t ret;
254     uint16_t i;
255     uint16_t j;
256     uint8_t *pRGBBuf;
257 
258     pRGBBuf = videoLogo->picBuffer;
259     for (i = 0; i < videoLogo->height; i++) {
260         for (j = 0; j < videoLogo->width; j++) {
261             ret = memcpy_s((pRGBBuf + i * videoLogo->stride + j * videoLogo->bpp), videoLogo->len,
262                 (origBuf + ((videoLogo->height - 1) - i) * stride + j * videoLogo->bpp), videoLogo->bpp);
263             if (ret != EOK) {
264                 HDF_LOGE("%s: file: %s, line: %d, memcpy_s failure", __func__, __FILE__, __LINE__);
265                 return DISPLAY_FAILURE;
266             }
267         }
268     }
269     return DISPLAY_SUCCESS;
270 }
271 
LoadBMPEx(const int8_t * fileName,OsdLogo * videoLogo,OsdColorFmt enFmt)272 static int32_t LoadBMPEx(const int8_t *fileName, OsdLogo *videoLogo, OsdColorFmt enFmt)
273 {
274     int32_t ret;
275     uint32_t stride;
276     uint8_t *origBmpBuf = NULL;
277 
278     ret = LoadPicToBuffer(fileName, videoLogo, enFmt, &origBmpBuf, &stride);
279     if (ret != DISPLAY_SUCCESS) {
280         HDF_LOGE("%s: LoadPicToBuffer failure", __func__);
281         return DISPLAY_FAILURE;
282     }
283     if (videoLogo->bpp == THREE_BITS_PER_PIXEL) {
284         ret = Copy3BitsByFmt(videoLogo, enFmt, stride, origBmpBuf);
285         if (ret != DISPLAY_SUCCESS) {
286             HDF_LOGE("%s: Copy3BitsByFmt failure", __func__);
287         }
288     } else if ((videoLogo->bpp == TWO_BITS_PER_PIXEL) || (videoLogo->bpp == FOUR_BITS_PER_PIXEL)) {
289         ret = Copy2BitsAnd4Bits(videoLogo, stride, origBmpBuf);
290         if (ret != DISPLAY_SUCCESS) {
291             HDF_LOGE("%s: Copy2BitsAnd4Bits failure", __func__);
292             free(origBmpBuf);
293             return ret;
294         }
295     }
296     free(origBmpBuf);
297     return DISPLAY_SUCCESS;
298 }
299 
LoadImageEx(const int8_t * fileName,OsdLogo * videoLogo,OsdColorFmt enFmt)300 static int32_t LoadImageEx(const int8_t *fileName, OsdLogo *videoLogo, OsdColorFmt enFmt)
301 {
302     char *ext = strrchr((const char *)fileName, '.');
303 
304     if (ext == NULL) {
305         HDF_LOGE("%s: LoadImageEx error", __func__);
306         return DISPLAY_FAILURE;
307     }
308 
309     ext = ext + 1;
310     if (strcmp(ext, "bmp") == 0) {
311         if (LoadBMPEx(fileName, videoLogo, enFmt) != 0) {
312             HDF_LOGE("%s: LoadBMPEx error", __func__);
313             return DISPLAY_FAILURE;
314         }
315     } else {
316         HDF_LOGE("%s: not supported image file", __func__);
317         return DISPLAY_FAILURE;
318     }
319 
320     return DISPLAY_SUCCESS;
321 }
322 
CreateSurfaceByBitMap(const int8_t * fileName,OsdSurface * pstSurface,uint8_t * virAddr,uint32_t len)323 int32_t CreateSurfaceByBitMap(const int8_t *fileName, OsdSurface *pstSurface, uint8_t *virAddr, uint32_t len)
324 {
325     OsdLogo stLogo;
326 
327     if (fileName == NULL) {
328         HDF_LOGE("%s: fileName is null", __func__);
329         return DISPLAY_FAILURE;
330     }
331     if (pstSurface == NULL) {
332         HDF_LOGE("%s: pstSurface is null", __func__);
333         return DISPLAY_FAILURE;
334     }
335     if (virAddr == NULL) {
336         HDF_LOGE("%s: virAddr is null", __func__);
337         return DISPLAY_FAILURE;
338     }
339     (void)memset_s(&stLogo, sizeof(OsdLogo), 0, sizeof(OsdLogo));
340     stLogo.picBuffer = virAddr;
341     stLogo.len = len;
342     if (LoadImageEx(fileName, &stLogo, pstSurface->colorFmt) < 0) {
343         HDF_LOGE("%s: load bmp error", __func__);
344         return DISPLAY_FAILURE;
345     }
346     pstSurface->height = stLogo.height;
347     pstSurface->width = stLogo.width;
348     pstSurface->stride = stLogo.stride;
349     return DISPLAY_SUCCESS;
350 }
351