AlbumArt.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include "main.h"
  2. #include "Metadata.h"
  3. #include "api__in_mp3.h"
  4. #include "../nu/AutoWide.h"
  5. #include "AlbumArt.h"
  6. #include "Stopper.h"
  7. #include <shlwapi.h>
  8. #include <strsafe.h>
  9. bool IsMyExtension(const wchar_t *filename)
  10. {
  11. // check if it's the current stream and is playing and is SHOUTcast2
  12. if (PathIsURLW(filename))
  13. {
  14. if (g_playing_file)
  15. {
  16. EnterCriticalSection(&streamInfoLock);
  17. if (g_playing_file &&
  18. (g_playing_file->uvox_artwork.uvox_stream_artwork || g_playing_file->uvox_artwork.uvox_playing_artwork) &&
  19. !lstrcmpW(lastfn, filename)) // check again now that we've acquired the lock
  20. {
  21. LeaveCriticalSection(&streamInfoLock);
  22. return true;
  23. }
  24. LeaveCriticalSection(&streamInfoLock);
  25. }
  26. }
  27. // otherwise handle as normal embedded
  28. else
  29. {
  30. const wchar_t *extension = PathFindExtension(filename);
  31. if (extension && *extension)
  32. {
  33. AutoWide wideList(config_extlist); // TODO: build a copy of this at config load time so we don't have to run this every time
  34. extension++;
  35. wchar_t *b = wideList;
  36. wchar_t *c = 0;
  37. do
  38. {
  39. wchar_t d[20] = {0};
  40. StringCchCopyW(d, 15, b);
  41. if ((c = wcschr(b, L';')))
  42. {
  43. if ((c-b)<15)
  44. d[c - b] = 0;
  45. }
  46. if (!lstrcmpiW(extension, d))
  47. return true;
  48. b = c + 1;
  49. }
  50. while (c);
  51. }
  52. }
  53. return false;
  54. }
  55. bool ID3v2_AlbumArtProvider::IsMine(const wchar_t *filename)
  56. {
  57. return IsMyExtension(filename);
  58. }
  59. int ID3v2_AlbumArtProvider::ProviderType()
  60. {
  61. return ALBUMARTPROVIDER_TYPE_EMBEDDED;
  62. }
  63. int ID3v2_AlbumArtProvider::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType)
  64. {
  65. if (g_playing_file)
  66. {
  67. EnterCriticalSection(&streamInfoLock);
  68. if (g_playing_file && !lstrcmpW(lastfn, filename)) // check again now that we've acquired the lock
  69. {
  70. wchar_t* mimeType[] = {
  71. L"image/jpeg",
  72. L"image/png",
  73. L"image/bmp",
  74. L"image/gif"
  75. };
  76. if (!g_playing_file->uvox_artwork.uvox_stream_artwork)
  77. {
  78. int ret = g_playing_file->info.GetAlbumArt(type, bits, len, mimeType);
  79. LeaveCriticalSection(&streamInfoLock);
  80. return ret;
  81. }
  82. else
  83. {
  84. // will handle "playing" and "cover" - cover is the stream branding
  85. // with "playing" used to provide song specific stream artwork
  86. if (!_wcsicmp(type, L"playing"))
  87. {
  88. if (g_playing_file->uvox_artwork.uvox_playing_artwork_len > 0)
  89. {
  90. *len = g_playing_file->uvox_artwork.uvox_playing_artwork_len;
  91. int type = g_playing_file->uvox_artwork.uvox_playing_artwork_type;
  92. if(type >= 0 && type <= 3)
  93. {
  94. *mimeType = (wchar_t *)WASABI_API_MEMMGR->sysMalloc(12 * sizeof(wchar_t));
  95. wcsncpy(*mimeType, mimeType[type], 12);
  96. }
  97. else
  98. {
  99. *mimeType = 0;
  100. }
  101. *bits = WASABI_API_MEMMGR->sysMalloc(*len);
  102. memcpy(*bits, g_playing_file->uvox_artwork.uvox_playing_artwork, *len);
  103. LeaveCriticalSection(&streamInfoLock);
  104. return ALBUMARTPROVIDER_SUCCESS;
  105. }
  106. else
  107. {
  108. LeaveCriticalSection(&streamInfoLock);
  109. return ALBUMARTPROVIDER_FAILURE;
  110. }
  111. }
  112. else
  113. {
  114. if (g_playing_file->uvox_artwork.uvox_stream_artwork_len > 0)
  115. {
  116. *len = g_playing_file->uvox_artwork.uvox_stream_artwork_len;
  117. int type = g_playing_file->uvox_artwork.uvox_stream_artwork_type;
  118. if(type >= 0 && type <= 3)
  119. {
  120. *mimeType = (wchar_t *)WASABI_API_MEMMGR->sysMalloc(12 * sizeof(wchar_t));
  121. wcsncpy(*mimeType, mimeType[type], 12);
  122. }
  123. else
  124. {
  125. *mimeType = 0;
  126. }
  127. *bits = WASABI_API_MEMMGR->sysMalloc(*len);
  128. memcpy(*bits, g_playing_file->uvox_artwork.uvox_stream_artwork, *len);
  129. LeaveCriticalSection(&streamInfoLock);
  130. return ALBUMARTPROVIDER_SUCCESS;
  131. }
  132. else
  133. {
  134. LeaveCriticalSection(&streamInfoLock);
  135. return ALBUMARTPROVIDER_FAILURE;
  136. }
  137. }
  138. }
  139. }
  140. LeaveCriticalSection(&streamInfoLock);
  141. }
  142. Metadata metadata;
  143. if (metadata.Open(filename) == METADATA_SUCCESS)
  144. {
  145. return metadata.id3v2.GetAlbumArt(type, bits, len, mimeType);
  146. }
  147. return ALBUMARTPROVIDER_FAILURE;
  148. }
  149. extern Metadata *m_ext_get_mp3info;
  150. int ID3v2_AlbumArtProvider::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType)
  151. {
  152. Metadata metadata;
  153. if (metadata.Open(filename) == METADATA_SUCCESS)
  154. {
  155. int ret = metadata.id3v2.SetAlbumArt(type, bits, len, mimeType);
  156. if (ret == METADATA_SUCCESS)
  157. {
  158. // flush our read cache too :)
  159. if (m_ext_get_mp3info) m_ext_get_mp3info->Release();
  160. m_ext_get_mp3info = NULL;
  161. Stopper stopper;
  162. if (metadata.IsMe(lastfn))
  163. stopper.Stop();
  164. metadata.Save();
  165. stopper.Play();
  166. }
  167. return ret;
  168. }
  169. return ALBUMARTPROVIDER_FAILURE;
  170. }
  171. int ID3v2_AlbumArtProvider::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
  172. {
  173. Metadata metadata;
  174. if (metadata.Open(filename) == METADATA_SUCCESS)
  175. {
  176. int ret = metadata.id3v2.DeleteAlbumArt(type);
  177. if (ret == METADATA_SUCCESS)
  178. {
  179. // flush our read cache too :)
  180. if (m_ext_get_mp3info) m_ext_get_mp3info->Release();
  181. m_ext_get_mp3info = NULL;
  182. Stopper stopper;
  183. if (metadata.IsMe(lastfn))
  184. stopper.Stop();
  185. metadata.Save();
  186. stopper.Play();
  187. }
  188. return ret;
  189. }
  190. return ALBUMARTPROVIDER_FAILURE;
  191. }
  192. #define CBCLASS ID3v2_AlbumArtProvider
  193. START_DISPATCH;
  194. CB(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, ProviderType);
  195. CB(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, GetAlbumArtData);
  196. CB(SVC_ALBUMARTPROVIDER_ISMINE, IsMine);
  197. CB(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, SetAlbumArtData);
  198. CB(SVC_ALBUMARTPROVIDER_DELETEALBUMART, DeleteAlbumArt);
  199. END_DISPATCH;
  200. #undef CBCLASS
  201. static ID3v2_AlbumArtProvider albumArtProvider;
  202. // {C8222317-8F0D-4e79-9222-447381C46E07}
  203. static const GUID id3v2_albumartproviderGUID =
  204. { 0xc8222317, 0x8f0d, 0x4e79, { 0x92, 0x22, 0x44, 0x73, 0x81, 0xc4, 0x6e, 0x7 } };
  205. FOURCC AlbumArtFactory::GetServiceType()
  206. {
  207. return svc_albumArtProvider::SERVICETYPE;
  208. }
  209. const char *AlbumArtFactory::GetServiceName()
  210. {
  211. return "ID3v2 Album Art Provider";
  212. }
  213. GUID AlbumArtFactory::GetGUID()
  214. {
  215. return id3v2_albumartproviderGUID;
  216. }
  217. void *AlbumArtFactory::GetInterface(int global_lock)
  218. {
  219. return &albumArtProvider;
  220. }
  221. int AlbumArtFactory::SupportNonLockingInterface()
  222. {
  223. return 1;
  224. }
  225. int AlbumArtFactory::ReleaseInterface(void *ifc)
  226. {
  227. //plugin.service->service_unlock(ifc);
  228. return 1;
  229. }
  230. const char *AlbumArtFactory::GetTestString()
  231. {
  232. return 0;
  233. }
  234. int AlbumArtFactory::ServiceNotify(int msg, int param1, int param2)
  235. {
  236. return 1;
  237. }
  238. #ifdef CBCLASS
  239. #undef CBCLASS
  240. #endif
  241. #define CBCLASS AlbumArtFactory
  242. START_DISPATCH;
  243. CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
  244. CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
  245. CB(WASERVICEFACTORY_GETGUID, GetGUID)
  246. CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
  247. CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
  248. CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
  249. CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
  250. CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
  251. END_DISPATCH;