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