• 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 "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