|
1
|
1 #include "foobar2000-sdk-pch.h"
|
|
|
2 #include "image.h"
|
|
|
3 #include "album_art.h"
|
|
|
4 #include "album_art_helpers.h"
|
|
|
5 #include "input.h"
|
|
|
6
|
|
|
7 GUID album_art_extractor::get_guid() {
|
|
|
8 album_art_extractor_v2::ptr v2;
|
|
|
9 if ( v2 &= this ) return v2->get_guid();
|
|
|
10 return pfc::guid_null;
|
|
|
11 }
|
|
|
12
|
|
|
13 GUID album_art_editor::get_guid() {
|
|
|
14 album_art_editor_v2::ptr v2;
|
|
|
15 if ( v2 &= this ) return v2->get_guid();
|
|
|
16 return pfc::guid_null;
|
|
|
17 }
|
|
|
18
|
|
|
19 bool album_art_extractor_instance::query(const GUID & what, album_art_data::ptr & out, abort_callback & abort) {
|
|
|
20 try { out = query(what, abort); return true; } catch (exception_album_art_not_found const &) { return false; }
|
|
|
21 }
|
|
|
22
|
|
|
23 service_ptr_t<fb2k::image> album_art_extractor_instance::query_image_(const GUID & what, abort_callback& a) {
|
|
|
24 auto data = this->query(what, a);
|
|
|
25 return fb2k::imageCreator::get()->loadImageData( data);
|
|
|
26 }
|
|
|
27
|
|
|
28 bool album_art_extractor_instance::have_entry(const GUID & what, abort_callback & abort) {
|
|
|
29 try { query(what, abort); return true; } catch(exception_album_art_not_found const &) { return false; }
|
|
|
30 }
|
|
|
31
|
|
|
32 void album_art_editor_instance::remove_all_() {
|
|
|
33 album_art_editor_instance_v2::ptr v2;
|
|
|
34 if ( v2 &= this ) {
|
|
|
35 v2->remove_all();
|
|
|
36 } else {
|
|
|
37 for( size_t walk = 0; walk < album_art_ids::num_types(); ++ walk ) {
|
|
|
38 try {
|
|
|
39 this->remove( album_art_ids::query_type( walk ) );
|
|
|
40 } catch(exception_io_data const &) {}
|
|
|
41 catch(exception_album_art_not_found const &) {}
|
|
|
42 }
|
|
|
43 }
|
|
|
44 }
|
|
|
45
|
|
|
46 bool album_art_editor::g_get_interface(service_ptr_t<album_art_editor> & out,const char * path) {
|
|
|
47 auto ext = pfc::string_extension(path);
|
|
|
48 for (auto ptr : enumerate()) {
|
|
|
49 if (ptr->is_our_path(path, ext)) { out = ptr; return true; }
|
|
|
50 }
|
|
|
51 return false;
|
|
|
52 }
|
|
|
53
|
|
|
54 bool album_art_editor::g_is_supported_path(const char * path) {
|
|
|
55 ptr ptr; return g_get_interface(ptr,path);
|
|
|
56 }
|
|
|
57
|
|
|
58 album_art_editor_instance_ptr album_art_editor::g_open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) {
|
|
|
59
|
|
|
60 #ifdef FOOBAR2000_DESKTOP
|
|
|
61 {
|
|
|
62 input_manager_v2::ptr m;
|
|
|
63 if (fb2k::std_api_try_get(m)) {
|
|
|
64 album_art_editor_instance::ptr ret;
|
|
|
65 ret ^= m->open_v2(album_art_editor_instance::class_guid, p_filehint, p_path, false, nullptr, p_abort);
|
|
|
66 return ret;
|
|
|
67 }
|
|
|
68 }
|
|
|
69 #endif
|
|
|
70
|
|
|
71 album_art_editor::ptr obj;
|
|
|
72 if (!g_get_interface(obj, p_path)) throw exception_album_art_unsupported_format();
|
|
|
73 return obj->open(p_filehint, p_path, p_abort);
|
|
|
74 }
|
|
|
75
|
|
|
76
|
|
|
77 bool album_art_extractor::g_get_interface(service_ptr_t<album_art_extractor> & out,const char * path) {
|
|
|
78
|
|
|
79 auto ext = pfc::string_extension(path);
|
|
|
80 for (auto ptr : enumerate()) {
|
|
|
81 if (ptr->is_our_path(path, ext)) { out = ptr; return true; }
|
|
|
82 }
|
|
|
83 return false;
|
|
|
84 }
|
|
|
85
|
|
|
86 bool album_art_extractor::g_is_supported_path(const char * path) {
|
|
|
87 ptr ptr; return g_get_interface(ptr,path);
|
|
|
88 }
|
|
|
89 album_art_extractor_instance_ptr album_art_extractor::g_open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) {
|
|
|
90 #ifdef FOOBAR2000_DESKTOP
|
|
|
91 {
|
|
|
92 input_manager_v2::ptr m;
|
|
|
93 if (fb2k::std_api_try_get(m)) {
|
|
|
94 album_art_extractor_instance::ptr ret;
|
|
|
95 ret ^= m->open_v2(album_art_extractor_instance::class_guid, p_filehint, p_path, false, nullptr, p_abort);
|
|
|
96 return ret;
|
|
|
97 }
|
|
|
98 }
|
|
|
99 #endif
|
|
|
100
|
|
|
101 album_art_extractor::ptr obj;
|
|
|
102 if (!g_get_interface(obj, p_path)) throw exception_album_art_unsupported_format();
|
|
|
103 return obj->open(p_filehint, p_path, p_abort);
|
|
|
104 }
|
|
|
105
|
|
|
106
|
|
|
107 album_art_extractor_instance_ptr album_art_extractor::g_open_allowempty(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) {
|
|
|
108 try {
|
|
|
109 return g_open(p_filehint, p_path, p_abort);
|
|
|
110 } catch(exception_album_art_not_found const &) {
|
|
|
111 return new service_impl_t<album_art_extractor_instance_simple>();
|
|
|
112 }
|
|
|
113 }
|
|
|
114
|
|
|
115 namespace {
|
|
|
116 class now_playing_album_art_notify_lambda : public now_playing_album_art_notify {
|
|
|
117 public:
|
|
|
118 void on_album_art(album_art_data::ptr data) {
|
|
|
119 f(data);
|
|
|
120 }
|
|
|
121 std::function<void(album_art_data::ptr) > f;
|
|
|
122 };
|
|
|
123 }
|
|
|
124
|
|
|
125 now_playing_album_art_notify * now_playing_album_art_notify_manager::add(std::function<void (album_art_data::ptr) > f ) {
|
|
|
126 PFC_ASSERT ( f != nullptr );
|
|
|
127 auto obj = new now_playing_album_art_notify_lambda;
|
|
|
128 obj->f = f;
|
|
|
129 add(obj);
|
|
|
130 return obj;
|
|
|
131 }
|
|
|
132
|
|
|
133 namespace {
|
|
|
134 struct aa_t {
|
|
|
135 GUID type; const char * name;
|
|
|
136 };
|
|
|
137 static const GUID guids[] = {
|
|
|
138 album_art_ids::cover_front,
|
|
|
139 album_art_ids::cover_back,
|
|
|
140 album_art_ids::artist,
|
|
|
141 album_art_ids::disc,
|
|
|
142 album_art_ids::icon,
|
|
|
143 };
|
|
|
144 static const char * const names[] = {
|
|
|
145 "front cover",
|
|
|
146 "back cover",
|
|
|
147 "artist",
|
|
|
148 "disc",
|
|
|
149 "icon"
|
|
|
150 };
|
|
|
151 static const char * const names2[] = {
|
|
|
152 "Front Cover",
|
|
|
153 "Back Cover",
|
|
|
154 "Artist",
|
|
|
155 "Disc",
|
|
|
156 "Icon"
|
|
|
157 };
|
|
|
158 }
|
|
|
159
|
|
|
160 size_t album_art_ids::num_types() {
|
|
|
161 PFC_STATIC_ASSERT( PFC_TABSIZE( guids ) == PFC_TABSIZE( names ) );
|
|
|
162 PFC_STATIC_ASSERT( PFC_TABSIZE( guids ) == PFC_TABSIZE( names2 ) );
|
|
|
163 return PFC_TABSIZE( guids );
|
|
|
164 }
|
|
|
165
|
|
|
166 GUID album_art_ids::query_type(size_t idx) {
|
|
|
167 PFC_ASSERT( idx < PFC_TABSIZE( guids ) );
|
|
|
168 return guids[idx];
|
|
|
169 }
|
|
|
170
|
|
|
171 const char * album_art_ids::query_name(size_t idx) {
|
|
|
172 PFC_ASSERT( idx < PFC_TABSIZE( names ) );
|
|
|
173 return names[idx];
|
|
|
174 }
|
|
|
175
|
|
|
176 const char* album_art_ids::name_of_ex(const GUID& id, const char* def) {
|
|
|
177 auto ret = name_of(id);
|
|
|
178 if ( ret == nullptr ) ret = def;
|
|
|
179 return ret;
|
|
|
180 }
|
|
|
181
|
|
|
182 const char * album_art_ids::name_of(const GUID & id) {
|
|
|
183 for( size_t w = 0; w < num_types(); ++w ) {
|
|
|
184 if ( query_type(w) == id ) return query_name(w);
|
|
|
185 }
|
|
|
186 return nullptr;
|
|
|
187 }
|
|
|
188
|
|
|
189 const char * album_art_ids::query_capitalized_name( size_t idx ) {
|
|
|
190 PFC_ASSERT( idx < PFC_TABSIZE( names2 ) );
|
|
|
191 return names2[idx];
|
|
|
192 }
|
|
|
193
|
|
|
194 const char * album_art_ids::capitalized_name_of( const GUID & id) {
|
|
|
195 for( size_t w = 0; w < num_types(); ++w ) {
|
|
|
196 if ( query_type(w) == id ) return query_capitalized_name(w);
|
|
|
197 }
|
|
|
198 return nullptr;
|
|
|
199 }
|
|
|
200
|
|
|
201 GUID album_art_ids::by_name(const char* arg) {
|
|
|
202 for (size_t w = 0; w < num_types(); ++w) {
|
|
|
203 if (pfc::stringEqualsI_ascii(query_name(w), arg)) return query_type(w);
|
|
|
204 }
|
|
|
205 return pfc::guid_null;
|
|
|
206 }
|
|
|
207
|
|
|
208 bool album_art_path_list::equals(album_art_path_list const& v1, album_art_path_list const& v2) {
|
|
|
209 const size_t n = v1.get_count();
|
|
|
210 if (n != v2.get_count()) return false;
|
|
|
211 for (size_t w = 0; w < n; ++w) {
|
|
|
212 if (playable_location::path_compare(v1.get_path(w), v2.get_path(w)) != 0) return false;
|
|
|
213 }
|
|
|
214 return true;
|
|
|
215 }
|
|
|
216
|
|
|
217 bool album_art_path_list::equals(ptr const& v1, ptr const& v2) {
|
|
|
218 if (v1.is_valid() != v2.is_valid()) return false;
|
|
|
219 if (v1.is_empty() && v2.is_empty()) return true;
|
|
|
220 return equals(*v1, *v2);
|
|
|
221 }
|