• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "metadata_utils.h"
17 #include <securec.h>
18 #include "metadata_log.h"
19 
20 namespace OHOS::Camera {
EncodeCameraMetadata(const std::shared_ptr<CameraMetadata> & metadata,MessageParcel & data)21 bool MetadataUtils::EncodeCameraMetadata(const std::shared_ptr<CameraMetadata> &metadata,
22                                          MessageParcel &data)
23 {
24     if (metadata == nullptr) {
25         return false;
26     }
27 
28     bool bRet = true;
29     uint32_t tagCount = 0;
30     common_metadata_header_t *meta = metadata->get();
31     if (meta != nullptr) {
32         tagCount = GetCameraMetadataItemCount(meta);
33         bRet = bRet && data.WriteUint32(tagCount);
34         bRet = bRet && data.WriteUint32(GetCameraMetadataItemCapacity(meta));
35         bRet = bRet && data.WriteUint32(GetCameraMetadataDataSize(meta));
36         for (uint32_t i = 0; i < tagCount; i++) {
37             camera_metadata_item_t item;
38             int ret = GetCameraMetadataItem(meta, i, &item);
39             if (ret != CAM_META_SUCCESS) {
40                 return false;
41             }
42 
43             bRet = bRet && data.WriteUint32(item.index);
44             bRet = bRet && data.WriteUint32(item.item);
45             bRet = bRet && data.WriteUint32(item.data_type);
46             bRet = bRet && data.WriteUint32(item.count);
47             bRet = bRet && MetadataUtils::WriteMetadata(item, data);
48         }
49     } else {
50         bRet = data.WriteUint32(tagCount);
51     }
52     return bRet;
53 }
54 
DecodeCameraMetadata(MessageParcel & data,std::shared_ptr<CameraMetadata> & metadata)55 void MetadataUtils::DecodeCameraMetadata(MessageParcel &data, std::shared_ptr<CameraMetadata> &metadata)
56 {
57     uint32_t tagCount = data.ReadUint32();
58     uint32_t itemCapacity = data.ReadUint32();
59     uint32_t dataCapacity = data.ReadUint32();
60     constexpr uint32_t MAX_SUPPORTED_TAGS = 1000;
61     constexpr uint32_t MAX_SUPPORTED_ITEMS = 1000;
62     constexpr uint32_t MAX_ITEM_CAPACITY = (1000 * 10);
63     constexpr uint32_t MAX_DATA_CAPACITY = (1000 * 10 * 10);
64 
65     if (tagCount > MAX_SUPPORTED_TAGS) {
66         tagCount = MAX_SUPPORTED_TAGS;
67         METADATA_ERR_LOG("MetadataUtils::DecodeCameraMetadata tagCount is more than supported value");
68     }
69 
70     if (itemCapacity > MAX_ITEM_CAPACITY) {
71         itemCapacity = MAX_ITEM_CAPACITY;
72         METADATA_ERR_LOG("MetadataUtils::DecodeCameraMetadata itemCapacity is more than supported value");
73     }
74 
75     if (dataCapacity > MAX_DATA_CAPACITY) {
76         dataCapacity = MAX_DATA_CAPACITY;
77         METADATA_ERR_LOG("MetadataUtils::DecodeCameraMetadata dataCapacity is more than supported value");
78     }
79 
80     std::vector<camera_metadata_item_t> items;
81     for (uint32_t i = 0; i < tagCount; i++) {
82         camera_metadata_item_t item;
83         item.index = data.ReadUint32();
84         item.item = data.ReadUint32();
85         item.data_type = data.ReadUint32();
86         item.count = data.ReadUint32();
87         if (item.count > MAX_SUPPORTED_ITEMS) {
88             item.count = MAX_SUPPORTED_ITEMS;
89             METADATA_ERR_LOG("MetadataUtils::DecodeCameraMetadata item.count is more than supported value");
90         }
91         MetadataUtils::ReadMetadata(item, data);
92         items.push_back(item);
93     }
94 
95     metadata = std::make_shared<CameraMetadata>(itemCapacity, dataCapacity);
96     common_metadata_header_t *meta = metadata->get();
97     for (auto &item : items) {
98         void *buffer = nullptr;
99         MetadataUtils::ItemDataToBuffer(item, &buffer);
100         (void)AddCameraMetadataItem(meta, item.item, buffer, item.count);
101     }
102 }
103 
WriteMetadata(const camera_metadata_item_t & item,MessageParcel & data)104 bool MetadataUtils::WriteMetadata(const camera_metadata_item_t &item, MessageParcel &data)
105 {
106     bool bRet = false;
107     if (item.data_type == META_TYPE_BYTE) {
108         std::vector<uint8_t> buffers;
109         for (size_t i = 0; i < item.count; i++) {
110             buffers.push_back(*(item.data.u8 + i));
111         }
112         bRet = data.WriteUInt8Vector(buffers);
113     } else if (item.data_type == META_TYPE_INT32) {
114         std::vector<int32_t> buffers;
115         for (size_t i = 0; i < item.count; i++) {
116             buffers.push_back(*(item.data.i32 + i));
117         }
118         bRet = data.WriteInt32Vector(buffers);
119     } else if (item.data_type == META_TYPE_FLOAT) {
120         std::vector<float> buffers;
121         for (size_t i = 0; i < item.count; i++) {
122             buffers.push_back(*(item.data.f + i));
123         }
124         bRet = data.WriteFloatVector(buffers);
125     } else if (item.data_type == META_TYPE_UINT32) {
126         std::vector<uint32_t> buffers;
127         for (size_t i = 0; i < item.count; i++) {
128             buffers.push_back(*(item.data.ui32 + i));
129         }
130         bRet = data.WriteUInt32Vector(buffers);
131     } else if (item.data_type == META_TYPE_INT64) {
132         std::vector<int64_t> buffers;
133         for (size_t i = 0; i < item.count; i++) {
134             buffers.push_back(*(item.data.i64 + i));
135         }
136         bRet = data.WriteInt64Vector(buffers);
137     } else if (item.data_type == META_TYPE_DOUBLE) {
138         std::vector<double> buffers;
139         for (size_t i = 0; i < item.count; i++) {
140             buffers.push_back(*(item.data.d + i));
141         }
142         bRet = data.WriteDoubleVector(buffers);
143     } else if (item.data_type == META_TYPE_RATIONAL) {
144         std::vector<int32_t> buffers;
145         for (size_t i = 0; i < item.count; i++) {
146             buffers.push_back((*(item.data.r + i)).numerator);
147             buffers.push_back((*(item.data.r + i)).denominator);
148         }
149         bRet = data.WriteInt32Vector(buffers);
150     }
151 
152     return bRet;
153 }
154 
EncodeToString(std::shared_ptr<CameraMetadata> metadata)155 std::string MetadataUtils::EncodeToString(std::shared_ptr<CameraMetadata> metadata)
156 {
157     int32_t ret, dataLen;
158     const int32_t headerLength = sizeof(common_metadata_header_t);
159     const int32_t itemLen = sizeof(camera_metadata_item_entry_t);
160     const int32_t itemFixedLen = static_cast<int32_t>(offsetof(camera_metadata_item_entry_t, data));
161 
162     if (metadata == nullptr || metadata->get() == nullptr) {
163         METADATA_ERR_LOG("MetadataUtils::EncodeToString Metadata is invalid");
164         return {};
165     }
166 
167     common_metadata_header_t *meta = metadata->get();
168     std::string s(headerLength + (itemLen * meta->item_count) + meta->data_count, '\0');
169     char *encodeData = &s[0];
170     ret = memcpy_s(encodeData, headerLength, meta, headerLength);
171     if (ret != CAM_META_SUCCESS) {
172         METADATA_ERR_LOG("MetadataUtils::EncodeToString Failed to copy memory for metadata header");
173         return {};
174     }
175     encodeData += headerLength;
176     camera_metadata_item_entry_t *item = GetMetadataItems(meta);
177     for (uint32_t index = 0; index < meta->item_count; index++, item++) {
178         ret = memcpy_s(encodeData, itemFixedLen, item, itemFixedLen);
179         if (ret != CAM_META_SUCCESS) {
180             METADATA_ERR_LOG("MetadataUtils::EncodeToString Failed to copy memory for item fixed fields");
181             return {};
182         }
183         encodeData += itemFixedLen;
184         dataLen = itemLen - itemFixedLen;
185         ret = memcpy_s(encodeData, dataLen,  &(item->data), dataLen);
186         if (ret != CAM_META_SUCCESS) {
187             METADATA_ERR_LOG("MetadataUtils::EncodeToString Failed to copy memory for item data field");
188             return {};
189         }
190         encodeData += dataLen;
191     }
192 
193     if (meta->data_count != 0) {
194         ret = memcpy_s(encodeData, meta->data_count, GetMetadataData(meta), meta->data_count);
195         if (ret != CAM_META_SUCCESS) {
196             METADATA_ERR_LOG("MetadataUtils::EncodeToString Failed to copy memory for data");
197             return {};
198         }
199         encodeData += meta->data_count;
200     }
201     METADATA_DEBUG_LOG("MetadataUtils::EncodeToString Calculated length: %{public}d, encoded length: %{public}d",
202                        s.capacity(), (encodeData - &s[0]));
203 
204     return s;
205 }
206 
DecodeFromString(std::string setting)207 std::shared_ptr<CameraMetadata> MetadataUtils::DecodeFromString(std::string setting)
208 {
209     uint32_t ret, dataLen;
210     uint32_t totalLen = setting.capacity();
211     const uint32_t headerLength = sizeof(common_metadata_header_t);
212     const uint32_t itemLen = sizeof(camera_metadata_item_entry_t);
213     const uint32_t itemFixedLen = offsetof(camera_metadata_item_entry_t, data);
214 
215     if (totalLen < headerLength) {
216         METADATA_ERR_LOG("MetadataUtils::DecodeFromString Length is less than metadata header length");
217         return {};
218     }
219 
220     char *decodeData = &setting[0];
221     common_metadata_header_t header;
222     ret = memcpy_s(&header, headerLength, decodeData, headerLength);
223     if (ret != CAM_META_SUCCESS) {
224         METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed to copy memory for metadata header");
225         return {};
226     }
227     header.item_capacity = header.item_count;
228     header.data_capacity = header.data_count;
229     std::shared_ptr<CameraMetadata> metadata
230         = std::make_shared<CameraMetadata>(header.item_capacity, header.data_capacity);
231     common_metadata_header_t *meta = metadata->get();
232     ret = memcpy_s(meta, headerLength, &header, headerLength);
233     if (ret != CAM_META_SUCCESS) {
234         METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed to copy memory for metadata header");
235         return {};
236     }
237     decodeData += headerLength;
238     camera_metadata_item_entry_t *item = GetMetadataItems(meta);
239     for (uint32_t index = 0; index < meta->item_count; index++, item++) {
240         if (totalLen < ((decodeData - &setting[0]) + itemLen)) {
241             METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed at item index: %{public}d", index);
242             return {};
243         }
244         ret = memcpy_s(item, itemFixedLen, decodeData, itemFixedLen);
245         if (ret != CAM_META_SUCCESS) {
246             METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed to copy memory for item fixed fields");
247             return {};
248         }
249         decodeData += itemFixedLen;
250         dataLen = itemLen - itemFixedLen;
251         ret = memcpy_s(&(item->data), dataLen,  decodeData, dataLen);
252         if (ret != CAM_META_SUCCESS) {
253             METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed to copy memory for item data field");
254             return {};
255         }
256         decodeData += dataLen;
257     }
258 
259     if (meta->data_count != 0) {
260         if (totalLen < static_cast<uint32_t>(((decodeData - &setting[0]) + meta->data_count))) {
261             METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed at data copy");
262             return {};
263         }
264         ret = memcpy_s(GetMetadataData(meta), meta->data_count, decodeData, meta->data_count);
265         if (ret != CAM_META_SUCCESS) {
266             METADATA_ERR_LOG("MetadataUtils::DecodeFromString Failed to copy memory for data");
267             return {};
268         }
269         decodeData += meta->data_count;
270     }
271 
272     METADATA_DEBUG_LOG("MetadataUtils::DecodeFromString String length: %{public}d, Decoded length: %{public}d",
273                        setting.capacity(), (decodeData - &setting[0]));
274     return metadata;
275 }
276 
ReadMetadata(camera_metadata_item_t & item,MessageParcel & data)277 bool MetadataUtils::ReadMetadata(camera_metadata_item_t &item, MessageParcel &data)
278 {
279     if (item.data_type == META_TYPE_BYTE) {
280         std::vector<uint8_t> buffers;
281         data.ReadUInt8Vector(&buffers);
282         item.data.u8 = new(std::nothrow) uint8_t[item.count];
283         if (item.data.u8 != nullptr) {
284             for (size_t i = 0; i < item.count; i++) {
285                 item.data.u8[i] = buffers.at(i);
286             }
287         }
288     } else if (item.data_type == META_TYPE_INT32) {
289         std::vector<int32_t> buffers;
290         data.ReadInt32Vector(&buffers);
291         item.data.i32 = new(std::nothrow) int32_t[item.count];
292         if (item.data.i32 != nullptr) {
293             for (size_t i = 0; i < item.count; i++) {
294                 item.data.i32[i] = buffers.at(i);
295             }
296         }
297     } else if (item.data_type == META_TYPE_FLOAT) {
298         std::vector<float> buffers;
299         data.ReadFloatVector(&buffers);
300         item.data.f = new(std::nothrow) float[item.count];
301         if (item.data.f != nullptr) {
302             for (size_t i = 0; i < item.count; i++) {
303                 item.data.f[i] = buffers.at(i);
304             }
305         }
306     } else if (item.data_type == META_TYPE_UINT32) {
307         std::vector<uint32_t> buffers;
308         data.ReadUInt32Vector(&buffers);
309         item.data.ui32 = new(std::nothrow) uint32_t[item.count];
310         if (item.data.ui32 != nullptr) {
311             for (size_t i = 0; i < item.count; i++) {
312                 item.data.ui32[i] = buffers.at(i);
313             }
314         }
315     } else if (item.data_type == META_TYPE_INT64) {
316         std::vector<int64_t> buffers;
317         data.ReadInt64Vector(&buffers);
318         item.data.i64 = new(std::nothrow) int64_t[item.count];
319         if (item.data.i64 != nullptr) {
320             for (size_t i = 0; i < item.count; i++) {
321                 item.data.i64[i] = buffers.at(i);
322             }
323         }
324     } else if (item.data_type == META_TYPE_DOUBLE) {
325         std::vector<double> buffers;
326         data.ReadDoubleVector(&buffers);
327         item.data.d = new(std::nothrow) double[item.count];
328         if (item.data.d != nullptr) {
329             for (size_t i = 0; i < item.count; i++) {
330                 item.data.d[i] = buffers.at(i);
331             }
332         }
333     } else if (item.data_type == META_TYPE_RATIONAL) {
334         std::vector<int32_t> buffers;
335         data.ReadInt32Vector(&buffers);
336         item.data.r = new(std::nothrow) camera_rational_t[item.count];
337         if (item.data.r != nullptr) {
338             for (size_t i = 0, j = 0;
339                     i < item.count && j < static_cast<size_t>(buffers.size());
340                     i++, j += INDEX_COUNTER) {
341                 item.data.r[i].numerator = buffers.at(j);
342                 item.data.r[i].denominator = buffers.at(j + 1);
343             }
344         }
345     }
346     return true;
347 }
348 
ItemDataToBuffer(const camera_metadata_item_t & item,void ** buffer)349 void MetadataUtils::ItemDataToBuffer(const camera_metadata_item_t &item, void **buffer)
350 {
351     if (buffer == nullptr) {
352         METADATA_ERR_LOG("MetadataUtils::ItemDataToBuffer buffer is null");
353         return;
354     }
355     if (item.data_type == META_TYPE_BYTE) {
356         *buffer = (void*)item.data.u8;
357     } else if (item.data_type == META_TYPE_INT32) {
358         *buffer = (void*)item.data.i32;
359     } else if (item.data_type == META_TYPE_FLOAT) {
360         *buffer = (void*)item.data.f;
361     } else if (item.data_type == META_TYPE_UINT32) {
362         *buffer = (void*)item.data.ui32;
363     } else if (item.data_type == META_TYPE_INT64) {
364         *buffer = (void*)item.data.i64;
365     } else if (item.data_type == META_TYPE_DOUBLE) {
366         *buffer = (void*)item.data.d;
367     } else if (item.data_type == META_TYPE_RATIONAL) {
368         *buffer = (void*)item.data.r;
369     }
370 }
371 } // Camera
372