mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
cellPhotoDecode: optimize get_scaled_image
This commit is contained in:
parent
e6885e25b5
commit
87e628a9e9
@ -162,7 +162,7 @@ error_code cellPhotoDecodeFromFile(vm::cptr<char> srcHddDir, vm::cptr<char> srcH
|
||||
s32 width{};
|
||||
s32 height{};
|
||||
|
||||
if (!Emu.GetCallbacks().get_scaled_image(path, set_param->width, set_param->height, width, height, static_cast<u8*>(set_param->dstBuffer.get_ptr())))
|
||||
if (!Emu.GetCallbacks().get_scaled_image(path, set_param->width, set_param->height, width, height, static_cast<u8*>(set_param->dstBuffer.get_ptr()), false))
|
||||
{
|
||||
cellPhotoDecode.error("Failed to decode '%s'", path);
|
||||
return CELL_PHOTO_DECODE_ERROR_DECODE;
|
||||
|
@ -157,7 +157,7 @@ error_code select_photo(std::string dst_dir)
|
||||
|
||||
if (!fs::stat(info.path, f_info) || f_info.is_directory)
|
||||
{
|
||||
cellPhotoImportUtil.error("Path is not a directory: '%s'", info.path);
|
||||
cellPhotoImportUtil.error("Path does not belong to a valid file: '%s'", info.path);
|
||||
result = CELL_PHOTO_IMPORT_ERROR_ACCESS_ERROR; // TODO: is this correct ?
|
||||
pi_manager.is_busy = false;
|
||||
pi_manager.func_finish(ppu, result, g_filedata, pi_manager.userdata);
|
||||
|
@ -97,7 +97,7 @@ struct EmuCallbacks
|
||||
std::function<std::u32string(localized_string_id, const char*)> get_localized_u32string;
|
||||
std::function<void(const std::string&)> play_sound;
|
||||
std::function<bool(const std::string&, std::string&, s32&, s32&, s32&)> get_image_info; // (filename, sub_type, width, height, CellSearchOrientation)
|
||||
std::function<bool(const std::string&, s32, s32, s32&, s32&, u8*)> get_scaled_image; // (filename, target_width, target_height, width, height, dst)
|
||||
std::function<bool(const std::string&, s32, s32, s32&, s32&, u8*, bool)> get_scaled_image; // (filename, target_width, target_height, width, height, dst, force_fit)
|
||||
std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt
|
||||
};
|
||||
|
||||
|
@ -189,11 +189,15 @@ EmuCallbacks main_application::CreateCallbacks()
|
||||
success = true;
|
||||
sys_log.notice("get_image_info found image: filename='%s', sub_type='%s', width=%d, height=%d, orientation=%d", filename, sub_type, width, height, orientation);
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_log.warning("get_image_info failed to read '%s'. Error='%s'", filename, reader.errorString().toStdString());
|
||||
}
|
||||
});
|
||||
return success;
|
||||
};
|
||||
|
||||
callbacks.get_scaled_image = [](const std::string& path, s32 target_width, s32 target_height, s32& width, s32& height, u8* dst) -> bool
|
||||
callbacks.get_scaled_image = [](const std::string& path, s32 target_width, s32 target_height, s32& width, s32& height, u8* dst, bool force_fit) -> bool
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
@ -206,34 +210,58 @@ EmuCallbacks main_application::CreateCallbacks()
|
||||
bool success = false;
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
QImage image{};
|
||||
success = image.load(QString::fromStdString(path)) && !image.isNull();
|
||||
// We use QImageReader instead of QImage. This way we can load and scale image in one step.
|
||||
QImageReader reader(QString::fromStdString(path));
|
||||
|
||||
if (success)
|
||||
if (reader.canRead())
|
||||
{
|
||||
width = image.width();
|
||||
height = image.height();
|
||||
QSize size = reader.size();
|
||||
width = size.width();
|
||||
height = size.height();
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (width > target_width || height > target_height)
|
||||
if (force_fit || width > target_width || height > target_height)
|
||||
{
|
||||
const QSize size(target_width, target_height);
|
||||
image = image.scaled(QSize(target_width, target_height), Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation);
|
||||
width = image.width();
|
||||
height = image.height();
|
||||
const f32 target_ratio = target_width / static_cast<f32>(target_height);
|
||||
const f32 image_ratio = width / static_cast<f32>(height);
|
||||
const f32 convert_ratio = image_ratio / target_ratio;
|
||||
|
||||
if (convert_ratio > 1.0f)
|
||||
{
|
||||
size = QSize(target_width, target_height / convert_ratio);
|
||||
}
|
||||
else if (convert_ratio < 1.0f)
|
||||
{
|
||||
size = QSize(target_width * convert_ratio, target_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = QSize(target_width, target_height);
|
||||
}
|
||||
|
||||
reader.setScaledSize(size);
|
||||
width = size.width();
|
||||
height = size.height();
|
||||
}
|
||||
|
||||
QImage image = reader.read();
|
||||
|
||||
if (image.format() != QImage::Format::Format_RGBA8888)
|
||||
{
|
||||
image = image.convertToFormat(QImage::Format::Format_RGBA8888);
|
||||
}
|
||||
|
||||
std::memcpy(dst, image.constBits(), std::min(4 * target_width * target_height, image.height() * image.bytesPerLine()));
|
||||
success = true;
|
||||
sys_log.notice("get_scaled_image scaled image: path='%s', width=%d, height=%d", path, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_log.error("get_scaled_image failed to read '%s'. Error='%s'", path, reader.errorString().toStdString());
|
||||
}
|
||||
});
|
||||
return success;
|
||||
|
Loading…
Reference in New Issue
Block a user