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 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 "picture_handle_client.h"
17
18 #include <cstdlib>
19 #include <fcntl.h>
20 #include <libexif/exif-entry.h>
21 #include <securec.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24
25 #include "exif_metadata.h"
26 #include "image_type.h"
27 #include "image_utils.h"
28 #include "medialibrary_db_const.h"
29 #include "medialibrary_errno.h"
30 #include "medialibrary_napi_utils.h"
31 #include "media_column.h"
32 #include "media_file_utils.h"
33 #include "media_log.h"
34 #include "pixel_yuv.h"
35 #include "pixel_yuv_ext.h"
36 #include "userfilemgr_uri.h"
37 #include "userfile_client.h"
38 #include <fstream>
39
40 namespace OHOS {
41 namespace Media {
42 const int32_t MAX_VALUE = 100000000;
RequestPicture(const int32_t & fileId)43 std::shared_ptr<Media::Picture> PictureHandlerClient::RequestPicture(const int32_t &fileId)
44 {
45 MEDIA_DEBUG_LOG("PictureHandlerClient::RequestPicture fileId: %{public}d", fileId);
46 std::string uri = PhotoColumn::PHOTO_REQUEST_PICTURE;
47 MediaFileUtils::UriAppendKeyValue(uri, MediaColumn::MEDIA_ID, std::to_string(fileId));
48 Uri requestUri(uri);
49 int32_t fd = UserFileClient::OpenFile(requestUri, MEDIA_FILEMODE_READONLY);
50 if (fd < 0) {
51 MEDIA_DEBUG_LOG("PictureHandlerClient::RequestPicture picture not exist");
52 return nullptr;
53 }
54 std::shared_ptr<Media::Picture> picture = nullptr;
55 ReadPicture(fd, fileId, picture);
56 FinishRequestPicture(fileId);
57 close(fd);
58 return picture;
59 }
60
FinishRequestPicture(const int32_t & fileId)61 void PictureHandlerClient::FinishRequestPicture(const int32_t &fileId)
62 {
63 MEDIA_DEBUG_LOG("PictureHandlerClient::FinishRequestPicture fileId: %{public}d", fileId);
64 std::string uri = PAH_FINISH_REQUEST_PICTURE;
65 MediaLibraryNapiUtils::UriAppendKeyValue(uri, API_VERSION, std::to_string(MEDIA_API_VERSION_V10));
66 Uri finishRequestPictureUri(uri);
67
68 DataShare::DataShareValuesBucket valuesBucket;
69 valuesBucket.Put(PhotoColumn::MEDIA_ID, fileId);
70 UserFileClient::Insert(finishRequestPictureUri, valuesBucket);
71 }
72
ReadPicture(const int32_t & fd,const int32_t & fileId,std::shared_ptr<Media::Picture> & picture)73 int32_t PictureHandlerClient::ReadPicture(const int32_t &fd, const int32_t &fileId,
74 std::shared_ptr<Media::Picture> &picture)
75 {
76 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture fd: %{public}d", fd);
77 // 获取消息总长度
78 void *msgLenAddr = mmap(nullptr, UINT32_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
79 if (msgLenAddr == MAP_FAILED || msgLenAddr == nullptr) {
80 MEDIA_ERR_LOG("PictureHandlerClient::ReadPicture mmap msgLenAddr failed!");
81 close(fd);
82 return E_ERR;
83 }
84 uint32_t msgLen = *((uint32_t*)msgLenAddr);
85 munmap(msgLenAddr, UINT32_LEN);
86 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture msgLen: %{public}d", msgLen);
87
88 // 获取消息
89 uint8_t *addr = (uint8_t*)mmap(nullptr, msgLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
90 if (addr == MAP_FAILED || addr == nullptr) {
91 MEDIA_ERR_LOG("PictureHandlerClient::ReadPicture mmap addr failed!");
92 close(fd);
93 return E_ERR;
94 }
95 uint32_t readoffset = UINT32_LEN;
96
97 // 读取dataSize
98 uint32_t dataSize = *reinterpret_cast<const uint32_t*>(addr + readoffset);
99 readoffset += UINT32_LEN;
100 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture dataSize: %{public}d", dataSize);
101 if (dataSize == 0) {
102 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture picture is not exists");
103 munmap(addr, msgLen);
104 return E_NO_SUCH_FILE;
105 }
106
107 // 读取auxiliaryPictureSize
108 uint32_t auxiliaryPictureSize = *reinterpret_cast<const uint32_t*>(addr + readoffset);
109 readoffset += UINT32_LEN;
110 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture auxiliaryPictureSize: %{public}d",
111 auxiliaryPictureSize);
112 uint8_t *pictureParcelData = static_cast<uint8_t *>(malloc(dataSize));
113 if (pictureParcelData == nullptr) {
114 munmap(addr, msgLen);
115 return E_ERR;
116 }
117 if (memcpy_s((void*)pictureParcelData, dataSize, addr+readoffset, dataSize)) {
118 MEDIA_ERR_LOG("PictureHandlerService::ReadPicture memcpy_s pictureParcel failed!");
119 free(pictureParcelData);
120 munmap(addr, msgLen);
121 return E_ERR;
122 }
123 MessageParcel pictureParcel;
124 if (!pictureParcel.ParseFrom(reinterpret_cast<uintptr_t>(pictureParcelData), dataSize)) {
125 MEDIA_ERR_LOG("pictureParcel parse failed!");
126 free(pictureParcelData);
127 return E_ERR;
128 }
129
130 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture read mainPixelMap");
131 std::shared_ptr<PixelMap> mainPixelMap = ReadPixelMap(pictureParcel);
132 std::unique_ptr<Media::Picture> picturePtr = Picture::Create(mainPixelMap);
133 if (picturePtr == nullptr) {
134 MEDIA_ERR_LOG("PictureHandlerService::ReadPicture picturePtr is nullptr!");
135 munmap(addr, msgLen);
136 return E_ERR;
137 }
138
139 ReadExifMetadata(pictureParcel, picturePtr);
140 ReadMaintenanceData(pictureParcel, picturePtr);
141
142 for (size_t i = 1; i <= auxiliaryPictureSize; i++) {
143 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture read auxiliaryPicture, index:%{public}zu", i);
144 ReadAuxiliaryPicture(pictureParcel, picturePtr);
145 }
146 picture.reset(picturePtr.get());
147 picturePtr.release();
148 munmap(addr, msgLen);
149 return E_OK;
150 }
151
ReadPixelMap(MessageParcel & data)152 std::shared_ptr<PixelMap> PictureHandlerClient::ReadPixelMap(MessageParcel &data)
153 {
154 ImageInfo imageInfo;
155 ReadImageInfo(data, imageInfo);
156
157 bool isYuv = data.ReadBool();
158 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap isYuv:%{public}d", isYuv);
159 YUVDataInfo yuvInfo;
160 if (isYuv) {
161 ReadYuvDataInfo(data, yuvInfo);
162 }
163
164 bool editable = data.ReadBool();
165 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap editable:%{public}d", editable);
166
167 std::unique_ptr<PixelMap> pixelMap;
168 if (isYuv) {
169 #ifdef EXT_PIXEL
170 pixelMap = std::make_unique<PixelYuvExt>();
171 #else
172 pixelMap = std::make_unique<PixelYuv>();
173 #endif
174 } else {
175 pixelMap = std::make_unique<PixelMap>();
176 }
177 pixelMap->SetImageInfo(imageInfo);
178 pixelMap->SetImageYUVInfo(yuvInfo);
179
180 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap read surface buffer");
181 ReadSurfaceBuffer(data, pixelMap);
182
183 return pixelMap;
184 }
185
ReadAuxiliaryPicture(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)186 bool PictureHandlerClient::ReadAuxiliaryPicture(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
187 {
188 AuxiliaryPictureInfo auxiliaryPictureInfo;
189 ReadAuxiliaryPictureInfo(data, auxiliaryPictureInfo);
190
191 std::shared_ptr<PixelMap> pixelMap = ReadPixelMap(data);
192 std::unique_ptr<AuxiliaryPicture> uptr = AuxiliaryPicture::Create(pixelMap,
193 auxiliaryPictureInfo.auxiliaryPictureType, auxiliaryPictureInfo.size);
194 std::shared_ptr<AuxiliaryPicture> auxiliaryPicture;
195 auxiliaryPicture.reset(uptr.get());
196 uptr.release();
197
198 auxiliaryPicture->SetAuxiliaryPictureInfo(auxiliaryPictureInfo);
199
200 int32_t metadataSize = 0;
201 if (data.ReadInt32(metadataSize) && metadataSize >= 0 && metadataSize < MAX_VALUE) {
202 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPicture metadataSize: %{public}d", metadataSize);
203 for (int i = 0; i < metadataSize; i++) {
204 MetadataType type = static_cast<MetadataType>(data.ReadInt32());
205 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPicture type: %{public}d", type);
206 std::shared_ptr<ImageMetadata> metadataPtr(nullptr);
207 metadataPtr.reset(ExifMetadata::Unmarshalling(data));
208 auxiliaryPicture->SetMetadata(type, metadataPtr);
209 }
210 } else {
211 MEDIA_ERR_LOG("PictureHandlerClient::ReadAuxiliaryPicture metadataSize failed");
212 }
213 picture->SetAuxiliaryPicture(auxiliaryPicture);
214 MEDIA_DEBUG_LOG("PictureHandler::ReadAuxiliaryPicture end");
215 return true;
216 }
217
ReadAuxiliaryPictureInfo(MessageParcel & data,AuxiliaryPictureInfo & auxiliaryPictureInfo)218 bool PictureHandlerClient::ReadAuxiliaryPictureInfo(MessageParcel &data, AuxiliaryPictureInfo &auxiliaryPictureInfo)
219 {
220 auxiliaryPictureInfo.auxiliaryPictureType = static_cast<AuxiliaryPictureType>(data.ReadInt32());
221 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo auxiliaryPictureType: %{public}d",
222 auxiliaryPictureInfo.auxiliaryPictureType);
223
224 auxiliaryPictureInfo.colorSpace = static_cast<ColorSpace>(data.ReadInt32());
225 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo colorSpace: %{public}d",
226 auxiliaryPictureInfo.colorSpace);
227
228 auxiliaryPictureInfo.pixelFormat = static_cast<PixelFormat>(data.ReadInt32());
229 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo pixelFormat: %{public}d",
230 auxiliaryPictureInfo.pixelFormat);
231
232 auxiliaryPictureInfo.rowStride = static_cast<uint32_t>(data.ReadInt32());
233 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo rowStride: %{public}d",
234 auxiliaryPictureInfo.rowStride);
235
236 auxiliaryPictureInfo.size.height = data.ReadInt32();
237 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo height: %{public}d",
238 auxiliaryPictureInfo.size.height);
239
240 auxiliaryPictureInfo.size.width = data.ReadInt32();
241 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo width: %{public}d",
242 auxiliaryPictureInfo.size.width);
243
244 return true;
245 }
246
ReadImageInfo(MessageParcel & data,ImageInfo & imageInfo)247 bool PictureHandlerClient::ReadImageInfo(MessageParcel &data, ImageInfo &imageInfo)
248 {
249 imageInfo.size.width = data.ReadInt32();
250 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo width: %{public}d", imageInfo.size.width);
251 imageInfo.size.height = data.ReadInt32();
252 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo height: %{public}d", imageInfo.size.height);
253 imageInfo.pixelFormat = static_cast<PixelFormat>(data.ReadInt32());
254 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo pixelFormat: %{public}d", imageInfo.pixelFormat);
255 imageInfo.colorSpace = static_cast<ColorSpace>(data.ReadInt32());
256 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo colorSpace: %{public}d", imageInfo.colorSpace);
257 imageInfo.alphaType = static_cast<AlphaType>(data.ReadInt32());
258 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo alphaType: %{public}d", imageInfo.alphaType);
259 imageInfo.baseDensity = data.ReadInt32();
260 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo baseDensity: %{public}d", imageInfo.baseDensity);
261 return true;
262 }
263
ReadYuvDataInfo(MessageParcel & data,YUVDataInfo & info)264 bool PictureHandlerClient::ReadYuvDataInfo(MessageParcel &data, YUVDataInfo &info)
265 {
266 info.imageSize.width = data.ReadInt32();
267 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo width: %{public}d", info.imageSize.width);
268 info.imageSize.height = data.ReadInt32();
269 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo height: %{public}d", info.imageSize.height);
270 info.yWidth = data.ReadUint32();
271 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yWidth: %{public}d", info.yWidth);
272 info.yHeight = data.ReadUint32();
273 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yHeight: %{public}d", info.yHeight);
274 info.uvWidth = data.ReadUint32();
275 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvWidth: %{public}d", info.uvWidth);
276 info.uvHeight = data.ReadUint32();
277 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvHeight: %{public}d", info.uvHeight);
278 info.yStride = data.ReadUint32();
279 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yStride: %{public}d", info.yStride);
280 info.uStride = data.ReadUint32();
281 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uStride: %{public}d", info.uStride);
282 info.vStride = data.ReadUint32();
283 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo vStride: %{public}d", info.vStride);
284 info.uvStride = data.ReadUint32();
285 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvStride: %{public}d", info.uvStride);
286 info.yOffset = data.ReadUint32();
287 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yOffset: %{public}d", info.yOffset);
288 info.uOffset = data.ReadUint32();
289 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uOffset: %{public}d", info.uOffset);
290 info.vOffset = data.ReadUint32();
291 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo vOffset: %{public}d", info.vOffset);
292 info.uvOffset = data.ReadUint32();
293 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvOffset: %{public}d", info.uvOffset);
294 return true;
295 }
296
ReadSurfaceBuffer(MessageParcel & data,std::unique_ptr<PixelMap> & pixelMap)297 bool PictureHandlerClient::ReadSurfaceBuffer(MessageParcel &data, std::unique_ptr<PixelMap> &pixelMap)
298 {
299 bool hasBufferHandle = data.ReadBool();
300 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadSurfaceBuffer hasBufferHandle: %{public}d", hasBufferHandle);
301 if (!hasBufferHandle) {
302 return false;
303 }
304 sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
305 ReadBufferHandle(data, surfaceBuffer);
306 void* nativeBuffer = surfaceBuffer.GetRefPtr();
307 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(nativeBuffer);
308 ref->IncStrongRef(ref);
309 pixelMap->SetPixelsAddr(static_cast<uint8_t*>(surfaceBuffer->GetVirAddr()), nativeBuffer,
310 pixelMap->GetByteCount(), AllocatorType::DMA_ALLOC, nullptr);
311 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadSurfaceBuffer end");
312 return true;
313 }
314
ReadBufferHandle(MessageParcel & data,sptr<SurfaceBuffer> & surfaceBuffer)315 bool PictureHandlerClient::ReadBufferHandle(MessageParcel &data, sptr<SurfaceBuffer> &surfaceBuffer)
316 {
317 uint32_t reserveFds = 0;
318 bool readReserveFdsRet = data.ReadUint32(reserveFds);
319 if (reserveFds < 0 || reserveFds > static_cast<uint32_t>(MAX_VALUE)) {
320 return false;
321 }
322 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserveFds: %{public}d", reserveFds);
323 uint32_t reserveInts = 0;
324 bool reserveIntsRet = data.ReadUint32(reserveInts);
325 if (reserveInts < 0 || reserveInts > static_cast<uint32_t>(MAX_VALUE)) {
326 return false;
327 }
328 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserveInts: %{public}d", reserveInts);
329
330 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
331 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
332 if (handle == nullptr) {
333 MEDIA_ERR_LOG("PictureHandlerClient::ReadBufferHandle malloc BufferHandle failed");
334 return false;
335 }
336 memset_s(handle, handleSize, 0, handleSize);
337
338 handle->reserveFds = reserveFds;
339 handle->reserveInts = reserveInts;
340 handle->width = data.ReadInt32();
341 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle width: %{public}d", handle->width);
342 handle->stride = data.ReadInt32();
343 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle stride: %{public}d", handle->stride);
344 handle->height = data.ReadInt32();
345 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle height: %{public}d", handle->height);
346 handle->size = data.ReadInt32();
347 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle size: %{public}d", handle->size);
348 handle->format = data.ReadInt32();
349 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle format: %{public}d", handle->format);
350 handle->usage = data.ReadUint64();
351 handle->phyAddr = data.ReadUint64();
352
353 int32_t fd = RequestBufferHandlerFd(data.ReadInt32());
354 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle fd: %{public}d", fd);
355 handle->fd = dup(fd);
356 close(fd);
357 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle handle->fd: %{public}d", handle->fd);
358 if (readReserveFdsRet) {
359 for (uint32_t i = 0; i < reserveFds; i++) {
360 int32_t reserveFd = RequestBufferHandlerFd(data.ReadInt32());
361 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserve[%{public}d]: %{public}d", i, reserveFd);
362 handle->reserve[i] = dup(reserveFd);
363 close(reserveFd);
364 }
365 }
366
367 if (reserveIntsRet) {
368 for (uint32_t j = 0; j < handle->reserveInts; j++) {
369 handle->reserve[reserveFds + j] = data.ReadInt32();
370 }
371 }
372 surfaceBuffer->SetBufferHandle(handle);
373 return true;
374 }
375
ReadExifMetadata(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)376 bool PictureHandlerClient::ReadExifMetadata(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
377 {
378 bool hasExifMetadata = data.ReadBool();
379 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadExifMetadata hasExifMetadata:%{public}d", hasExifMetadata);
380 if (!hasExifMetadata) {
381 return true;
382 }
383 ExifMetadata *exifMetadataPtr = ExifMetadata::Unmarshalling(data);
384 auto exifMetadata = std::shared_ptr<ExifMetadata>(exifMetadataPtr);
385 picture->SetExifMetadata(exifMetadata);
386 return true;
387 }
388
ReadMaintenanceData(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)389 bool PictureHandlerClient::ReadMaintenanceData(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
390 {
391 bool hasMaintenanceData = data.ReadBool();
392 MEDIA_DEBUG_LOG("PictureHandlerClient::ReadMaintenanceData hasMaintenanceData:%{public}d", hasMaintenanceData);
393 if (!hasMaintenanceData) {
394 return true;
395 }
396 sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
397 ReadBufferHandle(data, surfaceBuffer);
398 return picture->SetMaintenanceData(surfaceBuffer);
399 }
400
RequestBufferHandlerFd(const int32_t & fd)401 int32_t PictureHandlerClient::RequestBufferHandlerFd(const int32_t &fd)
402 {
403 std::string uri = PhotoColumn::PHOTO_REQUEST_PICTURE_BUFFER;
404 MediaFileUtils::UriAppendKeyValue(uri, "fd", std::to_string(fd));
405 MEDIA_DEBUG_LOG("PictureHandlerClient::RequestBufferHandlerFd uri: %{public}s", uri.c_str());
406 Uri requestUri(uri);
407 return UserFileClient::OpenFile(requestUri, MEDIA_FILEMODE_READONLY);
408 }
409 }
410 }