• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "ans_image_util.h"
16 #include "ans_log_wrapper.h"
17 #include "image_packer.h"
18 #include "image_source.h"
19 
20 namespace OHOS {
21 namespace Notification {
22 const std::string AnsImageUtil::IMAGE_FORMAT_JPEG {"image/jpeg"};
23 const uint8_t AnsImageUtil::IMAGE_QUALITY {100};
24 const uint8_t AnsImageUtil::SHIFT_FOUR {4};
25 const uint8_t AnsImageUtil::NUM_TEN {10};
26 const size_t  AnsImageUtil::TWO_TIMES {2};
27 
PackImage(const std::shared_ptr<Media::PixelMap> & pixelMap,const std::string & format)28 std::string AnsImageUtil::PackImage(const std::shared_ptr<Media::PixelMap> &pixelMap, const std::string &format)
29 {
30     if (!pixelMap || format.empty()) {
31         ANS_LOGW("invalid parameters");
32         return {};
33     }
34 
35     Media::ImagePacker imagePacker;
36     Media::PackOption option;
37     option.format     = format;
38     option.quality    = IMAGE_QUALITY;
39     option.numberHint = 1;
40 
41     std::set<std::string> formats;
42     auto ret = imagePacker.GetSupportedFormats(formats);
43     if (ret) {
44         ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret);
45         return {};
46     }
47 
48     auto size = static_cast<uint32_t>(pixelMap->GetByteCount());
49     ANS_LOGI("size of pixelMap : %{public}u", size);
50     auto pbuf = new (std::nothrow) uint8_t [size];
51     if (pbuf == nullptr) {
52         ANS_LOGE("create buffer failed");
53         return {};
54     }
55 
56     imagePacker.StartPacking(pbuf, size, option);
57     imagePacker.AddImage(*pixelMap);
58     int64_t packedSize {0};
59     imagePacker.FinalizePacking(packedSize);
60     ANS_LOGI("packed size : %{public}" PRId64, packedSize);
61 
62     std::string pixelMapStr(reinterpret_cast<char*>(pbuf), static_cast<size_t>(packedSize));
63     delete [] pbuf;
64     pbuf = nullptr;
65 
66     return BinToHex(pixelMapStr);
67 }
68 
UnPackImage(const std::string & pixelMapStr)69 std::shared_ptr<Media::PixelMap> AnsImageUtil::UnPackImage(const std::string &pixelMapStr)
70 {
71     if (pixelMapStr.empty()) {
72         return {};
73     }
74 
75     auto binStr = HexToBin(pixelMapStr);
76 
77     uint32_t errorCode {0};
78     Media::SourceOptions opts;
79     auto imageSource = Media::ImageSource::CreateImageSource(
80         reinterpret_cast<const uint8_t*>(binStr.data()),
81         static_cast<uint32_t>(binStr.length()),
82         opts, errorCode);
83     if (errorCode || !imageSource) {
84         ANS_LOGE("create imageSource failed");
85         return {};
86     }
87 
88     Media::DecodeOptions decodeOpts;
89     auto pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
90     if (errorCode || !pixelMap) {
91         ANS_LOGE("create pixelMap failed");
92         return {};
93     }
94 
95     return pixelMap;
96 }
97 
PackImage2File(const std::shared_ptr<Media::PixelMap> & pixelMap,const std::string & outFilePath,const std::string & format)98 bool AnsImageUtil::PackImage2File(
99     const std::shared_ptr<Media::PixelMap> &pixelMap,
100     const std::string &outFilePath,
101     const std::string &format)
102 {
103     if (!pixelMap || outFilePath.empty() || format.empty()) {
104         ANS_LOGW("invalid parameters");
105         return false;
106     }
107 
108     Media::ImagePacker imagePacker;
109     Media::PackOption option;
110     option.format     = format;
111     option.quality    = IMAGE_QUALITY;
112     option.numberHint = 1;
113 
114     std::set<std::string> formats;
115     auto ret = imagePacker.GetSupportedFormats(formats);
116     if (ret) {
117         ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret);
118         return false;
119     }
120 
121     imagePacker.StartPacking(outFilePath, option);
122     imagePacker.AddImage(*pixelMap);
123     int64_t packedSize {0};
124     imagePacker.FinalizePacking(packedSize);
125     ANS_LOGI("packed size : %{public}" PRId64, packedSize);
126     return true;
127 }
128 
CreatePixelMap(const std::string & inFilePath,const std::string & format)129 std::shared_ptr<Media::PixelMap> AnsImageUtil::CreatePixelMap(const std::string &inFilePath, const std::string &format)
130 {
131     if (inFilePath.empty() || format.empty()) {
132         ANS_LOGW("invalid parameters");
133         return {};
134     }
135 
136     uint32_t errorCode {0};
137     Media::SourceOptions opts;
138     opts.formatHint = format;
139     auto imageSource = Media::ImageSource::CreateImageSource(inFilePath, opts, errorCode);
140     if (errorCode || !imageSource) {
141         ANS_LOGE("create imageSource failed");
142         return {};
143     }
144 
145     std::set<std::string> formats;
146     auto ret = imageSource->GetSupportedFormats(formats);
147     if (ret) {
148         ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret);
149         return {};
150     }
151 
152     Media::DecodeOptions decodeOpts;
153     auto pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
154     if (errorCode || !pixelMap) {
155         ANS_LOGE("create pixelMap failed");
156         return {};
157     }
158 
159     return pixelMap;
160 }
161 
BinToHex(const std::string & strBin)162 std::string AnsImageUtil::BinToHex(const std::string &strBin)
163 {
164     if (strBin.empty()) {
165         return {};
166     }
167 
168     std::string strHex;
169     strHex.resize(strBin.size() * TWO_TIMES);
170     for (size_t i = 0; i < strBin.size(); i++) {
171         uint8_t cTemp = strBin[i];
172         for (size_t j = 0; j < TWO_TIMES; j++) {
173             uint8_t cCur = (cTemp & 0x0f);
174             if (cCur < NUM_TEN) {
175                 cCur += '0';
176             } else {
177                 cCur += ('a' - NUM_TEN);
178             }
179             strHex[TWO_TIMES * i + 1 - j] = cCur;
180             cTemp >>= SHIFT_FOUR;
181         }
182     }
183 
184     return strHex;
185 }
186 
HexToBin(const std::string & strHex)187 std::string AnsImageUtil::HexToBin(const std::string &strHex)
188 {
189     if (strHex.size() % TWO_TIMES != 0) {
190         return {};
191     }
192 
193     std::string strBin;
194     strBin.resize(strHex.size() / TWO_TIMES);
195     for (size_t i = 0; i < strBin.size(); i++) {
196         uint8_t cTemp = 0;
197         for (size_t j = 0; j < TWO_TIMES; j++) {
198             char cCur = strHex[TWO_TIMES * i + j];
199             uint8_t value = static_cast<uint8_t>(cTemp << SHIFT_FOUR);
200             if (cCur >= '0' && cCur <= '9') {
201                 value = value + static_cast<uint8_t>(cCur - '0');
202             } else if (cCur >= 'a' && cCur <= 'f') {
203                 value = value + static_cast<uint8_t>(cCur - 'a' + NUM_TEN);
204             } else if (cCur >= 'A' && cCur <= 'F') {
205                 value = value + static_cast<uint8_t>(cCur - 'A' + NUM_TEN);
206             } else {
207                 return {};
208             }
209             cTemp = static_cast<uint8_t>(value);
210         }
211         strBin[i] = cTemp;
212     }
213 
214     return strBin;
215 }
216 }  // namespace Notification
217 }  // namespace OHOS