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 }