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