1 /*
2 * Copyright (c) 2024 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 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 "encode_heif_helper.h"
17
18 namespace OHOS::VDI::HEIF {
19 using namespace OHOS::HDI::Codec::Image::V2_0;
20 using namespace std;
21
22
AllocOutputBuffer(SharedBuffer & output)23 bool HeifEncodeHelper::AllocOutputBuffer(SharedBuffer& output)
24 {
25 static constexpr size_t EXTERNAL_BUFFER_SIZE = 18 * 1024 * 1024;
26 int fd = AshmemCreate("ForHeifEditOut", EXTERNAL_BUFFER_SIZE);
27 bool flag = true;
28 if (fd >= 0) {
29 output.fd = fd;
30 output.capacity = static_cast<uint32_t>(AshmemGetSize(fd));
31 } else {
32 flag = false;
33 output.fd = -1;
34 output.capacity = 0;
35 HDF_LOGE("failed to create output buffer");
36 }
37 output.filledLen = 0;
38 return flag;
39 }
40
41
Reset()42 void HeifEncodeHelper::Reset()
43 {
44 inputImgs_.clear();
45 inputMetas_.clear();
46 refs_.clear();
47 }
48
FillRefItem(ItemRef item,uint8_t * data,size_t size)49 ItemRef HeifEncodeHelper::FillRefItem(ItemRef item, uint8_t *data, size_t size)
50 {
51 uint8_t *dataEnd = data + size - 1;
52 if (dataEnd < (data + sizeof(uint8_t))) {
53 return item;
54 }
55 enum ValueOption : uint8_t {
56 OPTION_0 = 0,
57 OPTION_1,
58 OPTION_2,
59 OPTION_3,
60 OPTION_BUTT
61 };
62 switch ((*data) % OPTION_BUTT) {
63 case OPTION_0:
64 item.type = DIMG;
65 break;
66 case OPTION_1:
67 item.type = THMB;
68 break;
69 case OPTION_2:
70 item.type = AUXL;
71 break;
72 case OPTION_3:
73 item.type = CDSC;
74 break;
75 }
76 data += sizeof(uint8_t);
77
78 if (dataEnd < data + sizeof(item.from)) {
79 return item;
80 }
81 item.from = ToUint32(data);
82 data += sizeof(item.from);
83
84 if (dataEnd < data + sizeof(uint8_t)) {
85 return item;
86 }
87 uint8_t vecSize = (*data) % 2 + 1;
88 data += sizeof(vecSize);
89 if (dataEnd < (data + vecSize * sizeof(item.from))) {
90 return item;
91 } else {
92 while (vecSize--) {
93 item.to.emplace_back(ToUint32(data));
94 data += sizeof(item.from);
95 }
96 }
97 return item;
98 }
99
FillImageItem(ImgType type,ImageItem & item,uint8_t * data,size_t size)100 bool HeifEncodeHelper::FillImageItem(ImgType type, ImageItem& item, uint8_t *data, size_t size)
101 {
102 uint8_t *dataEnd = data + size - 1;
103 item.itemName = "";
104 if (dataEnd < data + sizeof(item.id)) {
105 return false;
106 }
107 item.id = ToUint32(data);
108 data += sizeof(item.id);
109
110 item.pixelBuffer = bufferHelper_.CreateImgBuffer(data, size);
111 IF_TRUE_RETURN_VAL((type != T_MAP && item.pixelBuffer == nullptr), false);
112 item.isPrimary = (type == PRIMARY_IMG);
113 item.isHidden = (type != PRIMARY_IMG);
114 item.compressType = (type == T_MAP ? "none" : "hevc");
115
116 if (dataEnd < (data + sizeof(item.quality))) {
117 return false;
118 }
119 item.quality = ToUint32(data);
120 data += sizeof(item.quality);
121
122 item.liteProperties = {};
123 if (dataEnd < (data + sizeof(uint8_t))) {
124 return false;
125 }
126 uint8_t liteProSize = *data;
127 data += sizeof(liteProSize);
128
129 if (dataEnd < data + liteProSize) {
130 return false;
131 }
132
133 HDF_LOGI("Fill Image LiteProperties");
134 while (liteProSize--) {
135 item.liteProperties.push_back(*data);
136 data += sizeof(uint8_t);
137 }
138
139 item.sharedProperties = {
140 .fd = -1,
141 .filledLen = 0,
142 .capacity = 0
143 };
144
145 if (dataEnd < (data + sizeof(uint8_t))) {
146 return false;
147 }
148 uint8_t decision = (*data) % 2;
149 data += sizeof(decision);
150 if (decision) {
151 HDF_LOGI("Fill Image SharedProperties");
152 item.sharedProperties = bufferHelper_.CreateSharedBuffer(data, size);
153 }
154 return true;
155 }
156
AssembleParamForOtherImg(uint32_t primaryImgId,uint8_t * data,size_t size)157 bool HeifEncodeHelper::AssembleParamForOtherImg(uint32_t primaryImgId, uint8_t *data, size_t size)
158 {
159 uint8_t *dataEnd = data + size - 1;
160 if (dataEnd < data + sizeof(uint8_t)) {
161 return false;
162 }
163 uint8_t decision = (*data) % 2;
164 data += sizeof(uint8_t);
165
166 if (decision == 1) {
167 ImageItem itemAuxlImg;
168 HDF_LOGI("Fill itemAuxlImg");
169 if (!FillImageItem(AUXILIARY_IMG, itemAuxlImg, data, size)) {
170 HDF_LOGE("%{public}s: Fill itemAuxlImg failed\n", __func__);
171 return false;
172 }
173 HDF_LOGI("Fill itemAuxlImg Succesfully");
174 inputImgs_.emplace_back(itemAuxlImg);
175 ItemRef refAuxl = {
176 .type = AUXL,
177 .auxType = "",
178 .from = itemAuxlImg.id,
179 .to = {primaryImgId}
180 };
181 ItemRef newRefAulx = FillRefItem(refAuxl, data, size);
182 refs_.emplace_back(newRefAulx);
183 } else {
184 ImageItem itemThmbImg;
185 HDF_LOGI("Fill itemThmbImg");
186 if (!FillImageItem(THUMBNAIL_IMG, itemThmbImg, data, size)) {
187 HDF_LOGE("%{public}s: Fill itemThmbImg failed\n", __func__);
188 return false;
189 }
190 HDF_LOGI("Fill itemThmbImg Succesfully");
191 inputImgs_.emplace_back(itemThmbImg);
192
193 ItemRef refThmb = {
194 .type = THMB,
195 .auxType = "",
196 .from = itemThmbImg.id,
197 .to = {primaryImgId}
198 };
199 ItemRef newRefThmb = FillRefItem(refThmb, data, size);
200 refs_.emplace_back(newRefThmb);
201 }
202 return true;
203 }
204
AssembleParamForTmap(uint8_t * data,size_t size)205 bool HeifEncodeHelper::AssembleParamForTmap(uint8_t *data, size_t size)
206 {
207 ImageItem itemTmap;
208 ImageItem itemPrimaryImg;
209 ImageItem itemGainMap;
210 HDF_LOGI("AssembleParamForTmap: Fill ImageItem");
211 if (!FillImageItem(T_MAP, itemTmap, data, size)) {
212 HDF_LOGE("%{public}s: Fill itemTmap failed\n", __func__);
213 return false;
214 }
215
216 if (!FillImageItem(PRIMARY_IMG, itemPrimaryImg, data, size)) {
217 HDF_LOGE("%{public}s: Fill itemPrimaryImg failed\n", __func__);
218 return false;
219 }
220
221 if (!FillImageItem(GAIN_MAP, itemGainMap, data, size)) {
222 HDF_LOGE("%{public}s: Fill itemGainMap failed\n", __func__);
223 return false;
224 }
225 inputImgs_.emplace_back(itemTmap);
226 inputImgs_.emplace_back(itemPrimaryImg);
227 inputImgs_.emplace_back(itemGainMap);
228
229 ItemRef refTMap = {
230 .type = DIMG,
231 .auxType = "",
232 .from = itemTmap.id,
233 .to = {itemPrimaryImg.id, itemGainMap.id}
234 };
235
236 HDF_LOGI("AssembleParamForTmap: Fill RefItem");
237 ItemRef newRefTMap = FillRefItem(refTMap, data, size);
238 refs_.emplace_back(newRefTMap);
239
240 HDF_LOGI("AssembleParamForTmap: Fill OtherImg");
241 if (AssembleParamForOtherImg(itemPrimaryImg.id, data, size)) {
242 HDF_LOGI("AssembleParamForTmap: Fill MetaData");
243 return AssembleParamForMetaData(itemPrimaryImg.id, data, size);
244 }
245 return false;
246 }
247
AssembleParamForPrimaryImg(uint8_t * data,size_t size)248 bool HeifEncodeHelper::AssembleParamForPrimaryImg(uint8_t *data, size_t size)
249 {
250 ImageItem itemPrimaryImg;
251 HDF_LOGI("AssembleParamForPrimaryImg: Fill ImageItem");
252 if (!FillImageItem(PRIMARY_IMG, itemPrimaryImg, data, size)) {
253 HDF_LOGE("%{public}s: Fill itemPrimaryImg failed\n", __func__);
254 return false;
255 }
256 inputImgs_.emplace_back(itemPrimaryImg);
257 HDF_LOGI("AssembleParamForPrimaryImg: Fill OtherImg");
258 if (AssembleParamForOtherImg(itemPrimaryImg.id, data, size)) {
259 HDF_LOGI("AssembleParamForPrimaryImg: Fill MetaData");
260 return AssembleParamForMetaData(itemPrimaryImg.id, data, size);
261 }
262 return true;
263 }
264
FillMetaItem(MetaType type,MetaItem & item,uint8_t * data,size_t size)265 bool HeifEncodeHelper::FillMetaItem(MetaType type, MetaItem& item, uint8_t *data, size_t size)
266 {
267 uint8_t *dataEnd = data + size - 1;
268 item.itemName = "";
269 if (dataEnd < data + sizeof(item.id)) {
270 return false;
271 }
272 item.id = ToUint32(data);
273 data += sizeof(item.id);
274 item.properties = {};
275
276 if (type == USER_DATA) {
277 static constexpr char USER_DATA_LABEL[] = "userdata";
278 item.itemName = USER_DATA_LABEL;
279
280 if (dataEnd < data + sizeof(uint8_t)) {
281 return false;
282 }
283 uint8_t propertiesSize = *data;
284 data += sizeof(propertiesSize);
285
286 if (dataEnd < data + propertiesSize) {
287 return false;
288 }
289
290 while (propertiesSize--) {
291 item.properties.emplace_back(*data);
292 data += sizeof(uint8_t);
293 }
294 } else if (type == EXIF_DATA) {
295 static constexpr char EXIF_LABEL[] = "exif";
296 item.itemName = EXIF_LABEL;
297 }
298 item.data = bufferHelper_.CreateSharedBuffer(data, size);
299 return (item.data.fd >= 0);
300 }
301
AssembleParamForMetaData(uint32_t primaryImgId,uint8_t * data,size_t size)302 bool HeifEncodeHelper::AssembleParamForMetaData(uint32_t primaryImgId, uint8_t *data, size_t size)
303 {
304 HDF_LOGI("AssembleParamForMetaData");
305 uint8_t* dataEnd = data + size - 1;
306 if (dataEnd < data + sizeof(uint8_t)) {
307 return false;
308 }
309 uint8_t decision = (*data) % 2;
310 data += sizeof(decision);
311 if (decision) {
312 HDF_LOGI("add exif");
313 MetaItem metaExifData;
314 HDF_LOGI("Fill Meta Item");
315 IF_TRUE_RETURN_VAL(!FillMetaItem(EXIF_DATA, metaExifData, data, size), false);
316 inputMetas_.emplace_back(metaExifData);
317 ItemRef refItem1 = {
318 .type = CDSC,
319 .auxType = "",
320 .from = metaExifData.id,
321 .to = {primaryImgId}
322 } ;
323 ItemRef newRefIt1 = FillRefItem(refItem1, data, size);
324 refs_.emplace_back(newRefIt1);
325 HDF_LOGI("Fill EXIF Data Succesfully");
326 } else {
327 HDF_LOGI("add userData");
328 MetaItem metaUserData;
329 HDF_LOGI("Fill Meta Item");
330 IF_TRUE_RETURN_VAL(!FillMetaItem(USER_DATA, metaUserData, data, size), false);
331 inputMetas_.emplace_back(metaUserData);
332 ItemRef refItem2 = {
333 .type = CDSC,
334 .auxType = "",
335 .from = metaUserData.id,
336 .to = {primaryImgId}
337 } ;
338 ItemRef newRefIt2 = FillRefItem(refItem2, data, size);
339 refs_.emplace_back(newRefIt2);
340 HDF_LOGI("Fill USER Data Succesfully");
341 }
342 return true;
343 }
344
345 }
346