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