00001
00002
00003
00008 class NOVTABLE album_art_data : public service_base {
00009 public:
00011 virtual const void * get_ptr() const = 0;
00013 virtual t_size get_size() const = 0;
00014
00016 static bool equals(album_art_data const & v1, album_art_data const & v2) {
00017 const t_size s = v1.get_size();
00018 if (s != v2.get_size()) return false;
00019 return memcmp(v1.get_ptr(), v2.get_ptr(),s) == 0;
00020 }
00021 bool operator==(const album_art_data & other) const {return equals(*this,other);}
00022 bool operator!=(const album_art_data & other) const {return !equals(*this,other);}
00023
00024 FB2K_MAKE_SERVICE_INTERFACE(album_art_data,service_base);
00025 };
00026
00027 typedef service_ptr_t<album_art_data> album_art_data_ptr;
00028
00031 class album_art_data_impl : public album_art_data {
00032 public:
00033 const void * get_ptr() const {return m_content.get_ptr();}
00034 t_size get_size() const {return m_content.get_size();}
00035
00036 void * get_ptr() {return m_content.get_ptr();}
00037 void set_size(t_size p_size) {m_content.set_size(p_size);}
00038
00040 void from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
00041 set_size(p_bytes); p_stream->read_object(get_ptr(),p_bytes,p_abort);
00042 }
00043
00045 static album_art_data_ptr g_create(const void * p_buffer,t_size p_bytes) {
00046 service_ptr_t<album_art_data_impl> instance = new service_impl_t<album_art_data_impl>();
00047 instance->set_size(p_bytes);
00048 memcpy(instance->get_ptr(),p_buffer,p_bytes);
00049 return instance;
00050 }
00052 static album_art_data_ptr g_create(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
00053 service_ptr_t<album_art_data_impl> instance = new service_impl_t<album_art_data_impl>();
00054 instance->from_stream(p_stream,p_bytes,p_abort);
00055 return instance;
00056 }
00057
00058 private:
00059 pfc::array_t<t_uint8> m_content;
00060 };
00061
00064 namespace album_art_ids {
00066 static const GUID cover_front = { 0xf1e66f4e, 0xfe09, 0x4b94, { 0x91, 0xa3, 0x67, 0xc2, 0x3e, 0xd1, 0x44, 0x5e } };
00068 static const GUID cover_back = { 0xcb552d19, 0x86d5, 0x434c, { 0xac, 0x77, 0xbb, 0x24, 0xed, 0x56, 0x7e, 0xe4 } };
00070 static const GUID disc = { 0x3dba9f36, 0xf928, 0x4fa4, { 0x87, 0x9c, 0xd3, 0x40, 0x47, 0x59, 0x58, 0x7e } };
00072 static const GUID icon = { 0x74cdf5b4, 0x7053, 0x4b3d, { 0x9a, 0x3c, 0x54, 0x69, 0xf5, 0x82, 0x6e, 0xec } };
00073 };
00074
00075 PFC_DECLARE_EXCEPTION(exception_album_art_not_found,exception_io_not_found,"Album Art Not Found");
00076 PFC_DECLARE_EXCEPTION(exception_album_art_unsupported_entry,exception_io_data,"Unsupported Album Art Entry");
00077
00080 class NOVTABLE album_art_extractor_instance : public service_base {
00081 public:
00083 virtual album_art_data_ptr query(const GUID & p_what,abort_callback & p_abort) = 0;
00084
00085 FB2K_MAKE_SERVICE_INTERFACE(album_art_extractor_instance,service_base);
00086 };
00087
00090 class NOVTABLE album_art_editor_instance : public album_art_extractor_instance {
00091 public:
00093 virtual void set(const GUID & p_what,album_art_data_ptr p_data,abort_callback & p_abort) = 0;
00094
00096 virtual void remove(const GUID & p_what) = 0;
00097
00099 virtual void commit(abort_callback & p_abort) = 0;
00100
00101
00102 FB2K_MAKE_SERVICE_INTERFACE(album_art_editor_instance,album_art_extractor_instance);
00103 };
00104
00105 typedef service_ptr_t<album_art_extractor_instance> album_art_extractor_instance_ptr;
00106 typedef service_ptr_t<album_art_editor_instance> album_art_editor_instance_ptr;
00107
00111 class NOVTABLE album_art_extractor : public service_base {
00112 public:
00116 virtual bool is_our_path(const char * p_path,const char * p_extension) = 0;
00117
00121 virtual album_art_extractor_instance_ptr open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) = 0;
00122
00123 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(album_art_extractor);
00124 };
00125
00128 class NOVTABLE album_art_editor : public service_base {
00129 public:
00133 virtual bool is_our_path(const char * p_path,const char * p_extension) = 0;
00134
00137 virtual album_art_editor_instance_ptr open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) = 0;
00138
00141 static bool g_get_interface(service_ptr_t<album_art_editor> & out,const char * path);
00143 static bool g_is_supported_path(const char * path);
00144
00145 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(album_art_editor);
00146 };
00147
00154 class NOVTABLE album_art_manager_instance : public service_base {
00155 public:
00157 virtual bool open(const char * p_file,abort_callback & p_abort) = 0;
00159 virtual void close() = 0;
00160
00162 virtual album_art_data_ptr query(const GUID & p_what,abort_callback & p_abort) = 0;
00163
00166 virtual album_art_data_ptr query_stub_image(abort_callback & p_abort) = 0;
00167
00168 FB2K_MAKE_SERVICE_INTERFACE(album_art_manager_instance,service_base);
00169 };
00170
00171 typedef service_ptr_t<album_art_manager_instance> album_art_manager_instance_ptr;
00172
00175 class NOVTABLE album_art_manager : public service_base {
00176 public:
00177 virtual album_art_manager_instance_ptr instantiate() = 0;
00178
00179 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(album_art_manager);
00180 };
00181
00182
00185 class album_art_extractor_instance_simple : public album_art_extractor_instance {
00186 public:
00187 void set(const GUID & p_what,album_art_data_ptr p_content) {m_content.set(p_what,p_content);}
00188 bool have_item(const GUID & p_what) {return m_content.have_item(p_what);}
00189 album_art_data_ptr query(const GUID & p_what,abort_callback & p_abort) {
00190 album_art_data_ptr temp;
00191 if (!m_content.query(p_what,temp)) throw exception_album_art_not_found();
00192 return temp;
00193 }
00194 bool is_empty() const {return m_content.get_count() == 0;}
00195 private:
00196 pfc::map_t<GUID,album_art_data_ptr> m_content;
00197 };
00198
00201 class NOVTABLE tag_processor_album_art_utils : public service_base {
00202 public:
00203
00205 virtual album_art_extractor_instance_ptr open(file_ptr p_file,abort_callback & p_abort) = 0;
00206
00208 virtual album_art_editor_instance_ptr edit(file_ptr p_file,abort_callback & p_abort) = 0;
00209
00210 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(tag_processor_album_art_utils)
00211 };
00212
00215 class album_art_extractor_impl_stdtags : public album_art_extractor {
00216 public:
00218 album_art_extractor_impl_stdtags(const char * exts) {
00219 pfc::splitStringSimple_toList(m_extensions,";",exts);
00220 }
00221
00222 bool is_our_path(const char * p_path,const char * p_extension) {
00223 return m_extensions.have_item(p_extension);
00224 }
00225
00226 album_art_extractor_instance_ptr open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) {
00227 PFC_ASSERT( is_our_path(p_path, pfc::string_extension(p_path) ) );
00228 file_ptr l_file ( p_filehint );
00229 if (l_file.is_empty()) filesystem::g_open_read(l_file, p_path, p_abort);
00230 return static_api_ptr_t<tag_processor_album_art_utils>()->open( l_file, p_abort );
00231 }
00232 private:
00233 pfc::avltree_t<pfc::string,pfc::string::comparatorCaseInsensitiveASCII> m_extensions;
00234 };