• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "image_utils.h"
17 #include <sys/stat.h>
18 #include <climits>
19 #include <cmath>
20 #include <cstdint>
21 #include <cstdlib>
22 #include "__config"
23 #include "__string"
24 #include "hilog/log_cpp.h"
25 #include "image_log.h"
26 #include "ios"
27 #include "istream"
28 #include "media_errors.h"
29 #include "new"
30 #include "plugin_server.h"
31 #include "singleton.h"
32 #include "string"
33 #include "type_traits"
34 #include "vector"
35 
36 namespace OHOS {
37 namespace Media {
38 using namespace OHOS::HiviewDFX;
39 using namespace std;
40 using namespace MultimediaPlugin;
41 
42 constexpr int32_t ALPHA8_BYTES = 1;
43 constexpr int32_t RGB565_BYTES = 2;
44 constexpr int32_t RGB888_BYTES = 3;
45 constexpr int32_t ARGB8888_BYTES = 4;
46 constexpr int32_t RGBA_F16_BYTES = 8;
47 constexpr int32_t NV21_BYTES = 2;  // Each pixel is sorted on 3/2 bytes.
48 constexpr float EPSILON = 1e-6;
49 constexpr int MAX_DIMENSION = INT32_MAX >> 2;
50 static bool g_pluginRegistered = false;
51 
GetFileSize(const string & pathName,size_t & size)52 bool ImageUtils::GetFileSize(const string &pathName, size_t &size)
53 {
54     if (pathName.empty()) {
55         IMAGE_LOGE("[ImageUtil]input parameter exception.");
56         return false;
57     }
58     struct stat statbuf;
59     int ret = stat(pathName.c_str(), &statbuf);
60     if (ret != 0) {
61         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d.", ret);
62         return false;
63     }
64     size = statbuf.st_size;
65     return true;
66 }
67 
GetFileSize(const int fd,size_t & size)68 bool ImageUtils::GetFileSize(const int fd, size_t &size)
69 {
70     struct stat statbuf;
71 
72     if (fd < 0) {
73         return false;
74     }
75 
76     int ret = fstat(fd, &statbuf);
77     if (ret != 0) {
78         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d.", ret);
79         return false;
80     }
81     size = statbuf.st_size;
82     return true;
83 }
84 
GetInputStreamSize(istream & inputStream,size_t & size)85 bool ImageUtils::GetInputStreamSize(istream &inputStream, size_t &size)
86 {
87     if (inputStream.rdbuf() == nullptr) {
88         IMAGE_LOGE("[ImageUtil]input parameter exception.");
89         return false;
90     }
91     size_t original = inputStream.tellg();
92     inputStream.seekg(0, ios_base::end);
93     size = inputStream.tellg();
94     inputStream.seekg(original);
95     return true;
96 }
97 
GetPixelBytes(const PixelFormat & pixelFormat)98 int32_t ImageUtils::GetPixelBytes(const PixelFormat &pixelFormat)
99 {
100     int pixelBytes = 0;
101     switch (pixelFormat) {
102         case PixelFormat::ARGB_8888:
103         case PixelFormat::BGRA_8888:
104         case PixelFormat::RGBA_8888:
105         case PixelFormat::CMYK:
106             pixelBytes = ARGB8888_BYTES;
107             break;
108         case PixelFormat::ALPHA_8:
109             pixelBytes = ALPHA8_BYTES;
110             break;
111         case PixelFormat::RGB_888:
112             pixelBytes = RGB888_BYTES;
113             break;
114         case PixelFormat::RGB_565:
115             pixelBytes = RGB565_BYTES;
116             break;
117         case PixelFormat::RGBA_F16:
118             pixelBytes = RGBA_F16_BYTES;
119             break;
120         case PixelFormat::NV21:
121         case PixelFormat::NV12:
122             pixelBytes = NV21_BYTES;  // perl pixel 1.5 Bytes but return int so return 2
123             break;
124         default:
125             IMAGE_LOGE("[ImageUtil]get pixel bytes failed, pixelFormat:%{public}d.", static_cast<int32_t>(pixelFormat));
126             break;
127     }
128     return pixelBytes;
129 }
130 
RegisterPluginServer()131 uint32_t ImageUtils::RegisterPluginServer()
132 {
133 #ifdef _WIN32
134     vector<string> pluginPaths = { "" };
135 #elif defined(_APPLE)
136     vector<string> pluginPaths = { "./" };
137 #else
138     vector<string> pluginPaths = { "/system/etc/multimediaplugin/image" };
139 #endif
140     PluginServer &pluginServer = DelayedRefSingleton<PluginServer>::GetInstance();
141     uint32_t result = pluginServer.Register(std::move(pluginPaths));
142     if (result != SUCCESS) {
143         IMAGE_LOGE("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
144     } else {
145         g_pluginRegistered = true;
146         IMAGE_LOGI("[ImageUtil]success to register plugin server");
147     }
148     return result;
149 }
150 
GetPluginServer()151 PluginServer& ImageUtils::GetPluginServer()
152 {
153     if (!g_pluginRegistered) {
154         uint32_t result = RegisterPluginServer();
155         if (result != SUCCESS) {
156             IMAGE_LOGI("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
157         }
158     }
159     return DelayedRefSingleton<PluginServer>::GetInstance();
160 }
161 
PathToRealPath(const string & path,string & realPath)162 bool ImageUtils::PathToRealPath(const string &path, string &realPath)
163 {
164     if (path.empty()) {
165         IMAGE_LOGE("path is empty!");
166         return false;
167     }
168 
169     if ((path.length() >= PATH_MAX)) {
170         IMAGE_LOGE("path len is error, the len is: [%{public}lu]", static_cast<unsigned long>(path.length()));
171         return false;
172     }
173 
174     char tmpPath[PATH_MAX] = { 0 };
175 
176 #ifdef _WIN32
177     if (_fullpath(tmpPath, path.c_str(), path.length()) == nullptr) {
178         IMAGE_LOGW("path to _fullpath error");
179     }
180 #else
181     if (realpath(path.c_str(), tmpPath) == nullptr) {
182         IMAGE_LOGE("path to realpath is nullptr");
183         return false;
184     }
185 #endif
186 
187     realPath = tmpPath;
188     return true;
189 }
190 
FloatCompareZero(float src)191 bool ImageUtils::FloatCompareZero(float src)
192 {
193     return fabs(src - 0) < EPSILON;
194 }
195 
GetValidAlphaTypeByFormat(const AlphaType & dstType,const PixelFormat & format)196 AlphaType ImageUtils::GetValidAlphaTypeByFormat(const AlphaType &dstType, const PixelFormat &format)
197 {
198     switch (format) {
199         case PixelFormat::RGBA_8888:
200         case PixelFormat::BGRA_8888:
201         case PixelFormat::ARGB_8888:
202         case PixelFormat::RGBA_F16: {
203             break;
204         }
205         case PixelFormat::ALPHA_8: {
206             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_PREMUL) {
207                 return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
208             }
209             break;
210         }
211         case PixelFormat::RGB_888:
212         case PixelFormat::RGB_565: {
213             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
214                 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
215             }
216             break;
217         }
218         case PixelFormat::NV21:
219         case PixelFormat::NV12:
220         case PixelFormat::CMYK:
221         default: {
222             HiLog::Error(LABEL, "GetValidAlphaTypeByFormat unsupport the format(%{public}d).", format);
223             return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
224         }
225     }
226     return dstType;
227 }
228 
IsValidImageInfo(const ImageInfo & info)229 bool ImageUtils::IsValidImageInfo(const ImageInfo &info)
230 {
231     if (info.size.width <= 0 || info.size.height <= 0 || info.size.width > MAX_DIMENSION ||
232         info.size.height > MAX_DIMENSION) {
233         HiLog::Error(LABEL, "width(%{public}d) or height(%{public}d) is invalid.", info.size.width, info.size.height);
234         return false;
235     }
236     if (info.pixelFormat == PixelFormat::UNKNOWN || info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
237         HiLog::Error(LABEL, "check pixelformat and alphatype is invalid.");
238         return false;
239     }
240     return true;
241 }
242 
CheckMulOverflow(int32_t width,int32_t bytesPerPixel)243 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t bytesPerPixel)
244 {
245     if (width == 0 || bytesPerPixel == 0) {
246         HiLog::Error(LABEL, "para is 0");
247         return true;
248     }
249     int64_t rowSize = static_cast<int64_t>(width) * bytesPerPixel;
250     if ((rowSize / width) != bytesPerPixel) {
251         HiLog::Error(LABEL, "width * bytesPerPixel overflow!");
252         return true;
253     }
254     return false;
255 }
256 
CheckMulOverflow(int32_t width,int32_t height,int32_t bytesPerPixel)257 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t height, int32_t bytesPerPixel)
258 {
259     if (width == 0 || height == 0 || bytesPerPixel == 0) {
260         HiLog::Error(LABEL, "para is 0");
261         return true;
262     }
263     int64_t rectSize = static_cast<int64_t>(width) * height;
264     if ((rectSize / width) != height) {
265         HiLog::Error(LABEL, "width * height overflow!");
266         return true;
267     }
268     int64_t bufferSize = rectSize * bytesPerPixel;
269     if ((bufferSize / bytesPerPixel) != rectSize) {
270         HiLog::Error(LABEL, "bytesPerPixel overflow!");
271         return true;
272     }
273     return false;
274 }
275 } // namespace Media
276 } // namespace OHOS
277