• 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 <string>
23 #include "__config"
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 #include "image_trace.h"
36 #include "hitrace_meter.h"
37 #if !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
38 #include "surface_buffer.h"
39 #else
40 #include "refbase.h"
41 #endif
42 
43 namespace OHOS {
44 namespace Media {
45 using namespace OHOS::HiviewDFX;
46 using namespace std;
47 using namespace MultimediaPlugin;
48 
49 constexpr int32_t ALPHA8_BYTES = 1;
50 constexpr int32_t RGB565_BYTES = 2;
51 constexpr int32_t RGB888_BYTES = 3;
52 constexpr int32_t ARGB8888_BYTES = 4;
53 constexpr int32_t RGBA_F16_BYTES = 8;
54 constexpr int32_t NV21_BYTES = 2;  // Each pixel is sorted on 3/2 bytes.
55 constexpr float EPSILON = 1e-6;
56 constexpr int MAX_DIMENSION = INT32_MAX >> 2;
57 static bool g_pluginRegistered = false;
58 static const uint8_t NUM_0 = 0;
59 static const uint8_t NUM_1 = 1;
60 static const uint8_t NUM_2 = 2;
61 static const uint8_t NUM_3 = 3;
62 static const uint8_t NUM_4 = 4;
63 
GetFileSize(const string & pathName,size_t & size)64 bool ImageUtils::GetFileSize(const string &pathName, size_t &size)
65 {
66     if (pathName.empty()) {
67         IMAGE_LOGE("[ImageUtil]input parameter exception.");
68         return false;
69     }
70     struct stat statbuf;
71     int ret = stat(pathName.c_str(), &statbuf);
72     if (ret != 0) {
73         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d.", ret);
74         return false;
75     }
76     size = statbuf.st_size;
77     return true;
78 }
79 
GetFileSize(const int fd,size_t & size)80 bool ImageUtils::GetFileSize(const int fd, size_t &size)
81 {
82     struct stat statbuf;
83 
84     if (fd < 0) {
85         return false;
86     }
87 
88     int ret = fstat(fd, &statbuf);
89     if (ret != 0) {
90         IMAGE_LOGE("[ImageUtil]get the file size failed, ret:%{public}d.", ret);
91         return false;
92     }
93     size = statbuf.st_size;
94     return true;
95 }
96 
GetInputStreamSize(istream & inputStream,size_t & size)97 bool ImageUtils::GetInputStreamSize(istream &inputStream, size_t &size)
98 {
99     if (inputStream.rdbuf() == nullptr) {
100         IMAGE_LOGE("[ImageUtil]input parameter exception.");
101         return false;
102     }
103     size_t original = inputStream.tellg();
104     inputStream.seekg(0, ios_base::end);
105     size = inputStream.tellg();
106     inputStream.seekg(original);
107     return true;
108 }
109 
GetPixelBytes(const PixelFormat & pixelFormat)110 int32_t ImageUtils::GetPixelBytes(const PixelFormat &pixelFormat)
111 {
112     int pixelBytes = 0;
113     switch (pixelFormat) {
114         case PixelFormat::ARGB_8888:
115         case PixelFormat::BGRA_8888:
116         case PixelFormat::RGBA_8888:
117         case PixelFormat::CMYK:
118             pixelBytes = ARGB8888_BYTES;
119             break;
120         case PixelFormat::ALPHA_8:
121             pixelBytes = ALPHA8_BYTES;
122             break;
123         case PixelFormat::RGB_888:
124             pixelBytes = RGB888_BYTES;
125             break;
126         case PixelFormat::RGB_565:
127             pixelBytes = RGB565_BYTES;
128             break;
129         case PixelFormat::RGBA_F16:
130             pixelBytes = RGBA_F16_BYTES;
131             break;
132         case PixelFormat::NV21:
133         case PixelFormat::NV12:
134             pixelBytes = NV21_BYTES;  // perl pixel 1.5 Bytes but return int so return 2
135             break;
136         default:
137             IMAGE_LOGE("[ImageUtil]get pixel bytes failed, pixelFormat:%{public}d.", static_cast<int32_t>(pixelFormat));
138             break;
139     }
140     return pixelBytes;
141 }
142 
RegisterPluginServer()143 uint32_t ImageUtils::RegisterPluginServer()
144 {
145 #ifdef _WIN32
146     vector<string> pluginPaths = { "" };
147 #elif defined(_APPLE)
148     vector<string> pluginPaths = { "./" };
149 #elif defined(A_PLATFORM) || defined(IOS_PLATFORM)
150     vector<string> pluginPaths = {};
151 #else
152     vector<string> pluginPaths = { "/system/etc/multimediaplugin/image" };
153 #endif
154     PluginServer &pluginServer = DelayedRefSingleton<PluginServer>::GetInstance();
155     uint32_t result = pluginServer.Register(std::move(pluginPaths));
156     if (result != SUCCESS) {
157         IMAGE_LOGE("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
158     } else {
159         g_pluginRegistered = true;
160         IMAGE_LOGI("[ImageUtil]success to register plugin server");
161     }
162     return result;
163 }
164 
GetPluginServer()165 PluginServer& ImageUtils::GetPluginServer()
166 {
167     if (!g_pluginRegistered) {
168         uint32_t result = RegisterPluginServer();
169         if (result != SUCCESS) {
170             IMAGE_LOGI("[ImageUtil]failed to register plugin server, ERRNO: %{public}u.", result);
171         }
172     }
173     return DelayedRefSingleton<PluginServer>::GetInstance();
174 }
175 
PathToRealPath(const string & path,string & realPath)176 bool ImageUtils::PathToRealPath(const string &path, string &realPath)
177 {
178     if (path.empty()) {
179         IMAGE_LOGE("path is empty!");
180         return false;
181     }
182 
183     if ((path.length() >= PATH_MAX)) {
184         IMAGE_LOGE("path len is error, the len is: [%{public}lu]", static_cast<unsigned long>(path.length()));
185         return false;
186     }
187 
188     char tmpPath[PATH_MAX] = { 0 };
189 
190 #ifdef _WIN32
191     if (_fullpath(tmpPath, path.c_str(), path.length()) == nullptr) {
192         IMAGE_LOGW("path to _fullpath error");
193     }
194 #else
195     if (realpath(path.c_str(), tmpPath) == nullptr) {
196         IMAGE_LOGE("path to realpath is nullptr");
197         return false;
198     }
199 #endif
200 
201     realPath = tmpPath;
202     return true;
203 }
204 
FloatCompareZero(float src)205 bool ImageUtils::FloatCompareZero(float src)
206 {
207     return fabs(src - 0) < EPSILON;
208 }
209 
GetValidAlphaTypeByFormat(const AlphaType & dstType,const PixelFormat & format)210 AlphaType ImageUtils::GetValidAlphaTypeByFormat(const AlphaType &dstType, const PixelFormat &format)
211 {
212     switch (format) {
213         case PixelFormat::RGBA_8888:
214         case PixelFormat::BGRA_8888:
215         case PixelFormat::ARGB_8888:
216         case PixelFormat::RGBA_F16: {
217             break;
218         }
219         case PixelFormat::ALPHA_8: {
220             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_PREMUL) {
221                 return AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
222             }
223             break;
224         }
225         case PixelFormat::RGB_888:
226         case PixelFormat::RGB_565: {
227             if (dstType != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
228                 return AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
229             }
230             break;
231         }
232         case PixelFormat::NV21:
233         case PixelFormat::NV12:
234         case PixelFormat::CMYK:
235         default: {
236             HiLog::Error(LABEL, "GetValidAlphaTypeByFormat unsupport the format(%{public}d).", format);
237             return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
238         }
239     }
240     return dstType;
241 }
242 
IsValidImageInfo(const ImageInfo & info)243 bool ImageUtils::IsValidImageInfo(const ImageInfo &info)
244 {
245     if (info.size.width <= 0 || info.size.height <= 0 || info.size.width > MAX_DIMENSION ||
246         info.size.height > MAX_DIMENSION) {
247         HiLog::Error(LABEL, "width(%{public}d) or height(%{public}d) is invalid.", info.size.width, info.size.height);
248         return false;
249     }
250     if (info.pixelFormat == PixelFormat::UNKNOWN || info.alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
251         HiLog::Error(LABEL, "check pixelformat and alphatype is invalid.");
252         return false;
253     }
254     return true;
255 }
256 
CheckMulOverflow(int32_t width,int32_t bytesPerPixel)257 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t bytesPerPixel)
258 {
259     if (width == 0 || bytesPerPixel == 0) {
260         HiLog::Error(LABEL, "para is 0");
261         return true;
262     }
263     int64_t rowSize = static_cast<int64_t>(width) * bytesPerPixel;
264     if ((rowSize / width) != bytesPerPixel) {
265         HiLog::Error(LABEL, "width * bytesPerPixel overflow!");
266         return true;
267     }
268     return false;
269 }
270 
CheckMulOverflow(int32_t width,int32_t height,int32_t bytesPerPixel)271 bool ImageUtils::CheckMulOverflow(int32_t width, int32_t height, int32_t bytesPerPixel)
272 {
273     if (width == 0 || height == 0 || bytesPerPixel == 0) {
274         HiLog::Error(LABEL, "para is 0");
275         return true;
276     }
277     int64_t rectSize = static_cast<int64_t>(width) * height;
278     if ((rectSize / width) != height) {
279         HiLog::Error(LABEL, "width * height overflow!");
280         return true;
281     }
282     int64_t bufferSize = rectSize * bytesPerPixel;
283     if ((bufferSize / bytesPerPixel) != rectSize) {
284         HiLog::Error(LABEL, "bytesPerPixel overflow!");
285         return true;
286     }
287     return false;
288 }
289 
ReversePixels(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)290 static void ReversePixels(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
291 {
292     if (byteCount % NUM_4 != NUM_0) {
293         HiLog::Error(LABEL, "Pixel count must multiple of 4.");
294         return;
295     }
296     uint8_t *src = srcPixels;
297     uint8_t *dst = dstPixels;
298     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
299         // 0-B 1-G 2-R 3-A
300         dst[NUM_0] = src[NUM_3];
301         dst[NUM_1] = src[NUM_2];
302         dst[NUM_2] = src[NUM_1];
303         dst[NUM_3] = src[NUM_0];
304         src += NUM_4;
305         dst += NUM_4;
306     }
307 }
308 
BGRAToARGB(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)309 void ImageUtils::BGRAToARGB(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
310 {
311     StartTrace(HITRACE_TAG_ZIMAGE, "BGRAToARGB");
312     ReversePixels(srcPixels, dstPixels, byteCount);
313     FinishTrace(HITRACE_TAG_ZIMAGE);
314 }
315 
ARGBToBGRA(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)316 void ImageUtils::ARGBToBGRA(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
317 {
318     ReversePixels(srcPixels, dstPixels, byteCount);
319 }
320 
SurfaceBuffer_Reference(void * buffer)321 int32_t ImageUtils::SurfaceBuffer_Reference(void* buffer)
322 {
323     if (buffer == nullptr) {
324         HiLog::Error(LABEL, "parameter error, please check input parameter");
325         return ERR_SURFACEBUFFER_REFERENCE_FAILED;
326     }
327     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
328     ref->IncStrongRef(ref);
329     return SUCCESS;
330 }
331 
SurfaceBuffer_Unreference(void * buffer)332 int32_t ImageUtils::SurfaceBuffer_Unreference(void* buffer)
333 {
334     if (buffer == nullptr) {
335         HiLog::Error(LABEL, "parameter error, please check input parameter");
336         return ERR_SURFACEBUFFER_UNREFERENCE_FAILED;
337     }
338     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
339     ref->DecStrongRef(ref);
340     return SUCCESS;
341 }
342 } // namespace Media
343 } // namespace OHOS
344