1 /*
2 * Copyright (c) 2020-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 "gfx_utils/file.h"
17 #include "gfx_utils/mem_api.h"
18 #include "imgdecode/file_img_decoder.h"
19 #include "imgdecode/image_load.h"
20
21 namespace OHOS {
GetInstance()22 FileImgDecoder& FileImgDecoder::GetInstance()
23 {
24 static FileImgDecoder instance;
25 return instance;
26 }
27
Open(ImgResDsc & dsc)28 RetCode FileImgDecoder::Open(ImgResDsc& dsc)
29 {
30 #ifdef _WIN32
31 int32_t fd = open(dsc.path, O_RDONLY | O_BINARY);
32 #else
33 int32_t fd = open(dsc.path, O_RDONLY);
34 #endif
35 if (fd == -1) {
36 return RetCode::FAIL;
37 }
38 dsc.fd = fd;
39
40 dsc.imgInfo.data = nullptr;
41 dsc.inCache_ = false;
42 uint8_t colorMode = dsc.imgInfo.header.colorMode;
43 if (IsImgValidMode(colorMode)) {
44 return RetCode::OK;
45 } else {
46 return RetCode::FAIL;
47 }
48 }
49
Close(ImgResDsc & dsc)50 RetCode FileImgDecoder::Close(ImgResDsc& dsc)
51 {
52 if (dsc.imgInfo.data != nullptr) {
53 ImageCacheFree(dsc.imgInfo);
54 dsc.imgInfo.data = nullptr;
55 }
56 if (dsc.fd && (dsc.fd != -1)) {
57 close(dsc.fd);
58 dsc.fd = -1;
59 }
60
61 return RetCode::OK;
62 }
63
GetHeader(ImgResDsc & dsc)64 RetCode FileImgDecoder::GetHeader(ImgResDsc& dsc)
65 {
66 int32_t fd;
67 int32_t readCount;
68 #ifdef _WIN32
69 fd = open(dsc.path, O_BINARY);
70 #else
71 fd = open(dsc.path, O_RDONLY);
72 #endif
73 if (fd == -1) {
74 return RetCode::FAIL;
75 }
76
77 readCount = read(fd, &dsc.imgInfo.header, sizeof(ImageHeader));
78 close(fd);
79 dsc.fd = -1;
80 if (readCount != sizeof(ImageHeader)) {
81 dsc.imgInfo.header.width = 0;
82 dsc.imgInfo.header.height = 0;
83 dsc.imgInfo.header.colorMode = UNKNOWN;
84 return RetCode::FAIL;
85 }
86
87 return RetCode::OK;
88 }
89
ReadLine(ImgResDsc & dsc,const Point & start,int16_t len,uint8_t * buf)90 RetCode FileImgDecoder::ReadLine(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf)
91 {
92 if (IsImgValidMode(dsc.imgInfo.header.colorMode)) {
93 return ReadLineTrueColor(dsc, start, len, buf);
94 }
95 return RetCode::FAIL;
96 }
97
ReadToCache(ImgResDsc & dsc)98 RetCode FileImgDecoder::ReadToCache(ImgResDsc& dsc)
99 {
100 struct stat info;
101 if (!dsc.inCache_) {
102 lseek(dsc.fd, 0, SEEK_SET);
103 int32_t readCount = read(dsc.fd, &dsc.imgInfo.header, sizeof(ImageHeader));
104 if (readCount != sizeof(ImageHeader)) {
105 return RetCode::FAIL;
106 }
107
108 int32_t ret = fstat(dsc.fd, &info);
109 if (ret != 0) {
110 return RetCode::FAIL;
111 }
112 uint32_t pxCount = info.st_size - readCount;
113 if (dsc.imgInfo.data != nullptr) {
114 ImageCacheFree(dsc.imgInfo);
115 dsc.imgInfo.data = nullptr;
116 }
117
118 bool readSuccess = false;
119 if (dsc.imgInfo.header.compressMode != COMPRESS_MODE_NONE) {
120 readSuccess = ImageLoad::GetImageInfo(dsc.fd, pxCount, dsc.imgInfo);
121 } else {
122 dsc.imgInfo.dataSize = pxCount;
123 dsc.imgInfo.data = reinterpret_cast<uint8_t*>(ImageCacheMalloc(dsc.imgInfo));
124 if (dsc.imgInfo.data == nullptr) {
125 return RetCode::OK;
126 }
127 uint8_t* tmp = const_cast<uint8_t*>(dsc.imgInfo.data);
128 readSuccess = (static_cast<int32_t>(pxCount) == read(dsc.fd, reinterpret_cast<void*>(tmp), pxCount));
129 }
130 if (!readSuccess) {
131 ImageCacheFree(dsc.imgInfo);
132 dsc.imgInfo.data = nullptr;
133 dsc.imgInfo.dataSize = 0;
134 close(dsc.fd);
135 dsc.fd = -1;
136 return RetCode::OK;
137 }
138 dsc.inCache_ = true;
139 close(dsc.fd);
140 dsc.fd = -1;
141 }
142
143 return RetCode::OK;
144 }
145
ReadLineTrueColor(ImgResDsc & dsc,const Point & start,int16_t len,uint8_t * buf)146 RetCode FileImgDecoder::ReadLineTrueColor(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf)
147 {
148 uint8_t pxSizeInBit = DrawUtils::GetPxSizeByColorMode(dsc.imgInfo.header.colorMode);
149 off_t res;
150
151 uint32_t pos = ((start.y * dsc.imgInfo.header.width + start.x) * pxSizeInBit) >> BYTE_TO_BIT_SHIFT;
152 pos += sizeof(ImageHeader); /* Skip the header */
153 res = lseek(dsc.fd, pos, SEEK_SET);
154 if (res == -1) {
155 return RetCode::FAIL;
156 }
157 uint32_t btr = len * (pxSizeInBit >> BYTE_TO_BIT_SHIFT);
158 int32_t br = read(dsc.fd, buf, btr);
159 if ((br == -1) || (btr != static_cast<uint32_t>(br))) {
160 return RetCode::FAIL;
161 }
162
163 return RetCode::OK;
164 }
165 } // namespace OHOS
166