123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #include "nsid3v2.h"
- #include "nsid3v2/header.h"
- #include "nsid3v2/tag.h"
- #include "nsid3v2/frame_utils.h"
- #include <api/memmgr/api_memmgr.h>
- #include <strsafe.h>
- struct ParsedPicture
- {
- uint8_t encoding; // 0 - iso-8859-1, 1 - UTF16LE, 2 - UTF16BE, 3 - UTF8
- const char *mime_type;
- size_t mime_cch;
- uint8_t picture_type;
- union
- {
- const char *as8;
- const wchar_t *as16;
- } description_data;
- size_t description_cch;
- const void *picture_data;
- size_t picture_bytes;
- };
- static int ParsePicture(const void *data, size_t data_len, ParsedPicture &parsed)
- {
- const uint8_t *data8 = (const uint8_t *)data;
- parsed.encoding = data8[0];
- parsed.mime_type = (const char *)&data8[1];
- data_len--;
- ParseDescription(parsed.mime_type, data_len, parsed.mime_cch);
- parsed.picture_type = data8[2+parsed.mime_cch];
- data_len--;
- switch(parsed.encoding)
- {
- case 0: // ISO-8859-1
- ParseDescription(parsed.description_data.as8, parsed.description_cch, data_len);
- parsed.picture_data = parsed.description_data.as8 + parsed.description_cch + 1;
- parsed.picture_bytes = data_len;
- return NErr_Success;
- case 1: // UTF-16
- ParseDescription(parsed.description_data.as16, parsed.description_cch, data_len, parsed.encoding);
- parsed.picture_data = parsed.description_data.as8 + parsed.description_cch + 1;
- parsed.picture_bytes = data_len;
- return NErr_Success;
- case 2: // UTF-16 BE
- ParseDescription(parsed.description_data.as16, parsed.description_cch, data_len, parsed.encoding);
- parsed.picture_data = parsed.description_data.as8 + parsed.description_cch + 1;
- parsed.picture_bytes = data_len;
- return NErr_Success;
- case 3: // UTF-8
- ParseDescription(parsed.description_data.as8, parsed.description_cch, data_len);
- parsed.picture_data = parsed.description_data.as8 + parsed.description_cch + 1;
- parsed.picture_bytes = data_len;
- return NErr_Success;
- }
- return NErr_NotImplemented;
- }
- int NSID3v2_Tag_APIC_GetPicture(const nsid3v2_tag_t t, uint8_t picture_type, void *_memmgr, wchar_t **mime_type, void **picture_data, size_t *picture_bytes)
- {
- api_memmgr *memmgr = (api_memmgr *)_memmgr;
- const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
- const ID3v2::Frame *frame = tag->FindFirstFrame(NSID3V2_FRAME_PICTURE);
- while (frame)
- {
- const void *data;
- size_t data_len;
- ParsedPicture parsed;
- if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePicture(data, data_len, parsed) == NErr_Success && parsed.picture_type == picture_type)
- {
- const char *type = strchr(parsed.mime_type, '/');
- if (type && *type)
- {
- type++;
- int typelen = MultiByteToWideChar(CP_ACP, 0, type, -1, 0, 0);
- *mime_type = (wchar_t *)memmgr->sysMalloc(typelen * sizeof(wchar_t));
- MultiByteToWideChar(CP_ACP, 0, type, -1, *mime_type, typelen);
- }
- else
- *mime_type = 0; // unknown!
- *picture_bytes = parsed.picture_bytes;
- *picture_data = memmgr->sysMalloc(parsed.picture_bytes);
- memcpy(*picture_data, parsed.picture_data, parsed.picture_bytes);
- return NErr_Success;
- }
- frame = tag->FindNextFrame(frame);
- }
- return NErr_Error;
- }
- int NSID3v2_Tag_APIC_GetFirstPicture(const nsid3v2_tag_t t, void *_memmgr, wchar_t **mime_type, void **picture_data, size_t *picture_bytes)
- {
- api_memmgr *memmgr = (api_memmgr *)_memmgr;
- const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
- const ID3v2::Frame *frame = tag->FindFirstFrame(NSID3V2_FRAME_PICTURE);
- while (frame)
- {
- const void *data;
- size_t data_len;
- ParsedPicture parsed;
- if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePicture(data, data_len, parsed) == NErr_Success)
- {
- const char *type = strchr(parsed.mime_type, '/');
- if (type && *type)
- {
- type++;
- int typelen = MultiByteToWideChar(CP_ACP, 0, type, -1, 0, 0);
- *mime_type = (wchar_t *)memmgr->sysMalloc(typelen * sizeof(wchar_t));
- MultiByteToWideChar(CP_ACP, 0, type, -1, *mime_type, typelen);
- }
- else
- *mime_type = 0; // unknown!
- *picture_bytes = parsed.picture_bytes;
- *picture_data = memmgr->sysMalloc(parsed.picture_bytes);
- memcpy(*picture_data, parsed.picture_data, parsed.picture_bytes);
- return NErr_Success;
- }
- frame = tag->FindNextFrame(frame);
- }
- return NErr_Error;
- }
- int NSID3v2_Tag_APIC_GetFrame(const nsid3v2_tag_t t, uint8_t picture_type, nsid3v2_frame_t *f)
- {
- const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
- const ID3v2::Frame *frame = tag->FindFirstFrame(NSID3V2_FRAME_PICTURE);
- while (frame)
- {
- const void *data;
- size_t data_len;
- ParsedPicture parsed;
- if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePicture(data, data_len, parsed) == NErr_Success && parsed.picture_type == picture_type)
- {
- *f = (nsid3v2_frame_t)frame;
- return NErr_Success;
- }
- frame = tag->FindNextFrame(frame);
- }
- return NErr_Error;
- }
- int NSID3v2_Tag_APIC_GetFirstFrame(const nsid3v2_tag_t t, nsid3v2_frame_t *f)
- {
- const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
- const ID3v2::Frame *frame = tag->FindFirstFrame(NSID3V2_FRAME_PICTURE);
- while (frame)
- {
- const void *data;
- size_t data_len;
- ParsedPicture parsed;
- if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePicture(data, data_len, parsed) == NErr_Success)
- {
- *f = (nsid3v2_frame_t)frame;
- return NErr_Success;
- }
- frame = tag->FindNextFrame(frame);
- }
- return NErr_Error;
- }
|