• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 "resource_check.h"
16 #include "file_manager.h"
17 #include <png.h>
18 
19 namespace OHOS {
20 namespace Global {
21 namespace Restool {
22 using namespace std;
23 
24 namespace {
25     constexpr int PNG_BYTRS_TO_CHECK = 8;
26 }
27 
ResourceCheck(const std::map<std::string,std::set<uint32_t>> & jsonCheckIds,const shared_ptr<ResourceAppend> & resourceAppend)28 ResourceCheck::ResourceCheck(const std::map<std::string, std::set<uint32_t>> &jsonCheckIds,
29     const shared_ptr<ResourceAppend> &resourceAppend) : jsonCheckIds_(jsonCheckIds), resourceAppend_(resourceAppend)
30 {
31 }
32 
CheckConfigJson()33 void ResourceCheck::CheckConfigJson()
34 {
35     auto &fileManager = FileManager::GetInstance();
36     auto &allResource = fileManager.GetResources();
37     for (auto it = jsonCheckIds_.begin(); it != jsonCheckIds_.end(); it++) {
38         for (const auto &id : it->second) {
39             auto res = allResource.find(id);
40             if (res == allResource.end()) {
41                 continue;
42             }
43             for (auto resourceItem : res->second) {
44                 CheckNodeInResourceItem(it->first, resourceItem);
45             }
46         }
47     }
48 }
49 
CheckConfigJsonForCombine()50 void ResourceCheck::CheckConfigJsonForCombine()
51 {
52     auto &allResource = resourceAppend_->GetItems();
53     for (auto it = jsonCheckIds_.begin(); it != jsonCheckIds_.end(); it++) {
54         for (const auto &id : it->second) {
55             auto res = allResource.find(id);
56             if (res == allResource.end()) {
57                 continue;
58             }
59             for (auto resourceItemPtr : res->second) {
60                 CheckNodeInResourceItem(it->first, *resourceItemPtr);
61             }
62         }
63     }
64 }
65 
CheckNodeInResourceItem(const string & key,const ResourceItem & resourceItem)66 void ResourceCheck::CheckNodeInResourceItem(const string &key, const ResourceItem &resourceItem)
67 {
68     string filePath = resourceItem.GetFilePath();
69     uint32_t width;
70     uint32_t height;
71     if (!GetPngWidthAndHeight(filePath, &width, &height)) {
72         return;
73     }
74     if (width != height) {
75         cerr << "Warning: the png width and height not equal" << NEW_LINE_PATH << filePath << endl;
76         return;
77     }
78     auto result = g_keyNodeIndexs.find(key);
79     if (result == g_keyNodeIndexs.end()) {
80         return;
81     }
82     uint32_t normalSize = ResourceUtil::GetNormalSize(resourceItem.GetKeyParam(), result->second);
83     if (normalSize != 0 && width > normalSize) {
84         string warningMsg = "Warning: The width or height of the png file referenced by the " + key + \
85             " exceeds the limit (" + to_string(normalSize) + " pixels)" + NEW_LINE_PATH + filePath;
86         cerr << warningMsg << endl;
87     }
88 }
89 
IsValidPngImage(FILE * & in) const90 bool ResourceCheck::IsValidPngImage(FILE *&in) const
91 {
92     char checkheader[PNG_BYTRS_TO_CHECK];
93     if (fread(checkheader, 1, PNG_BYTRS_TO_CHECK, in) != PNG_BYTRS_TO_CHECK) {
94         return false;
95     }
96     if (png_sig_cmp(reinterpret_cast<png_const_bytep>(checkheader), 0, PNG_BYTRS_TO_CHECK) != 0) {
97         return false;
98     }
99 
100     rewind(in);
101     return true;
102 }
103 
GetPngWidthAndHeight(const string & filePath,uint32_t * width,uint32_t * height)104 bool ResourceCheck::GetPngWidthAndHeight(const string &filePath, uint32_t *width, uint32_t *height)
105 {
106     FILE *in = fopen(filePath.c_str(), "rb");
107     if (in == nullptr) {
108         cout << "Warning: " << filePath << " can not open" << endl;
109         return false;
110     }
111     if (!IsValidPngImage(in)) {
112         cout << "Warning: " << filePath << " is not png format" << endl;
113         CloseFile(in);
114         return false;
115     }
116     png_structp pngHandle = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
117     if (pngHandle == nullptr) {
118         CloseFile(in);
119         return false;
120     }
121     png_infop infoHandle = png_create_info_struct(pngHandle);
122     if (infoHandle == nullptr) {
123         CloseFile(in);
124         png_destroy_read_struct(&pngHandle, nullptr, nullptr);
125         return false;
126     }
127     png_init_io(pngHandle, in);
128     png_read_info(pngHandle, infoHandle);
129     unsigned int w;
130     unsigned int h;
131     png_get_IHDR(pngHandle, infoHandle, &w, &h, nullptr, nullptr, nullptr, nullptr, nullptr);
132     *width = w;
133     *height = h;
134     CloseFile(in);
135     png_destroy_read_struct(&pngHandle, &infoHandle, 0);
136     return true;
137 }
138 
CloseFile(FILE * fp)139 void ResourceCheck::CloseFile(FILE *fp)
140 {
141     if (fp != nullptr) {
142         fclose(fp);
143     }
144 }
145 
146 }
147 }
148 }