Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for non-front cover stub images to artwork view #345

Merged
merged 1 commit into from
Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Development version

* Support for back cover, disc and artist stub images was added to the Artwork view panel. [[#345](https://github.com/reupen/columns_ui/pull/345)]

* The `Zc:threadSafeInit-` compiler option is no longer used. [[#340](https://github.com/reupen/columns_ui/pull/340)]

## 1.6.0
Expand Down
16 changes: 8 additions & 8 deletions foo_ui_columns/artwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,17 +346,17 @@ void ArtworkPanel::on_completion(unsigned p_code)
}

if (!b_found) {
show_emptycover();
show_stub_image();
}
}
}
#endif

void ArtworkPanel::show_emptycover()
void ArtworkPanel::show_stub_image()
{
if (m_artwork_loader && m_artwork_loader->IsReady()) {
album_art_data_ptr data;
if (m_artwork_loader->QueryEmptyCover(data)) {
album_art_data_ptr data = m_artwork_loader->get_stub_image(g_artwork_types[m_position]);
if (data.is_valid()) {
wil::com_ptr_t<mmh::IStreamMemblock> pStream
= new mmh::IStreamMemblock((const t_uint8*)data->get_ptr(), data->get_size());
{
Expand All @@ -383,8 +383,8 @@ bool ArtworkPanel::refresh_image(t_size index)
if (!m_artwork_loader || !m_artwork_loader->IsReady())
return false;

album_art_data_ptr data;
if (!m_artwork_loader->Query(g_artwork_types[index], data))
const auto data = m_artwork_loader->get_image(g_artwork_types[index]);
if (data.is_empty())
return false;

cui::wic::BitmapData bitmap_data{};
Expand Down Expand Up @@ -720,10 +720,10 @@ ArtworkPanel::MenuNodeArtworkType::MenuNodeArtworkType(ArtworkPanel* p_wnd, t_si

void ArtworkPanel::MenuNodeArtworkType::execute()
{
p_this->m_position = m_type;
if (!p_this->refresh_image(m_type)) {
p_this->show_emptycover();
p_this->show_stub_image();
}
p_this->m_position = m_type;
}

bool ArtworkPanel::MenuNodeArtworkType::get_description(pfc::string_base& p_out) const
Expand Down
2 changes: 1 addition & 1 deletion foo_ui_columns/artwork.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class ArtworkPanel
void refresh_cached_bitmap();
void flush_cached_bitmap();
bool refresh_image(t_size index);
void show_emptycover();
void show_stub_image();
void flush_image();

ULONG_PTR m_gdiplus_instance{NULL};
Expand Down
134 changes: 68 additions & 66 deletions foo_ui_columns/artwork_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ void artwork_panel::ArtworkReader::run_notification_thisthread(DWORD state)
}

void artwork_panel::ArtworkReader::initialise(const std::vector<GUID>& p_requestIds,
const std::unordered_map<GUID, album_art_data_ptr>& p_content_previous, bool b_read_emptycover,
const std::unordered_map<GUID, album_art_data_ptr>& p_content_previous, bool read_stub_image,
const metadb_handle_ptr& p_handle, const completion_notify_ptr& p_notify,
std::shared_ptr<class ArtworkReaderManager> p_manager)
{
m_requestIds = p_requestIds;
m_content = p_content_previous;
m_read_emptycover = b_read_emptycover;
m_read_stub_image = read_stub_image;
m_handle = p_handle;
m_notify = p_notify;
m_manager = std::move(p_manager);
}

const album_art_data_ptr& artwork_panel::ArtworkReader::get_emptycover() const
const std::unordered_map<GUID, album_art_data_ptr>& artwork_panel::ArtworkReader::get_stub_images() const
{
return m_emptycover;
return m_stub_images;
}

const std::unordered_map<GUID, album_art_data_ptr>& artwork_panel::ArtworkReader::get_content() const
Expand Down Expand Up @@ -58,28 +58,39 @@ void artwork_panel::ArtworkReaderManager::deinitialise()
m_current_reader->wait_for_and_release_thread();
m_current_reader.reset();
}
m_emptycover.reset();
m_stub_images.clear();
}

bool artwork_panel::ArtworkReaderManager::QueryEmptyCover(album_art_data_ptr& p_data)
album_art_data_ptr artwork_panel::ArtworkReaderManager::get_stub_image(GUID artwork_type_id)
{
if (IsReady() && m_emptycover.is_valid()) {
p_data = m_emptycover;
if (!IsReady())
return {};

if (const auto content_iter = m_stub_images.find(artwork_type_id); content_iter != m_stub_images.end()) {
return content_iter->second;
}

if (artwork_type_id == album_art_ids::cover_front)
return {};

if (const auto content_iter = m_stub_images.find(album_art_ids::cover_front); content_iter != m_stub_images.end()) {
return content_iter->second;
}
return p_data.is_valid();

return {};
}

bool artwork_panel::ArtworkReaderManager::Query(const GUID& p_what, album_art_data_ptr& p_data)
album_art_data_ptr artwork_panel::ArtworkReaderManager::get_image(const GUID& p_what)
{
if (IsReady() && m_current_reader->did_succeed()) {
auto&& content = m_current_reader->get_content();
auto content_iter = content.find(p_what);
if (content_iter != content.end()) {
p_data = content_iter->second;
return true;
}
}
return false;
if (!IsReady() || !m_current_reader->did_succeed())
return {};

auto&& content = m_current_reader->get_content();
const auto content_iter = content.find(p_what);
if (content_iter != content.end())
return content_iter->second;

return {};
}

void artwork_panel::ArtworkReaderManager::Request(
Expand All @@ -92,7 +103,7 @@ void artwork_panel::ArtworkReaderManager::Request(
m_current_reader = std::make_shared<ArtworkReader>();
m_current_reader->initialise(m_requestIds,
b_prev_valid ? ptr_prev->get_content() : std::unordered_map<GUID, album_art_data_ptr>(),
!m_emptycover.is_valid(), p_handle, p_notify, shared_from_this());
m_stub_images.empty(), p_handle, p_notify, shared_from_this());
m_current_reader->set_priority(THREAD_PRIORITY_BELOW_NORMAL);
m_current_reader->create_thread();
}
Expand All @@ -107,7 +118,7 @@ void artwork_panel::ArtworkReaderManager::Reset()
{
abort_current_task();
m_current_reader.reset();
m_emptycover.reset();
m_stub_images.clear();
}

void artwork_panel::ArtworkReaderManager::abort_current_task()
Expand Down Expand Up @@ -150,8 +161,8 @@ void artwork_panel::ArtworkReaderManager::on_reader_completion(DWORD state, cons
{
if (m_current_reader && ptr == &*m_current_reader) {
m_current_reader->wait_for_and_release_thread();
if (m_current_reader->get_emptycover().is_valid())
m_emptycover = m_current_reader->get_emptycover();
if (!m_current_reader->get_stub_images().empty())
m_stub_images = m_current_reader->get_stub_images();
m_current_reader->run_notification_thisthread(state);
// m_current_reader.release();
} else {
Expand Down Expand Up @@ -217,29 +228,24 @@ DWORD artwork_panel::ArtworkReader::on_thread()
return ret;
}

bool artwork_panel::g_get_album_art_extractor_interface(service_ptr_t<album_art_extractor>& out, const char* path)
album_art_data_ptr query_artwork_data(
GUID artwork_type_id, album_art_extractor_instance_v2::ptr extractor, abort_callback& aborter)
{
service_enum_t<album_art_extractor> e;
album_art_extractor::ptr ptr;
pfc::string_extension ext(path);
while (e.next(ptr)) {
if (ptr->is_our_path(path, ext)) {
out = ptr;
return true;
}
}
return false;
}
try {
album_art_data_ptr data = extractor->query(artwork_type_id, aborter);

album_art_extractor_instance_ptr artwork_panel::g_get_album_art_extractor_instance(
const char* path, abort_callback& p_abort)
{
album_art_extractor::ptr api;
if (artwork_panel::g_get_album_art_extractor_interface(api, path)) {
return api->open(nullptr, path, p_abort);
if (data->get_size() > 0)
return data;
} catch (const exception_aborted&) {
throw;
} catch (exception_album_art_not_found const&) {
} catch (exception_io const& ex) {
fbh::print_to_console(u8"Artwork view – error loading artwork: ", ex.what());
}
throw exception_album_art_not_found();

return {};
}

unsigned artwork_panel::ArtworkReader::read_artwork(abort_callback& p_abort)
{
TRACK_CALL_TEXT("artwork_reader_v2_t::read_artwork");
Expand All @@ -250,36 +256,32 @@ unsigned artwork_panel::ArtworkReader::read_artwork(abort_callback& p_abort)

pfc::list_t<GUID> guids;
guids.add_items_fromptr(m_requestIds.data(), m_requestIds.size());
auto artwork_api_v2
const auto artwork_api_v2
= p_album_art_manager_v2->open(pfc::list_single_ref_t<metadb_handle_ptr>(m_handle), guids, p_abort);

for (auto&& artwork_id : m_requestIds) {
try {
album_art_data_ptr data = artwork_api_v2->query(artwork_id, p_abort);
if (data->get_size() > 0)
m_content.insert_or_assign(artwork_id, data);
} catch (const exception_aborted&) {
throw;
} catch (exception_io_not_found const&) {
} catch (exception_io const& e) {
console::formatter formatter;
formatter << u8"Artwork view – error loading artwork: " << e.what();
}
const auto data = query_artwork_data(artwork_id, artwork_api_v2, p_abort);

if (data.is_valid())
m_content.insert_or_assign(artwork_id, data);
}

if (m_read_emptycover) {
try {
auto p_extractor = p_album_art_manager_v2->open_stub(p_abort);
// FIXME: We are always using the front no cover image
m_emptycover = p_extractor->query(album_art_ids::cover_front, p_abort);
} catch (const exception_aborted&) {
throw;
} catch (exception_io_not_found const&) {
} catch (exception_io const& e) {
console::formatter formatter;
formatter << u8"Artwork view – error loading no-cover image: " << e.what();
if (m_read_stub_image) {
const auto stub_extractor = p_album_art_manager_v2->open_stub(p_abort);

for (auto&& artwork_id : m_requestIds) {
const auto data = query_artwork_data(artwork_id, stub_extractor, p_abort);

if (data.is_valid())
m_stub_images.insert_or_assign(artwork_id, data);
}
if (!m_emptycover.is_valid() && pvt::g_get_default_nocover_bitmap_data(m_emptycover, p_abort)) {

if (m_stub_images.find(album_art_ids::cover_front) == m_stub_images.end()) {
album_art_data_ptr data;
pvt::g_get_default_nocover_bitmap_data(data, p_abort);

if (data.is_valid())
m_stub_images.insert_or_assign(album_art_ids::cover_front, data);
}
}
return isContentEqual(m_content, content_previous) ? 0 : 1;
Expand Down
18 changes: 7 additions & 11 deletions foo_ui_columns/artwork_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ class ArtworkReader : public mmh::Thread {
// only called when thread closed
bool did_succeed();
const std::unordered_map<GUID, album_art_data_ptr>& get_content() const;
const album_art_data_ptr& get_emptycover() const;
const std::unordered_map<GUID, album_art_data_ptr>& get_stub_images() const;

ArtworkReader() = default;

void initialise(const std::vector<GUID>& p_requestIds,
const std::unordered_map<GUID, album_art_data_ptr>& p_content_previous, bool b_read_emptycover,
const std::unordered_map<GUID, album_art_data_ptr>& p_content_previous, bool read_stub_image,
const metadb_handle_ptr& p_handle, const completion_notify_ptr& p_notify,
std::shared_ptr<class ArtworkReaderManager> p_manager);
void run_notification_thisthread(DWORD state);
Expand All @@ -30,11 +30,11 @@ class ArtworkReader : public mmh::Thread {

std::vector<GUID> m_requestIds;
std::unordered_map<GUID, album_art_data_ptr> m_content;
std::unordered_map<GUID, album_art_data_ptr> m_stub_images;
metadb_handle_ptr m_handle;
completion_notify_ptr m_notify;
bool m_succeeded{false};
bool m_read_emptycover{true};
album_art_data_ptr m_emptycover;
bool m_read_stub_image{true};
abort_callback_impl m_abort;
std::shared_ptr<class ArtworkReaderManager> m_manager;
};
Expand All @@ -52,9 +52,8 @@ class ArtworkReaderManager : public std::enable_shared_from_this<ArtworkReaderMa
//! advanced to another track with the same album art data).
void Request(const metadb_handle_ptr& p_handle, completion_notify_ptr p_notify = nullptr);

bool Query(const GUID& p_what, album_art_data_ptr& p_data);

bool QueryEmptyCover(album_art_data_ptr& p_data);
album_art_data_ptr get_image(const GUID& p_what);
album_art_data_ptr get_stub_image(GUID artwork_type_id);

void deinitialise();

Expand All @@ -68,7 +67,7 @@ class ArtworkReaderManager : public std::enable_shared_from_this<ArtworkReaderMa

std::vector<GUID> m_requestIds;
std::unordered_map<GUID, album_art_data_ptr> m_content;
album_art_data_ptr m_emptycover;
std::unordered_map<GUID, album_art_data_ptr> m_stub_images;
};

class ArtworkReaderNotification : public main_thread_callback {
Expand All @@ -84,7 +83,4 @@ class ArtworkReaderNotification : public main_thread_callback {
std::shared_ptr<ArtworkReaderManager> m_manager;
};

bool g_get_album_art_extractor_interface(service_ptr_t<album_art_extractor>& out, const char* path);
album_art_extractor_instance_ptr g_get_album_art_extractor_instance(const char* path, abort_callback& p_abort);

}; // namespace artwork_panel