1 /*
2  * Copyright (C) 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 <fstream>
17 #include <string>
18 #include "directory_ex.h"
19 #include "image_log.h"
20 #include "image_packer.h"
21 #include "image_type.h"
22 #include "image_utils.h"
23 #include "media_errors.h"
24 #include "pixel_map.h"
25 #include "image_source_util.h"
26 
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
29 
30 #undef LOG_TAG
31 #define LOG_TAG "ImageSourceUtil"
32 
33 using namespace OHOS::Media;
34 using namespace OHOS::ImageSourceUtil;
35 
36 namespace OHOS {
37 namespace ImageSourceUtil {
38 constexpr uint32_t NUM_1 = 1;
39 constexpr uint32_t NUM_100 = 100;
40 constexpr int64_t BUFFER_SIZE = 2 * 1024 * 1024;
41 
PackImage(const std::string & filePath,std::unique_ptr<PixelMap> pixelMap)42 int64_t PackImage(const std::string &filePath, std::unique_ptr<PixelMap> pixelMap)
43 {
44     ImagePacker imagePacker;
45     PackOption option;
46     option.format = "image/jpeg";
47     option.quality = NUM_100;
48     option.numberHint = NUM_1;
49     std::set<std::string> formats;
50     if (pixelMap == nullptr) {
51         IMAGE_LOGE("pixelMap is nullptr");
52         return 0;
53     }
54     uint32_t ret = imagePacker.GetSupportedFormats(formats);
55     if (ret != SUCCESS) {
56         IMAGE_LOGE("image packer get supported format failed, ret=%{public}u.", ret);
57         return 0;
58     }
59     imagePacker.StartPacking(filePath, option);
60     imagePacker.AddImage(*pixelMap);
61     int64_t packedSize = 0;
62     imagePacker.FinalizePacking(packedSize);
63     return static_cast<int64_t>(packedSize);
64 }
65 
PackImage(std::unique_ptr<ImageSource> imageSource)66 int64_t PackImage(std::unique_ptr<ImageSource> imageSource)
67 {
68     ImagePacker imagePacker;
69     PackOption option;
70     option.format = "image/jpeg";
71     option.quality = NUM_100;
72     option.numberHint = 1;
73     std::set<std::string> formats;
74     if (imageSource == nullptr) {
75         IMAGE_LOGE("imageSource is nullptr");
76         return 0;
77     }
78     uint32_t ret = imagePacker.GetSupportedFormats(formats);
79     if (ret != SUCCESS) {
80         IMAGE_LOGE("image packer get supported format failed, ret=%{public}u.", ret);
81         return 0;
82     }
83     int64_t bufferSize = BUFFER_SIZE;
84     uint8_t *resultBuffer = reinterpret_cast<uint8_t *>(malloc(bufferSize));
85     if (resultBuffer == nullptr) {
86         IMAGE_LOGE("image packer malloc buffer failed.");
87         return 0;
88     }
89     imagePacker.StartPacking(resultBuffer, bufferSize, option);
90     imagePacker.AddImage(*imageSource);
91     int64_t packedSize = 0;
92     imagePacker.FinalizePacking(packedSize);
93     return static_cast<int64_t>(packedSize);
94 }
95 
PackImage(const std::string & filePath,std::unique_ptr<std::vector<std::unique_ptr<OHOS::Media::PixelMap>>> pixelMaps)96 int64_t PackImage(const std::string &filePath,
97                   std::unique_ptr<std::vector<std::unique_ptr<OHOS::Media::PixelMap>>> pixelMaps)
98 {
99     ImagePacker imagePacker;
100     PackOption option;
101     option.format = "image/gif";
102     option.quality = NUM_100;
103     option.numberHint = NUM_1;
104     std::set<std::string> formats;
105     if (pixelMaps == nullptr) {
106         IMAGE_LOGE("pixelMap is nullptr");
107         return 0;
108     }
109     uint32_t ret = imagePacker.GetSupportedFormats(formats);
110     if (ret != SUCCESS) {
111         IMAGE_LOGE("image packer get supported format failed, ret=%{public}u.", ret);
112         return 0;
113     }
114     imagePacker.StartPacking(filePath, option);
115     for (auto &pixelMap : *pixelMaps.get()) {
116         imagePacker.AddImage(*(pixelMap.get()));
117     }
118     int64_t packedSize = 0;
119     imagePacker.FinalizePacking(packedSize);
120     return static_cast<int64_t>(packedSize);
121 }
122 
ReadFileToBuffer(const std::string & filePath,uint8_t * buffer,size_t bufferSize)123 bool ReadFileToBuffer(const std::string &filePath, uint8_t *buffer, size_t bufferSize)
124 {
125     std::string realPath;
126     if (!OHOS::PathToRealPath(filePath, realPath)) {
127         IMAGE_LOGE("file path to real path failed, file path=%{public}s.", filePath.c_str());
128         return false;
129     }
130 
131     if (buffer == nullptr) {
132         IMAGE_LOGE("buffer is nullptr");
133         return false;
134     }
135 
136     FILE *fp = fopen(realPath.c_str(), "rb");
137     if (fp == nullptr) {
138         IMAGE_LOGE("open file failed, real path=%{public}s.", realPath.c_str());
139         return false;
140     }
141     fseek(fp, 0, SEEK_END);
142     size_t fileSize = ftell(fp);
143     fseek(fp, 0, SEEK_SET);
144     if (bufferSize < fileSize) {
145         IMAGE_LOGE("buffer size:(%{public}zu) is smaller than file size:(%{public}zu).", bufferSize, fileSize);
146         fclose(fp);
147         return false;
148     }
149     size_t retSize = fread(buffer, 1, fileSize, fp);
150     if (retSize != fileSize) {
151         IMAGE_LOGE("read file result size = %{public}zu, size = %{public}zu.", retSize, fileSize);
152         fclose(fp);
153         return false;
154     }
155     int ret = fclose(fp);
156     if (ret != 0) {
157         return true;
158     }
159     return true;
160 }
161 } // namespace ImageSourceUtil
162 } // namespace OHOS
163