6 Star 3 Fork 32

OpenHarmony/developtools_global_resource_tool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
compression_parser.cpp 22.27 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "compression_parser.h"
#include <algorithm>
#include <iostream>
#include <mutex>
#include "restool_errors.h"
namespace OHOS {
namespace Global {
namespace Restool {
using namespace std;
static shared_ptr<CompressionParser> compressionParseMgr = nullptr;
static once_flag compressionParserMgrFlag;
const map<TranscodeError, string> ERRORCODEMAP = {
{ TranscodeError::SUCCESS, "SUCCESS" },
{ TranscodeError::INVALID_PARAMETERS, "INVALID_PARAMETERS" },
{ TranscodeError::IMAGE_ERROR, "IMAGE_ERROR" },
{ TranscodeError::ANIMATED_IMAGE_SKIP, "ANIMATED_IMAGE_SKIP" },
{ TranscodeError::MALLOC_FAILED, "MALLOC_FAILED" },
{ TranscodeError::ENCODE_ASTC_FAILED, "ENCODE_ASTC_FAILED" },
{ TranscodeError::SUPER_COMPRESS_FAILED, "SUPER_COMPRESS_FAILED" },
{ TranscodeError::IMAGE_SIZE_NOT_MATCH, "IMAGE_SIZE_NOT_MATCH" },
{ TranscodeError::IMAGE_RESOLUTION_NOT_MATCH, "IMAGE_RESOLUTION_NOT_MATCH" },
{ TranscodeError::EXCLUDE_MATCH, "EXCLUDE_MATCH" },
{ TranscodeError::LOAD_COMPRESS_FAILED, "LOAD_COMPRESS_FAILED" },
};
CompressionParser::CompressionParser()
: filePath_(""), extensionPath_(""), mediaSwitch_(false), root_(nullptr), defaultCompress_(false), outPath_("")
{
}
CompressionParser::CompressionParser(const string &filePath)
: filePath_(filePath), extensionPath_(""), mediaSwitch_(false), root_(nullptr), defaultCompress_(false),
outPath_("")
{
}
CompressionParser::~CompressionParser()
{
if (root_) {
cJSON_Delete(root_);
}
#ifdef __WIN32
if (handle_) {
FreeLibrary(handle_);
handle_ = nullptr;
}
#else
if (handle_) {
dlclose(handle_);
handle_ = nullptr;
}
#endif
}
shared_ptr<CompressionParser> CompressionParser::GetCompressionParser(const string &filePath)
{
call_once(compressionParserMgrFlag, [&] {
compressionParseMgr = make_shared<CompressionParser>(filePath);
});
return compressionParseMgr;
}
shared_ptr<CompressionParser> CompressionParser::GetCompressionParser()
{
if (!compressionParseMgr) {
compressionParseMgr = make_shared<CompressionParser>();
}
return compressionParseMgr;
}
uint32_t CompressionParser::Init()
{
if (!ResourceUtil::OpenJsonFile(filePath_, &root_)) {
return RESTOOL_ERROR;
}
if (!root_ || !cJSON_IsObject(root_)) {
PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(filePath_));
return RESTOOL_ERROR;
}
cJSON *contextNode = cJSON_GetObjectItem(root_, "context");
if (!ParseContext(contextNode)) {
cout << NEW_LINE_PATH << filePath_ << endl;
return RESTOOL_SUCCESS;
}
if (!LoadImageTranscoder()) {
return RESTOOL_ERROR;
}
cJSON *compressionNode = cJSON_GetObjectItem(root_, "compression");
if (!ParseCompression(compressionNode)) {
return RESTOOL_ERROR;
}
if (!mediaSwitch_) {
return RESTOOL_SUCCESS;
}
cJSON *filtersNode = cJSON_GetObjectItem(compressionNode, "filters");
if (!ParseFilters(filtersNode)) {
return RESTOOL_ERROR;
}
string caches = outPath_;
caches.append(SEPARATOR_FILE).append(CACHES_DIR);
if (!ResourceUtil::CreateDirs(caches)) {
return RESTOOL_ERROR;
}
return RESTOOL_SUCCESS;
}
bool CompressionParser::ParseCompression(const cJSON *compressionNode)
{
if (!compressionNode) {
cerr << "Warning: get 'compression' node is empty, the compiled images are not transcoded.";
cerr << NEW_LINE_PATH << filePath_ << endl;
return true;
}
if (!cJSON_IsObject(compressionNode)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("compression", "object").SetPosition(filePath_));
return false;
}
cJSON *mediaNode = cJSON_GetObjectItem(compressionNode, "media");
if (!mediaNode) {
cerr << "Warning: get 'media' node is empty, the compiled images are not transcoded.";
cerr << NEW_LINE_PATH << filePath_ << endl;
return true;
}
if (!cJSON_IsObject(mediaNode)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("media", "object").SetPosition(filePath_));
return false;
}
cJSON *enableNode = cJSON_GetObjectItem(mediaNode, "enable");
if (!enableNode) {
cerr << "Warning: get 'enable' node is empty, the compiled images are not transcoded.";
cerr << NEW_LINE_PATH << filePath_ << endl;
return true;
}
if (!cJSON_IsBool(enableNode)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("enable", "bool").SetPosition(filePath_));
return false;
}
mediaSwitch_ = cJSON_IsTrue(enableNode);
return true;
}
bool CompressionParser::ParseContext(const cJSON *contextNode)
{
if (!contextNode) {
cout << "Warning: if image transcoding is supported, the 'context' node cannot be empty.";
return false;
}
if (!cJSON_IsObject(contextNode)) {
cout << "Warning: 'context' must be object.";
return false;
}
cJSON *extensionPathNode = cJSON_GetObjectItem(contextNode, "extensionPath");
if (!extensionPathNode) {
cout << "Warning: if image transcoding is supported, the 'extensionPath' node cannot be empty.";
return false;
}
if (!cJSON_IsString(extensionPathNode)) {
cout << "Warning: 'extensionPath' must be string.";
return false;
}
extensionPath_ = extensionPathNode->valuestring;
if (extensionPath_.empty()) {
cout << "Warning: 'extensionPath' value cannot be empty.";
return false;
}
return true;
}
bool CompressionParser::ParseFilters(const cJSON *filtersNode)
{
if (!filtersNode) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("filters").SetPosition(filePath_));
return false;
}
if (!cJSON_IsArray(filtersNode)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("filters", "array").SetPosition(filePath_));
return false;
}
if (cJSON_GetArraySize(filtersNode) == 0) {
PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY).FormatCause("filters").SetPosition(filePath_));
return false;
}
for (cJSON *item = filtersNode->child; item; item = item->next) {
if (!cJSON_IsObject(item)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("filters's value", "object")
.SetPosition(filePath_));
return false;
}
cJSON *methodNode = cJSON_GetObjectItem(item, "method");
if (!methodNode) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("method").SetPosition(filePath_));
return false;
}
if (!cJSON_IsObject(methodNode)) {
PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("method", "object").SetPosition(filePath_));
return false;
}
shared_ptr<CompressFilter> compressFilter = make_shared<CompressFilter>();
compressFilter->method = "\"method\":" + ParseJsonStr(methodNode);
cJSON *pathNode = cJSON_GetObjectItem(item, "path");
compressFilter->path = ParsePath(pathNode);
cJSON *excludePathNode = cJSON_GetObjectItem(item, "exclude_path");
compressFilter->excludePath = ParsePath(excludePathNode);
cJSON *rulesNode = cJSON_GetObjectItem(item, "rules_origin");
compressFilter->rules = ParseRules(rulesNode);
cJSON *excludeRulesNode = cJSON_GetObjectItem(item, "rules_exclude");
compressFilter->excludeRules = ParseRules(excludeRulesNode);
compressFilters_.emplace_back(compressFilter);
}
defaultCompress_ = IsDefaultCompress();
return true;
}
bool CompressionParser::IsDefaultCompress()
{
if (compressFilters_.size() != 1) {
return false;
}
auto compressFilter = compressFilters_[0];
bool pathEmpty = (compressFilter->path.size() == 1) && (compressFilter->path[0] == "true");
bool excludePathEmpty = (compressFilter->excludePath.size() == 1) && (compressFilter->excludePath[0] == "true");
return pathEmpty && excludePathEmpty && (compressFilter->rules.empty()) && (compressFilter->excludeRules.empty());
}
void CompressionParser::SetOutPath(const string &path)
{
outPath_ = path;
}
string CompressionParser::ParseRules(const cJSON *rulesNode)
{
string res = "";
if (!rulesNode || !cJSON_IsObject(rulesNode)) {
cout << "Warning: rules is not exist or node type is wrong" << endl;
return res;
}
for (cJSON *item = rulesNode->child; item; item = item->next) {
if (!item || !cJSON_IsArray(item)) {
continue;
}
string name(item->string);
res.append("\"").append(name).append("\":").append(ParseJsonStr(item)).append(",");
}
if (res.size() - 1 < 0) {
return res;
}
return res.substr(0, res.size() - 1);
}
vector<string> CompressionParser::ParsePath(const cJSON *pathNode)
{
vector<string> res;
if (!pathNode) {
res.emplace_back("true");
return res;
}
if (!cJSON_IsArray(pathNode)) {
cout << "Warning: pathnode is not array." << endl;
return res;
}
for (cJSON *item = pathNode->child; item; item = item->next) {
if (!item || !cJSON_IsString(item)) {
continue;
}
res.emplace_back(item->valuestring);
}
return res;
}
string CompressionParser::ParseJsonStr(const cJSON *node)
{
if (!node) {
return "";
}
char *jsonString = cJSON_Print(node);
if (jsonString == nullptr) {
return "";
}
string res(jsonString);
free(jsonString);
return res;
}
bool CompressionParser::LoadImageTranscoder()
{
#ifdef __WIN32
if (!handle_) {
handle_ = LoadLibrary(TEXT(extensionPath_.c_str()));
if (!handle_) {
DWORD err = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
const char *msg = static_cast<const char *>(lpMsgBuf);
std::string errMsg = "(" + std::to_string(err) + ")" + string(msg);
PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(extensionPath_.c_str(), errMsg.c_str()));
LocalFree(lpMsgBuf);
return false;
}
}
#else
if (!handle_) {
string realPath = ResourceUtil::RealPath(extensionPath_);
if (realPath.empty()) {
PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(extensionPath_.c_str(), "path invalid"));
return false;
}
handle_ = dlopen(realPath.c_str(), RTLD_LAZY);
if (!handle_) {
char *err = dlerror();
PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(realPath.c_str(), err));
return false;
}
}
#endif
return true;
}
bool CompressionParser::SetTranscodeOptions(const string &optionJson, const string &optionJsonExclude)
{
if (!handle_) {
cout << "Warning: SetTranscodeOptions handle_ is nullptr." << endl;
return false;
}
#ifdef __WIN32
ISetTranscodeOptions iSetTranscodeOptions = (ISetTranscodeOptions)GetProcAddress(handle_, "SetTranscodeOptions");
#else
ISetTranscodeOptions iSetTranscodeOptions = (ISetTranscodeOptions)dlsym(handle_, "SetTranscodeOptions");
#endif
if (!iSetTranscodeOptions) {
cout << "Warning: Failed to get the 'SetTranscodeOptions'." << endl;
return false;
}
bool ret = (*iSetTranscodeOptions)(optionJson, optionJsonExclude);
if (!ret) {
cout << "Warning: SetTranscodeOptions failed." << endl;
return false;
}
return true;
}
TranscodeError CompressionParser::TranscodeImages(const string &imagePath, const bool extAppend,
string &outputPath, TranscodeResult &result)
{
if (!handle_) {
cout << "Warning: TranscodeImages handle_ is nullptr." << endl;
return TranscodeError::LOAD_COMPRESS_FAILED;
}
#ifdef __WIN32
ITranscodeImages iTranscodeImages = (ITranscodeImages)GetProcAddress(handle_, "Transcode");
#else
ITranscodeImages iTranscodeImages = (ITranscodeImages)dlsym(handle_, "Transcode");
#endif
if (!iTranscodeImages) {
cout << "Warning: Failed to get the 'Transcode'." << endl;
return TranscodeError::LOAD_COMPRESS_FAILED;
}
TranscodeError ret = (*iTranscodeImages)(imagePath, extAppend, outputPath, result);
if (ret != TranscodeError::SUCCESS) {
auto iter = ERRORCODEMAP.find(ret);
if (iter != ERRORCODEMAP.end()) {
cout << "Warning: TranscodeImages failed, error message: " << iter->second << ", file path = " <<
imagePath << endl;
} else {
cout << "Warning: TranscodeImages failed" << ", file path = " << imagePath << endl;
}
return ret;
}
return TranscodeError::SUCCESS;
}
TranscodeError CompressionParser::ScaleImage(const std::string &imagePath, std::string &outputPath)
{
if (!handle_) {
cout << "Warning: ScaleImage handle_ is nullptr." << endl;
return TranscodeError::LOAD_COMPRESS_FAILED;
}
#ifdef __WIN32
IScaleImage iScaleImage = (IScaleImage)GetProcAddress(handle_, "TranscodeSLR");
#else
IScaleImage iScaleImage = (IScaleImage)dlsym(handle_, "TranscodeSLR");
#endif
if (!iScaleImage) {
cout << "Warning: Failed to get the 'TranscodeSLR'." << endl;
return TranscodeError::LOAD_COMPRESS_FAILED;
}
TranscodeError ret = (*iScaleImage)(imagePath, outputPath, { 512, 512 });
if (ret != TranscodeError::SUCCESS) {
auto iter = ERRORCODEMAP.find(ret);
if (iter != ERRORCODEMAP.end()) {
cout << "Warning: ScaleImage failed, error message: " << iter->second << ", file path = " << imagePath
<< endl;
} else {
cout << "Warning: ScaleImage failed" << ", file path = " << imagePath << endl;
}
return ret;
}
return TranscodeError::SUCCESS;
}
bool CompressionParser::CheckPath(const string &src, const vector<string> &paths)
{
if (paths.size() == 1 && paths[0] == "true") {
return true;
}
return any_of(paths.begin(), paths.end(), [src](const auto &iter) {
return iter == src;
});
}
bool CompressionParser::IsInPath(const string &src, const shared_ptr<CompressFilter> &compressFilter)
{
return CheckPath(src, compressFilter->path);
}
bool CompressionParser::IsInExcludePath(const string &src, const shared_ptr<CompressFilter> &compressFilter)
{
return CheckPath(src, compressFilter->excludePath);
}
string CompressionParser::GetMethod(const shared_ptr<CompressFilter> &compressFilter)
{
return "{" + compressFilter->method + "}";
}
string CompressionParser::GetRules(const shared_ptr<CompressFilter> &compressFilter)
{
return GetFileRules(compressFilter->rules, compressFilter->method);
}
string CompressionParser::GetExcludeRules(const shared_ptr<CompressFilter> &compressFilter)
{
return GetFileRules(compressFilter->excludeRules, compressFilter->method);
}
string CompressionParser::GetFileRules(const string &rules, const string &method)
{
if (rules.empty()) {
return "{" + method + "}";
}
string res = "{";
return res.append(method).append(",").append(rules).append("}");
}
void CompressionParser::CollectTime(uint32_t &count, unsigned long long &time,
std::chrono::time_point<std::chrono::steady_clock> &start)
{
unsigned long long costTime = static_cast<unsigned long long>(
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count());
time += costTime;
count++;
}
void CompressionParser::CollectTimeAndSize(TranscodeError res,
std::chrono::time_point<std::chrono::steady_clock> &start, TranscodeResult &result)
{
unsigned long long costTime = static_cast<unsigned long long>(
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count());
if (res == TranscodeError::SUCCESS) {
totalTime_ += costTime;
totalCounts_++;
compressTime_ += costTime;
compressCounts_++;
successTime_ += costTime;
successCounts_++;
originalSize_ += result.originSize;
successSize_ += static_cast<unsigned long long>(result.size);
} else if (res < TranscodeError::NOT_MATCH_BASE) {
totalTime_ += costTime;
compressTime_ += costTime;
compressCounts_++;
} else {
totalTime_ += costTime;
}
}
string CompressionParser::PrintTransMessage()
{
string res = "Processing report:\n";
res.append("total:").append(to_string(totalCounts_)).append(", ").append(to_string(totalTime_)).append(" us.\n");
res.append("compressed:").append(to_string(compressCounts_)).append(", ").append(to_string(compressTime_))
.append(" us.\n");
res.append("success:").append(to_string(successCounts_)).append(", ").append(to_string(successTime_))
.append(" us, ").append(to_string(originalSize_)).append(" Bytes to ").append(to_string(successSize_))
.append(" Bytes.");
return res;
}
bool CompressionParser::GetMediaSwitch()
{
return mediaSwitch_;
}
bool CompressionParser::GetDefaultCompress()
{
return defaultCompress_;
}
bool CompressionParser::CheckAndTranscode(const string &src, string &dst, string &output,
const shared_ptr<CompressFilter> &compressFilter, const bool extAppend)
{
auto t1 = std::chrono::steady_clock::now();
TranscodeResult result = {0, 0, 0, 0};
if (defaultCompress_) {
if (!SetTranscodeOptions(GetMethod(compressFilter), "")) {
return false;
}
auto res = TranscodeImages(src, extAppend, output, result);
CollectTimeAndSize(res, t1, result);
if (res != TranscodeError::SUCCESS) {
return false;
}
dst = output;
return true;
}
if (!IsInPath(src, compressFilter)) {
return false;
}
if (IsInExcludePath(src, compressFilter)) {
if (!SetTranscodeOptions(GetRules(compressFilter), GetExcludeRules(compressFilter))) {
return false;
}
auto res = TranscodeImages(src, extAppend, output, result);
CollectTimeAndSize(res, t1, result);
if (res != TranscodeError::SUCCESS) {
return false;
}
dst = output;
return true;
}
if (!SetTranscodeOptions(GetRules(compressFilter), "")) {
return false;
}
auto res = TranscodeImages(src, extAppend, output, result);
CollectTimeAndSize(res, t1, result);
if (res != TranscodeError::SUCCESS) {
return false;
}
dst = output;
return true;
}
bool CompressionParser::CopyForTrans(const string &src, const string &originDst, const string &dst)
{
string srcSuffix;
string dstSuffix;
auto srcIndex = src.find_last_of(".");
auto dstIndex = dst.find_last_of(".");
if (srcIndex != string::npos && dstIndex != string::npos) {
srcSuffix = src.substr(srcIndex + 1);
dstSuffix = dst.substr(dstIndex + 1);
}
auto ret = false;
if (srcSuffix == dstSuffix) {
ret = ResourceUtil::CopyFileInner(src, dst);
} else {
uint32_t startIndex = outPath_.size() + CACHES_DIR.size() + 1;
string dstPath = outPath_ + SEPARATOR_FILE + RESOURCES_DIR + dst.substr(startIndex);
ret = ResourceUtil::CopyFileInner(dst, dstPath);
}
return ret;
}
bool CompressionParser::CopyAndTranscode(const string &src, string &dst, const bool extAppend)
{
auto t0 = std::chrono::steady_clock::now();
if (!mediaSwitch_) {
auto res = ResourceUtil::CopyFileInner(src, dst);
CollectTime(totalCounts_, totalTime_, t0);
return res;
}
auto index = dst.find_last_of(SEPARATOR_FILE);
if (index == string::npos) {
PrintError(GetError(ERR_CODE_INVALID_RESOURCE_PATH).FormatCause(dst.c_str(), "missing separator"));
return false;
}
uint32_t startIndex = outPath_.size() + RESOURCES_DIR.size() + 1;
string endStr = dst.substr(startIndex, index - startIndex);
string output = outPath_ + SEPARATOR_FILE + CACHES_DIR + endStr;
string originDst = dst;
if (!ResourceUtil::CreateDirs(output)) {
return false;
}
for (const auto &compressFilter : compressFilters_) {
if (!CheckAndTranscode(src, dst, output, compressFilter, extAppend)) {
continue;
}
break;
}
auto t2 = std::chrono::steady_clock::now();
auto ret = CopyForTrans(src, originDst, dst);
CollectTime(totalCounts_, totalTime_, t2);
return ret;
}
bool CompressionParser::CheckAndScaleIcon(const std::string &src, const std::string &originDst, std::string &scaleDst)
{
scaleDst = src;
if (filePath_.empty() || outPath_.empty()) {
cout << "Info: compression path or out path is empty, unable to scale icon." << endl;
return true;
}
auto index = originDst.find_last_of(SEPARATOR_FILE);
if (index == string::npos) {
PrintError(GetError(ERR_CODE_INVALID_RESOURCE_PATH).FormatCause(originDst.c_str(), "missing separator"));
return false;
}
uint32_t startIndex = outPath_.size() + RESOURCES_DIR.size() + 1;
string qualifierDir = originDst.substr(startIndex, index - startIndex);
string outputCache = outPath_ + SEPARATOR_FILE + CACHES_DIR + qualifierDir;
if (!ResourceUtil::CreateDirs(outputCache)) {
return false;
}
string fileName = originDst.substr(index + 1);
string outputFile = outputCache + SEPARATOR_FILE + fileName;
auto ret = ScaleImage(src, outputFile);
if (ret == TranscodeError::SUCCESS) {
// if scale success, change src file to scale image
scaleDst = outputFile;
}
return true;
}
bool CompressionParser::ScaleIconEnable()
{
return !filePath_.empty() && !outPath_.empty() && handle_ != nullptr;
}
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C/C++
1
https://gitee.com/openharmony/developtools_global_resource_tool.git
git@gitee.com:openharmony/developtools_global_resource_tool.git
openharmony
developtools_global_resource_tool
developtools_global_resource_tool
master

搜索帮助