#include <unistd.h>
#include <glib.h>
+#define MIME_TYPE_JPEG "image/jpeg"
+#define MIME_TYPE_PNG "image/png"
+
static int __ID3_getTwixFrameByName(metadata_editor_s* _metadata, TagLib::ID3v1::Tag* tag1, TagLib::ID3v2::Tag* tag2, const char* frameID, char** value);
static int __ID3_setTwixFrameByName(metadata_editor_s* _metadata, TagLib::ID3v1::Tag* tag1, TagLib::ID3v2::Tag* tag2, const char* frameID, const char* value);
static int __ID3_getFrameByName(metadata_editor_s* _metadata, TagLib::ID3v2::Tag* tag2, const char* frameID, char** value);
}
}
-// *** This function returns buffer with picture under the specified index and buffer's (picture's) size *** //
-extern "C" int metadata_editor_get_picture(metadata_editor_h metadata, int index, void **picture, int *size, char **mime_type) {
- int ret = METADATA_EDITOR_ERROR_NONE;
- metadata_editor_s* _metadata = (metadata_editor_s*) metadata;
- const char *TYPE_JPEG = "image/jpeg";
- const char *TYPE_PNG = "image/png";
- int i = 0;
+static char * __get_mime_type(const TagLib::String& mime_type)
+{
+ if (mime_type == MIME_TYPE_JPEG || mime_type == MIME_TYPE_PNG)
+ return g_strdup(mime_type.toCString());
- ret = __check_metadata_get_parameter(_metadata, mime_type);
- metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_get_parameter() [%d]", ret);
- metadata_editor_retvm_if(!picture, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture");
- metadata_editor_retvm_if(!size, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid size");
+ return NULL;
+}
- switch (_metadata->filetype) { // Process the file according to the specified file type
- case METADATA_EDITOR_FORMAT_MP3: {
- TagLib::MPEG::File* _file = (TagLib::MPEG::File*)_metadata->file; // Bring the pointer to actual file type
- TagLib::ID3v2::Tag* tag2 = _file->ID3v2Tag();
- metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Error. No ID3v2 tag in file.");
-
- TagLib::ID3v2::FrameList lst = tag2->frameListMap()["APIC"];
- // Check if there are pictures in the tag
- if (lst.isEmpty()) {
- metadata_editor_error("No pictures in file");
- return METADATA_EDITOR_ERROR_OPERATION_FAILED;
- }
+static char * __get_mime_type_from_cover_art(const TagLib::MP4::CoverArt& cover_art)
+{
+ if (cover_art.format() == TagLib::MP4::CoverArt::JPEG)
+ return g_strdup(MIME_TYPE_JPEG);
+ else if (cover_art.format() == TagLib::MP4::CoverArt::PNG)
+ return g_strdup(MIME_TYPE_PNG);
- // Check if index is correct or not
- if ((index < 0) || (lst.size() <= (uint)index)) {
- metadata_editor_error("Index of picture is out of range");
- return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
- }
+ return NULL;
+}
- metadata_editor_info("There are %u pictures in file. Start of picture number %d extraction", lst.size(), index);
+static int __get_APIC(TagLib::ID3v2::Tag* tag, int index, void **picture, int *size, char **mime_type)
+{
+ metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Error. No ID3v2 tag in file.");
- i = 0;
- // Among all frames we must choose that one with specified index. "i" will be counter
- for (TagLib::ID3v2::FrameList::Iterator it = lst.begin(); it != lst.end(); ++it, ++i) {
- if (i != index)
- continue;
+ TagLib::ID3v2::FrameList lst = tag->frameListMap()["APIC"];
- TagLib::ID3v2::AttachedPictureFrame* pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
- uint pictureSize = pictureFrame->picture().size();
- metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
+ // Check if there are pictures in the tag
+ if (lst.isEmpty()) {
+ metadata_editor_error("No pictures in file");
+ return METADATA_EDITOR_ERROR_OPERATION_FAILED;
+ }
- *picture = g_memdup(pictureFrame->picture().data(), pictureSize);
- *size = pictureSize;
+ // Check if index is correct or not
+ if ((index < 0) || (lst.size() <= (uint)index)) {
+ metadata_editor_error("Index of picture is out of range");
+ return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
+ }
- TagLib::String mime = pictureFrame->mimeType();
- if (mime == "image/jpeg")
- *mime_type = strndup(TYPE_JPEG, strlen(TYPE_JPEG));
- else if (mime == "image/png")
- *mime_type = strndup(TYPE_PNG, strlen(TYPE_PNG));
- else
- *mime_type = NULL;
- break;
- }
+ metadata_editor_info("There are %u pictures in file. Start of picture number %d extraction", lst.size(), index);
- return METADATA_EDITOR_ERROR_NONE;
- }
+ auto pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(lst[index]);
- case METADATA_EDITOR_FORMAT_MP4: {
- TagLib::MP4::File* _file = (TagLib::MP4::File*) _metadata->file;
- TagLib::MP4::Tag* tag = _file->tag();
- metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Tag does not exist");
+ uint pictureSize = pictureFrame->picture().size();
+ metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
- // Get map of items directly from tag and launch a search of specific item
- TagLib::MP4::ItemListMap& itemMap = tag->itemListMap();
- TagLib::MP4::ItemListMap::ConstIterator it = itemMap.find("covr");
+ *picture = g_memdup(pictureFrame->picture().data(), pictureSize);
+ *size = pictureSize;
+ *mime_type = __get_mime_type(pictureFrame->mimeType());
- if (it == itemMap.end()) {
- metadata_editor_error("No item <covr> in file. No pictures in file");
- return METADATA_EDITOR_ERROR_OPERATION_FAILED;
- }
+ return METADATA_EDITOR_ERROR_NONE;
+}
- TagLib::MP4::CoverArtList lst = it->second.toCoverArtList();
+static int __get_mp3_picture(metadata_editor_s* metadata, int index, void **picture, int *size, char **mime_type)
+{
+ TagLib::MPEG::File* _file = (TagLib::MPEG::File*)metadata->file;
- // Check if the index is in range of CoverArtList Item
- if ((index < 0) || ((uint)index >= lst.size())) { // it is not
- metadata_editor_error("Index of picture is out of range");
- return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
- }
+ return __get_APIC(_file->ID3v2Tag(), index, picture, size, mime_type);
+}
- i = 0;
- for (TagLib::MP4::CoverArtList::ConstIterator picIt = lst.begin(); picIt != lst.end(); ++picIt, ++i) {
- if (i != index)
- continue;
+static int __get_mp4_picture(metadata_editor_s* metadata, int index, void **picture, int *size, char **mime_type)
+{
+ TagLib::MP4::File* _file = (TagLib::MP4::File*) metadata->file;
+ TagLib::MP4::Tag* tag = _file->tag();
- int pictureSize = picIt->data().size();
- metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
+ metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Tag does not exist");
- *picture = g_memdup(picIt->data().data(), pictureSize);
- *size = pictureSize;
+ // Get map of items directly from tag and launch a search of specific item
+ TagLib::MP4::ItemListMap& itemMap = tag->itemListMap();
+ TagLib::MP4::ItemListMap::ConstIterator it = itemMap.find("covr");
- if (picIt->format() == TagLib::MP4::CoverArt::JPEG)
- *mime_type = strndup(TYPE_JPEG, strlen(TYPE_JPEG));
- else if (picIt->format() == TagLib::MP4::CoverArt::PNG)
- *mime_type = strndup(TYPE_PNG, strlen(TYPE_PNG));
- else
- *mime_type = NULL;
- break;
- }
+ if (it == itemMap.end()) {
+ metadata_editor_error("No item <covr> in file. No pictures in file");
+ return METADATA_EDITOR_ERROR_OPERATION_FAILED;
+ }
- return METADATA_EDITOR_ERROR_NONE;
+ TagLib::MP4::CoverArtList lst = it->second.toCoverArtList();
+ // Check if the index is in range of CoverArtList Item
+ if ((index < 0) || ((uint)index >= lst.size())) {
+ metadata_editor_error("Index of picture is out of range");
+ return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
}
-#if 0
- case METADATA_EDITOR_FORMAT_FLAC: {
- TagLib::FLAC::File* _file = (TagLib::FLAC::File*) _metadata->file;
- TagLib::List<TagLib::FLAC::Picture*> lst = _file->pictureList();
- if (lst.isEmpty()) {
- metadata_editor_error("No pictures in FLAC file");
- return METADATA_EDITOR_ERROR_OPERATION_FAILED;
- }
+ auto pictureFrame = static_cast<TagLib::MP4::CoverArt>(lst[index]);
- // Check if the index is in range of CoverArtList Item
- if ((index < 0) || ((uint)index >= lst.size())) { // it is not
- metadata_editor_error("Index of picture is out of range");
- return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
- }
+ int pictureSize = pictureFrame.data().size();
+ metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
- // Consecutive check of all pictures until the desired one is found
- i = 0;
- for (TagLib::List<TagLib::FLAC::Picture*>::ConstIterator picIt = lst.begin(); picIt != lst.end(); ++picIt, ++i) {
- if (i != index)
- continue;
-
- // picture can be received as ByteVector (picIt->data()).
- // ByteVector has data() - picture itself and size() - the size of picture in data() method
- int pictureSize = (*picIt)->data().size();
- metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
-
- *picture = g_memdup((*picIt)->data().data(), pictureSize);
- *size = pictureSize;
-
- TagLib::String mime = (*picIt)->mimeType();
- if (mime == "image/jpeg")
- *mime_type = strndup(TYPE_JPEG, strlen(TYPE_JPEG));
- else if (mime == "image/png")
- *mime_type = strndup(TYPE_PNG, strlen(TYPE_PNG));
- else
- *mime_type = NULL;
- break;
- }
+ *picture = g_memdup(pictureFrame.data().data(), pictureSize);
+ *size = pictureSize;
+ *mime_type = __get_mime_type_from_cover_art(pictureFrame);
- return METADATA_EDITOR_ERROR_NONE;
+ return METADATA_EDITOR_ERROR_NONE;
+}
+
+#if 0
+static int __get_flac_picture(metadata_editor_s* metadata, int index, void **picture, int *size, char **mime_type)
+{
+ TagLib::FLAC::File* _file = (TagLib::FLAC::File*) metadata->file;
+ TagLib::List<TagLib::FLAC::Picture*> lst = _file->pictureList();
+
+ if (lst.isEmpty()) {
+ metadata_editor_error("No pictures in FLAC file");
+ return METADATA_EDITOR_ERROR_OPERATION_FAILED;
}
- case METADATA_EDITOR_FORMAT_WAV: {
- TagLib::RIFF::WAV::File* _file = (TagLib::RIFF::WAV::File*)_metadata->file; // Bring the pointer to actual file type
- TagLib::ID3v2::Tag* tag2 = _file->tag();
+ // Check if the index is in range of CoverArtList Item
+ if ((index < 0) || ((uint)index >= lst.size())) {
+ metadata_editor_error("Index of picture is out of range");
+ return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
+ }
- if (!tag2) {
- metadata_editor_error("No ID3v2 tag in file");
- return METADATA_EDITOR_ERROR_OPERATION_FAILED;
- }
+ auto pictureFrame = static_cast<TagLib::FLAC::Picture*>(lst[index]);
- TagLib::ID3v2::FrameList lst = tag2->frameListMap()["APIC"];
- // Check if there are pictures in the tag
- if (lst.isEmpty()) {
- metadata_editor_error("No pictures in file");
- return METADATA_EDITOR_ERROR_OPERATION_FAILED;
- }
+ int pictureSize = pictureFrame->data().size();
+ metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
- // Check if index is correct or not
- if ((index < 0) || (lst.size() <= (uint)index)) {
- metadata_editor_error("Index of picture is out of range");
- return METADATA_EDITOR_ERROR_INVALID_PARAMETER;
- }
+ *picture = g_memdup(pictureFrame->data().data(), pictureSize);
+ *size = pictureSize;
+ *mime_type = __get_mime_type(pictureFrame->mimeType());
- metadata_editor_info("There are %u pictures in file. Start of picture number %d extraction", lst.size(), index);
- i = 0;
- // Among all frames we must choose that one with specified index. "i" will be counter
- for (TagLib::ID3v2::FrameList::Iterator it = lst.begin(); it != lst.end(); ++it, ++i) {
- if (i != index)
- continue;
-
- TagLib::ID3v2::AttachedPictureFrame* pictureFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it);
- uint pictureSize = pictureFrame->picture().size();
- metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0");
-
- *picture = g_memdup(pictureFrame->picture().data(), pictureSize);
- *size = pictureSize;
-
- TagLib::String mime = pictureFrame->mimeType();
- if (mime == "image/jpeg")
- *mime_type = strndup(TYPE_JPEG, strlen(TYPE_JPEG));
- else if (mime == "image/png")
- *mime_type = strndup(TYPE_PNG, strlen(TYPE_PNG));
- else
- *mime_type = NULL;
- break;
- }
+ return METADATA_EDITOR_ERROR_NONE;
+}
- return METADATA_EDITOR_ERROR_NONE;
- }
+static int __get_wav_picture(metadata_editor_s* metadata, int index, void **picture, int *size, char **mime_type)
+{
+ TagLib::RIFF::WAV::File* _file = (TagLib::RIFF::WAV::File*)metadata->file;
+
+ return __get_APIC(_file->tag(), index, picture, size, mime_type);
+}
+#endif
+
+// *** This function returns buffer with picture under the specified index and buffer's (picture's) size *** //
+extern "C" int metadata_editor_get_picture(metadata_editor_h metadata, int index, void **picture, int *size, char **mime_type) {
+ int ret = METADATA_EDITOR_ERROR_NONE;
+ metadata_editor_s* _metadata = (metadata_editor_s*) metadata;
+
+ ret = __check_metadata_get_parameter(_metadata, mime_type);
+ metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_get_parameter() [%d]", ret);
+ metadata_editor_retvm_if(!picture, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture");
+ metadata_editor_retvm_if(!size, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid size");
+
+ switch (_metadata->filetype) { // Process the file according to the specified file type
+ case METADATA_EDITOR_FORMAT_MP3:
+ return __get_mp3_picture(_metadata, index, picture, size, mime_type);
+
+ case METADATA_EDITOR_FORMAT_MP4:
+ return __get_mp4_picture(_metadata, index, picture, size, mime_type);
+
+#if 0
+ case METADATA_EDITOR_FORMAT_FLAC:
+ return __get_flac_picture(_metadata, index, picture, size, mime_type);
+
+ case METADATA_EDITOR_FORMAT_WAV:
+ return __get_wav_picture(_metadata, index, picture, size, mime_type);
#endif
default:
metadata_editor_error("Wrong file type");