annotate foosdk/sdk/foobar2000/SDK/album_art_helpers.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "album_art.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 //! Implements album_art_data.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 class album_art_data_impl : public album_art_data {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 const void * data() const override {return m_content.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 size_t size() const override {return m_content.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 const void * get_data() const { return m_content.get_ptr(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 size_t sizeget_() const { return m_content.get_size(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 void * get_ptr() {return m_content.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 void set_size(t_size p_size) {m_content.set_size(p_size);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 //! Reads picture data from the specified stream object.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 void from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 set_size(p_bytes); p_stream->read_object(get_ptr(),p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 //! Creates an album_art_data object from picture data contained in a memory buffer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 static album_art_data_ptr g_create(const void * p_buffer,t_size p_bytes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 service_ptr_t<album_art_data_impl> instance = new service_impl_t<album_art_data_impl>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 instance->set_size(p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 memcpy(instance->get_ptr(),p_buffer,p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 return instance;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 //! Creates an album_art_data object from picture data contained in a stream.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 static album_art_data_ptr g_create(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 service_ptr_t<album_art_data_impl> instance = new service_impl_t<album_art_data_impl>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 instance->from_stream(p_stream,p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 return instance;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 pfc::array_t<t_uint8> m_content;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 //! Helper - simple implementation of album_art_extractor_instance.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 class album_art_extractor_instance_simple : public album_art_extractor_instance {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 void set(const GUID & p_what,album_art_data_ptr p_content) {m_content.set(p_what,p_content);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 bool have_item(const GUID & p_what) {return m_content.have_item(p_what);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 album_art_data_ptr query(const GUID & p_what,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 album_art_data_ptr temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 if (!m_content.query(p_what,temp)) throw exception_album_art_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 return temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 bool is_empty() const {return m_content.get_count() == 0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 bool remove(const GUID & p_what) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 return m_content.remove(p_what);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 void remove_all() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 m_content.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 pfc::map_t<GUID,album_art_data_ptr> m_content;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 //! Helper implementation of album_art_extractor - reads album art from arbitrary file formats that comply with APEv2 tagging specification.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 class album_art_extractor_impl_stdtags : public album_art_extractor_v2 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 //! @param exts Semicolon-separated list of file format extensions to support.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 album_art_extractor_impl_stdtags(const char * exts, const GUID & guid) : m_guid(guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 pfc::splitStringSimple_toList(m_extensions,';',exts);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 bool is_our_path(const char * p_path,const char * p_extension) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 (void)p_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 return m_extensions.have_item(p_extension);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 album_art_extractor_instance_ptr open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 PFC_ASSERT( is_our_path(p_path, pfc::string_extension(p_path) ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 file_ptr l_file ( p_filehint );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 if (l_file.is_empty()) filesystem::g_open_read(l_file, p_path, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 return tag_processor_album_art_utils::get()->open( l_file, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 GUID get_guid() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 return m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 pfc::avltree_t<pfc::string,pfc::string::comparatorCaseInsensitiveASCII> m_extensions;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 const GUID m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 //! Helper implementation of album_art_editor - edits album art from arbitrary file formats that comply with APEv2 tagging specification.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 class album_art_editor_impl_stdtags : public album_art_editor_v2 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 //! @param exts Semicolon-separated list of file format extensions to support.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 album_art_editor_impl_stdtags(const char * exts, const GUID & guid) : m_guid(guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 pfc::splitStringSimple_toList(m_extensions,';',exts);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 bool is_our_path(const char * p_path,const char * p_extension) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 (void)p_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 return m_extensions.have_item(p_extension);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 album_art_editor_instance_ptr open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 PFC_ASSERT( is_our_path(p_path, pfc::string_extension(p_path) ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 file_ptr l_file ( p_filehint );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 if (l_file.is_empty()) filesystem::g_open(l_file, p_path, filesystem::open_mode_write_existing, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 return tag_processor_album_art_utils::get()->edit( l_file, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 GUID get_guid() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 return m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 pfc::avltree_t<pfc::string,pfc::string::comparatorCaseInsensitiveASCII> m_extensions;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 const GUID m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 //! Helper - a more advanced implementation of album_art_extractor_instance.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 class album_art_extractor_instance_fileref : public album_art_extractor_instance {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 album_art_extractor_instance_fileref(file::ptr f) : m_file(f) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 void set(const GUID & p_what,t_filesize p_offset, t_filesize p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 const t_fileref ref = {p_offset, p_size};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 m_data.set(p_what, ref);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 m_cache.remove(p_what);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 bool have_item(const GUID & p_what) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 return m_data.have_item(p_what);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 album_art_data_ptr query(const GUID & p_what,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 album_art_data_ptr item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 if (m_cache.query(p_what,item)) return item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 t_fileref ref;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 if (!m_data.query(p_what, ref)) throw exception_album_art_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 m_file->seek(ref.m_offset, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 item = album_art_data_impl::g_create(m_file.get_ptr(), pfc::downcast_guarded<t_size>(ref.m_size), p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 m_cache.set(p_what, item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 return item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 bool is_empty() const {return m_data.get_count() == 0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 struct t_fileref {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 t_filesize m_offset, m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 const file::ptr m_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 pfc::map_t<GUID, t_fileref> m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 pfc::map_t<GUID, album_art_data::ptr> m_cache;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 //! album_art_path_list implementation helper
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 class album_art_path_list_impl : public album_art_path_list {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 album_art_path_list_impl(const char* single) { m_data.set_size(1); m_data[0] = single; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 template<typename t_in> album_art_path_list_impl(const t_in & in) {pfc::list_to_array(m_data, in);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 const char * get_path(t_size index) const {return m_data[index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 t_size get_count() const {return m_data.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 pfc::array_t<pfc::string8> m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 //! album_art_path_list implementation helper
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 class album_art_path_list_dummy : public album_art_path_list {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 const char * get_path(t_size) const override {FB2K_BugCheck();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 t_size get_count() const override {return 0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 };