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