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 }