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 "core/image/image_source_info.h"
17
18 #include <regex>
19 #include "base/log/log.h"
20
21 namespace OHOS::Ace {
22
IsSVGSource(const std::string & src,InternalResource::ResourceId resourceId)23 bool ImageSourceInfo::IsSVGSource(const std::string& src, InternalResource::ResourceId resourceId)
24 {
25 // 4 is the length of ".svg".
26 return (src.size() > 4 && src.substr(src.size() - 4) == ".svg") ||
27 (src.empty() && resourceId > InternalResource::ResourceId::SVG_START &&
28 resourceId < InternalResource::ResourceId::SVG_END);
29 }
30
IsValidBase64Head(const std::string & uri,const std::string & pattern)31 bool ImageSourceInfo::IsValidBase64Head(const std::string& uri, const std::string& pattern)
32 {
33 auto iter = uri.find_first_of(',');
34 if (iter == std::string::npos) {
35 LOGE("wrong base64 head format.");
36 return false;
37 }
38 std::string base64Head = uri.substr(0, iter);
39 std::regex regular(pattern);
40 return std::regex_match(base64Head, regular);
41 }
42
IsUriOfDataAbilityEncoded(const std::string & uri,const std::string & pattern)43 bool ImageSourceInfo::IsUriOfDataAbilityEncoded(const std::string& uri, const std::string& pattern)
44 {
45 std::regex regular(pattern);
46 return std::regex_match(uri, regular);
47 }
48
ResolveURIType(const std::string & uri)49 SrcType ImageSourceInfo::ResolveURIType(const std::string& uri)
50 {
51 if (uri.empty()) {
52 return SrcType::UNSUPPORTED;
53 }
54 auto iter = uri.find_first_of(':');
55 if (iter == std::string::npos) {
56 return SrcType::ASSET;
57 }
58 std::string head = uri.substr(0, iter);
59 std::transform(head.begin(), head.end(), head.begin(), [](unsigned char c) { return std::tolower(c); });
60 if (head == "http" || head == "https") {
61 return SrcType::NETWORK;
62 } else if (head == "file") {
63 return SrcType::FILE;
64 } else if (head == "internal") {
65 return SrcType::INTERNAL;
66 } else if (head == "data") {
67 static constexpr char BASE64_PATTERN[] = "^data:image/(jpeg|jpg|png|ico|gif|bmp|webp);base64$";
68 if (IsValidBase64Head(uri, BASE64_PATTERN)) {
69 return SrcType::BASE64;
70 }
71 return SrcType::UNSUPPORTED;
72 } else if (head == "memory") {
73 return SrcType::MEMORY;
74 } else if (head == "resource") {
75 return SrcType::RESOURCE;
76 } else if (head == "dataability") {
77 if (IsUriOfDataAbilityEncoded(uri, "^dataability://.*?/media/.*/thumbnail/.*$")) {
78 return SrcType::DATA_ABILITY_DECODED;
79 }
80 return SrcType::DATA_ABILITY;
81 } else {
82 return SrcType::UNSUPPORTED;
83 }
84 }
85
ImageSourceInfo(const std::string & imageSrc,Dimension width,Dimension height,InternalResource::ResourceId resourceId,const RefPtr<PixelMap> & pixmap)86 ImageSourceInfo::ImageSourceInfo(
87 const std::string& imageSrc,
88 Dimension width,
89 Dimension height,
90 InternalResource::ResourceId resourceId,
91 const RefPtr<PixelMap>& pixmap)
92 : src_(imageSrc),
93 sourceWidth_(width),
94 sourceHeight_(height),
95 resourceId_(resourceId),
96 pixmap_(pixmap),
97 isSvg_(IsSVGSource(src_, resourceId_)),
98 srcType_(ResolveSrcType())
99 {
100 // count how many source set.
101 int32_t count = 0;
102 if (!src_.empty()) {
103 ++count;
104 }
105 if (resourceId_ != InternalResource::ResourceId::NO_ID) {
106 ++count;
107 }
108 if (pixmap != nullptr) {
109 ++count;
110 }
111 if (count > 1) {
112 LOGW("multi image source set, only one will be load.");
113 }
114 cacheKey_ = std::to_string(std::hash<std::string> {}(src_));
115 }
116
ResolveSrcType() const117 SrcType ImageSourceInfo::ResolveSrcType() const
118 {
119 if (pixmap_) {
120 return SrcType::PIXMAP;
121 }
122 if (!src_.empty()) {
123 return ResolveURIType(src_);
124 }
125 if (resourceId_ != InternalResource::ResourceId::NO_ID) {
126 return SrcType::RESOURCE_ID;
127 }
128 return SrcType::UNSUPPORTED;
129 }
130
SetFillColor(const Color & color)131 void ImageSourceInfo::SetFillColor(const Color& color)
132 {
133 fillColor_.emplace(color.GetValue());
134 }
135
136 } // namespace OHOS::Ace
137