diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index a24219a44d..9f6e2c7e56 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -368,20 +368,50 @@ void populate_video_info(CellSearchVideoInfo& info, const utils::media_info& mi, info.videoBitrate, info.audioBitrate, info.playCount, info.drmEncrypted, info.videoCodec, info.audioCodec, info.status); } -void populate_photo_info(CellSearchPhotoInfo& info, const utils::media_info& /*mi*/, const fs::dir_entry& item) +void populate_photo_info(CellSearchPhotoInfo& info, const utils::media_info& mi, const fs::dir_entry& item) { // TODO - Some kinda file photo analysis and assign the values as such info.size = item.size; info.importedDate = -1; info.takenDate = -1; - info.width = 0; - info.height = 0; - info.orientation = CELL_SEARCH_ORIENTATION_UNKNOWN; - info.codec = CELL_SEARCH_CODEC_UNKNOWN; + info.width = mi.width; + info.height = mi.height; + info.orientation = mi.orientation; info.status = CELL_SEARCH_CONTENTSTATUS_AVAILABLE; strcpy_trunc(info.title, item.name.substr(0, item.name.find_last_of('.'))); strcpy_trunc(info.albumTitle, "ALBUM TITLE"); + const std::string sub_type = fmt::to_lower(mi.sub_type); + + if (sub_type == "jpg" || sub_type == "jpeg") + { + info.codec = CELL_SEARCH_CODEC_JPEG; + } + else if (sub_type == "png") + { + info.codec = CELL_SEARCH_CODEC_PNG; + } + else if (sub_type == "tif" || sub_type == "tiff") + { + info.codec = CELL_SEARCH_CODEC_TIFF; + } + else if (sub_type == "bmp") + { + info.codec = CELL_SEARCH_CODEC_BMP; + } + else if (sub_type == "gif") + { + info.codec = CELL_SEARCH_CODEC_GIF; + } + else if (sub_type == "mpo") + { + info.codec = CELL_SEARCH_CODEC_MPO; + } + else + { + info.codec = CELL_SEARCH_CODEC_UNKNOWN; + } + cellSearch.notice("CellSearchPhotoInfo: title='%s', albumTitle='%s', size=%d, width=%d, height=%d, orientation=%d, codec=%d, status=%d, importedDate=%d, takenDate=%d", info.title, info.albumTitle, info.size, info.width, info.height, info.orientation, info.codec, info.status, info.importedDate, info.takenDate); } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 831eeb17f8..dddd25c6e5 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -96,6 +96,7 @@ struct EmuCallbacks std::function get_localized_string; std::function get_localized_u32string; std::function play_sound; + std::function get_image_info; // (filename, sub_type, width, height, CellSearchOrientation) std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt }; diff --git a/rpcs3/main_application.cpp b/rpcs3/main_application.cpp index c4273e6f2d..39d26e3f44 100644 --- a/rpcs3/main_application.cpp +++ b/rpcs3/main_application.cpp @@ -31,6 +31,7 @@ #endif #include // This shouldn't be outside rpcs3qt... +#include // This shouldn't be outside rpcs3qt... #include LOG_CHANNEL(sys_log, "SYS"); @@ -147,6 +148,50 @@ EmuCallbacks main_application::CreateCallbacks() } }; + callbacks.get_image_info = [](const std::string& filename, std::string& sub_type, s32& width, s32& height, s32& orientation) -> bool + { + sub_type.clear(); + width = 0; + height = 0; + orientation = 0; // CELL_SEARCH_ORIENTATION_UNKNOWN + + bool success = false; + Emu.BlockingCallFromMainThread([&]() + { + const QImageReader reader(QString::fromStdString(filename)); + if (reader.canRead()) + { + const QSize size = reader.size(); + width = size.width(); + height = size.height(); + sub_type = reader.subType().toStdString(); + + switch (reader.transformation()) + { + case QImageIOHandler::Transformation::TransformationNone: + orientation = 1; // CELL_SEARCH_ORIENTATION_TOP_LEFT = 0° + break; + case QImageIOHandler::Transformation::TransformationRotate90: + orientation = 2; // CELL_SEARCH_ORIENTATION_TOP_RIGHT = 90° + break; + case QImageIOHandler::Transformation::TransformationRotate180: + orientation = 3; // CELL_SEARCH_ORIENTATION_BOTTOM_RIGHT = 180° + break; + case QImageIOHandler::Transformation::TransformationRotate270: + orientation = 4; // CELL_SEARCH_ORIENTATION_BOTTOM_LEFT = 270° + break; + default: + // Ignore other transformations for now + break; + } + + 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); + } + }); + return success; + }; + callbacks.resolve_path = [](std::string_view sv) { return QFileInfo(QString::fromUtf8(sv.data(), static_cast(sv.size()))).canonicalFilePath().toStdString(); diff --git a/rpcs3/util/media_utils.cpp b/rpcs3/util/media_utils.cpp index 5808b12e87..d2d00603d8 100644 --- a/rpcs3/util/media_utils.cpp +++ b/rpcs3/util/media_utils.cpp @@ -3,6 +3,7 @@ #include "logs.hpp" #include "Utilities/StrUtil.h" #include "Emu/Cell/Modules/cellSearch.h" +#include "Emu/System.h" #include @@ -67,9 +68,16 @@ namespace utils std::pair get_media_info(const std::string& path, s32 av_media_type) { - media_info info; + media_info info{}; info.path = path; + if (av_media_type == AVMEDIA_TYPE_UNKNOWN) // Let's use this for image info + { + const bool success = Emu.GetCallbacks().get_image_info(path, info.sub_type, info.width, info.height, info.orientation); + if (!success) media_log.error("get_image_info: failed to get image info for '%s'", path); + return { success, std::move(info) }; + } + // Only print FFMPEG errors, fatals and panics av_log_set_level(AV_LOG_ERROR); diff --git a/rpcs3/util/media_utils.h b/rpcs3/util/media_utils.h index 02d8cc49d4..550f2ac34a 100644 --- a/rpcs3/util/media_utils.h +++ b/rpcs3/util/media_utils.h @@ -16,6 +16,7 @@ namespace utils struct media_info { std::string path; + std::string sub_type; // The sub type if available (png, jpg...) s32 audio_av_codec_id = 0; // 0 = AV_CODEC_ID_NONE s32 video_av_codec_id = 0; // 0 = AV_CODEC_ID_NONE @@ -23,6 +24,9 @@ namespace utils s32 video_bitrate_bps = 0; // Bit rate in bit/s s32 sample_rate = 0; // Samples per second s64 duration_us = 0; // in AV_TIME_BASE fractional seconds (= microseconds) + s32 width = 0; // Width if available + s32 height = 0; // Height if available + s32 orientation = 0; // Orientation if available (= CellSearchOrientation) std::unordered_map metadata;