From: minje.ahn Date: Tue, 28 Jun 2022 08:41:53 +0000 (+0900) Subject: Use FileRef instead X-Git-Tag: submit/tizen/20220711.084601~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F53%2F276953%2F9;p=platform%2Fcore%2Fapi%2Fmetadata-editor.git Use FileRef instead FileRef helps to respond appropriately according to each format. Change-Id: Id2af3ca82e99c40b0dd6853c32f41c526c872e97 Signed-off-by: minje.ahn --- diff --git a/include/metadata_editor_private.h b/include/metadata_editor_private.h index fba0ffd..105a677 100755 --- a/include/metadata_editor_private.h +++ b/include/metadata_editor_private.h @@ -60,14 +60,14 @@ extern "C" { } while (0) #define metadata_editor_retvm_if(expr, val, fmt, arg...) do { \ - if (expr) { \ - LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ + if ((expr)) { \ + LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ return (val); \ } \ } while (0) #define metadata_editor_retm_if(expr, fmt, arg...) do { \ - if (expr) { \ + if ((expr)) { \ LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ return; \ } \ diff --git a/src/metadata_editor.cpp b/src/metadata_editor.cpp index 62dfcd5..c2d1612 100755 --- a/src/metadata_editor.cpp +++ b/src/metadata_editor.cpp @@ -24,6 +24,8 @@ #include #include +#include +#include #include #include #include @@ -46,138 +48,7 @@ using namespace TagLib; #define MIME_TYPE_JPEG "image/jpeg" #define MIME_TYPE_PNG "image/png" - -class MetadataFile -{ -public: - virtual ~MetadataFile() = default; - - virtual int appendPicture(const char *picture ,size_t size, const char *mime_type) = 0; - virtual int getPicture(int index, void **picture, int *size, char **mime_type) = 0; - virtual int removePicture(int index) = 0; - - virtual int setMetadata(metadata_editor_attr_e attribute, const char *value) = 0; - virtual int getMetadata(metadata_editor_attr_e attribute, char **value) = 0; - virtual int updateMetadata() = 0; - - bool isOpen() { return file->isOpen(); } - bool readOnly() { return file->readOnly(); } - -protected: - File* file {}; -}; - -class Mp3MetadataFile : public MetadataFile { -public: - explicit Mp3MetadataFile(const char *path) { - file = new MPEG::File(path); - } - - ~Mp3MetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -class Mp4MetadataFile : public MetadataFile -{ -public: - explicit Mp4MetadataFile(const char *path) { - file = new MP4::File(path); - } - ~Mp4MetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -class FlacMetadataFile : public MetadataFile -{ -public: - explicit FlacMetadataFile(const char *path) { - file = new FLAC::File(path); - } - ~FlacMetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -class OggVorbisMetadataFile : public MetadataFile -{ -public: - explicit OggVorbisMetadataFile(const char *path) { - file = new Ogg::Vorbis::File(path); - } - ~OggVorbisMetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -class OggFlacMetadataFile : public MetadataFile -{ -public: - explicit OggFlacMetadataFile(const char *path) { - file = new Ogg::FLAC::File(path); - } - ~OggFlacMetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -class WavMetadataFile : public MetadataFile -{ -public: - explicit WavMetadataFile(const char *path) { - file = new RIFF::WAV::File(path); - } - ~WavMetadataFile() override { - delete dynamic_cast(file); - } - - int appendPicture(const char *picture ,size_t size, const char *mime_type) override; - int getPicture(int index, void **picture, int *size, char **mime_type) override; - int removePicture(int index) override; - int setMetadata(metadata_editor_attr_e attribute, const char *value) override; - int getMetadata(metadata_editor_attr_e attribute, char **value) override; - int updateMetadata() override; -}; - -typedef struct { - MetadataFile* intf; -} metadata_editor_s; +#define EXT_LEN 255 typedef enum { METADATA_EDITOR_FORMAT_MP3 = 0, /**< MP3 File */ @@ -189,416 +60,40 @@ typedef enum { METADATA_EDITOR_FORMAT_NOTYPE = 0xFF /**< Error type. File type is not correct or not specified */ } metadata_editor_format_e; -static int __check_metadata_parameter(metadata_editor_s *metadata) -{ - metadata_editor_retvm_if(!metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); - metadata_editor_retvm_if(!metadata->intf, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __check_metadata_set_parameter(metadata_editor_s *metadata) -{ - int ret = METADATA_EDITOR_ERROR_NONE; - - ret = __check_metadata_parameter(metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_parameter"); - - metadata_editor_retvm_if(metadata->intf->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "File is readonly. Unable to modify"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __check_metadata_get_parameter(metadata_editor_s *metadata, char **value) -{ - int ret = METADATA_EDITOR_ERROR_NONE; - - ret = __check_metadata_parameter(metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_parameter"); - - metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __ID3_getTwixFrameByName(ID3v1::Tag *tag1, ID3v2::Tag *tag2, const char *frameID, char **value) -{ - metadata_editor_retvm_if(!frameID, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid frameID"); - - if (tag2 && !(tag2->frameListMap()[frameID].isEmpty())) { - metadata_editor_info("The frame %s exists in ID3v2 tag", frameID); - *value = g_strdup(tag2->frameListMap()[frameID][0]->toString().toCString(true)); - return METADATA_EDITOR_ERROR_NONE; - } - - metadata_editor_info("The frame %s in ID3v2 tag is empty", frameID); - - if (!tag1 || tag1->isEmpty()) { - metadata_editor_info("The frame %s in ID3v1 tag is empty as well", frameID); - return METADATA_EDITOR_ERROR_NONE; - } - - metadata_editor_info("Reading data from ID3v1 tag"); - - //check isEmpty(). toCString() returns "", when String is NULL. - //for "genre", taglib returns "", if genre is out or range. - if (!strcmp(frameID, "TPE1") && !(tag1->artist().isEmpty())) /* artist */ - *value = g_strdup(tag1->artist().toCString(true)); - else if (!strcmp(frameID, "TALB") && !(tag1->album().isEmpty())) /* album */ - *value = g_strdup(tag1->album().toCString(true)); - else if (!strcmp(frameID, "COMM") && !(tag1->comment().isEmpty())) /* comment */ - *value = g_strdup(tag1->comment().toCString(true)); - else if (!strcmp(frameID, "TCON") && !(tag1->genre().isEmpty()) && !(tag1->genre().isEmpty())) /* genre */ - *value = g_strdup(tag1->genre().toCString(true)); - else if (!strcmp(frameID, "TIT2") && !(tag1->title().isEmpty())) /* title */ - *value = g_strdup(tag1->title().toCString(true)); - else if (!strcmp(frameID, "TRCK")) /* track */ - *value = g_strdup_printf("%u", tag1->track()); - else if (!strcmp(frameID, "TDRC")) /* data (year) */ - *value = g_strdup_printf("%u", tag1->year()); - else - metadata_editor_debug("The desired frame was not found"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static void __ID3v1_setFrameByName(ID3v1::Tag *tag1, const char *frameID, const char *value) -{ - metadata_editor_retm_if(!tag1, "[No-Error] No ID3v1 tag to update"); //ID3v1 is optional - metadata_editor_retm_if(tag1->isEmpty(), "[No-Error] ID3v1 tag is empty"); - - if (!value || (*value == '\0')) { - metadata_editor_info("Request for frame %s deletion", frameID); - - if (!strcmp(frameID, "TPE1")) - tag1->setArtist(""); - else if (!strcmp(frameID, "TALB")) - tag1->setAlbum(""); - else if (!strcmp(frameID, "TCON")) - tag1->setGenre(""); - else if (!strcmp(frameID, "TIT2")) - tag1->setTitle(""); - else if (!strcmp(frameID, "TRCK")) - tag1->setTrack(0); - else if (!strcmp(frameID, "TDRC")) - tag1->setYear(0); - - return; - } - - if (!strcmp(frameID, "TPE1")) - tag1->setArtist(value); - else if (!strcmp(frameID, "TALB")) - tag1->setAlbum(value); - else if (!strcmp(frameID, "TCON")) // Genre in ID3v1 is enumeration, so can not write it with "value" - tag1->setGenre(""); - else if (!strcmp(frameID, "TIT2")) - tag1->setTitle(value); - else if (!strcmp(frameID, "TRCK")) - tag1->setTrack(atoi(value)); - else if (!strcmp(frameID, "TDRC")) - tag1->setYear(atoi(value)); - - return; -} - -static int __ID3v2_setFrameByName(ID3v2::Tag *tag2, const char *frameID, const char *value) -{ - metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Error. ID3v2 tag was not created. Can not proceed metadata updating"); - metadata_editor_retvm_if(!frameID, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid frameID"); - - // If the pointer is NULL or c-string is empty - handle as request for deletion - if (!value || (*value == '\0')) { - metadata_editor_info("Request for frame %s deletion", frameID); - tag2->removeFrames(frameID); - return METADATA_EDITOR_ERROR_NONE; - } - - // Check if the ID3v2 tag exists - if (tag2->frameListMap()[frameID].isEmpty()) { - metadata_editor_info("The frame %s does not exist. Creating", frameID); - // This is a common frame type for textural frames except comment frame - auto fr = new ID3v2::TextIdentificationFrame(frameID); - - fr->setTextEncoding(String::UTF8); - fr->setText(String(value, String::UTF8)); - tag2->addFrame(fr); - } else { // if not - just modify the data in the existing frame - metadata_editor_info("The frame %s exists. Changing", frameID); - tag2->frameListMap()[frameID][0]->setText(String(value, String::UTF8)); - } - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __ID3_setTwixFrameByName(ID3v1::Tag *tag1, ID3v2::Tag *tag2, const char *frameID, const char *value) -{ - metadata_editor_retvm_if(!frameID, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid frameID"); - if (tag1 && !(tag1->isEmpty())) - __ID3v1_setFrameByName(tag1, frameID, value); - - return __ID3v2_setFrameByName(tag2, frameID, value); -} - -static int __ID3_getNumberOfPictures(ID3v2::Tag *tag2, char **value) -{ - metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); - - *value = g_strdup_printf("%u", tag2 ? tag2->frameListMap()["APIC"].size() : 0); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __ID3_getLyricsFrame(ID3v2::Tag *tag2, char **value) -{ - metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_NONE, "[No-Error] No tag"); - - auto lst = tag2->frameListMap()["USLT"]; // link to unsynchronized lyric frames in tag - metadata_editor_retvm_if(lst.isEmpty(), METADATA_EDITOR_ERROR_NONE, "The frame USLT does not exist"); - - metadata_editor_info("The frame USLT exists"); - auto it = lst.begin(); - auto frame = static_cast(*it); - - if (!(frame->text().isEmpty())) - *value = g_strdup(frame->text().toCString(true)); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __ID3_setTwixCommentFrame(ID3v1::Tag *tag1, ID3v2::Tag *tag2, const char *value) -{ - metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Error. ID3v2 tag was not created. Can not proceed metadata updating"); - - // If the pointer is NULL or c-string is empty - handle as request for deletion - if (!value || (*value == '\0')) { - metadata_editor_info("Request for frame COMM deletion"); - tag2->removeFrames("COMM"); - if (tag1 && !tag1->isEmpty()) - tag1->setComment(""); - return METADATA_EDITOR_ERROR_NONE; - } - // If the comment frame is empty - create the frame and add it to the list - if (tag2->frameListMap()["COMM"].isEmpty()) { - metadata_editor_info("The frame COMM does not exist. Creating"); - auto fr = new ID3v2::CommentsFrame; - - fr->setText(String(value, String::UTF8)); - fr->setTextEncoding(String::UTF8); - tag2->addFrame(fr); - } else { // If the frame already exists - just modify its value - metadata_editor_info("The frame COMM exists. Changing"); - tag2->frameListMap()["COMM"][0]->setText(String(value, String::UTF8)); - } - - if (tag1 && !tag1->isEmpty()) { // Copy the value to ID3v1 tag comment - metadata_editor_info("ID3v1 tag also exists. Copying frame"); - tag1->setComment(value); - } - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __ID3_setLyricsFrame(ID3v2::Tag *tag2, const char *value) -{ - metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Error. ID3v2 tag was not created. Can not proceed metadata updating"); - - auto lst = tag2->frameListMap()["USLT"]; // link to unsynchronized lyric frames in tag - // If the pointer is NULL or c-string is empty - handle as request for deletion - if (!value || (*value == '\0')) { - metadata_editor_info("Request for frame USLT deletion"); - tag2->removeFrames("USLT"); - return METADATA_EDITOR_ERROR_NONE; - } - // Check if lyrics frames exist - if (lst.isEmpty()) { - // No lyrics - create the frame and add it to the ID3v2 tag - metadata_editor_info("The frame USLT does not exist. Creating"); - auto frame = new ID3v2::UnsynchronizedLyricsFrame; - - frame->setTextEncoding(String::UTF8); - frame->setText(String(value, String::UTF8)); - tag2->addFrame(frame); - } else { // the lyrics frames exist - change the existing one - metadata_editor_info("USLT frames exist in file. Changing"); - auto it = lst.begin(); - auto frame = static_cast(*it); - frame->setTextEncoding(String::UTF8); - frame->setText(String(value, String::UTF8)); - } - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __MP4_getStringItem(MP4::Tag *tag, const char *itemname, char **value) -{ - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_NONE, "[No-Error] No tag"); - metadata_editor_retvm_if(!itemname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid itemname"); - - auto item = tag->item(itemname); - - if (item.isValid()) - *value = g_strdup(item.toStringList().toString().toCString(false)); - else - metadata_editor_info("No item <%s> in file", itemname); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __MP4_getIntegerItem(MP4::Tag *tag, const char *itemname, char **value) -{ - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_NONE, "[No-Error] No tag"); - metadata_editor_retvm_if(!itemname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid itemname"); - - auto item = tag->item(itemname); - - if (item.isValid()) - *value = g_strdup_printf("%u", item.toInt()); - else - metadata_editor_info("No item <%s> in file", itemname); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __MP4_updateStringItem(MP4::Tag *tag, const char *itemname, const char *value) -{ - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - metadata_editor_retvm_if(!itemname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid itemname"); - - // Check if it is a request for deletion - if ((value == NULL) || value[0] == '\0') { - metadata_editor_info("Request for deleting of item <%s>", itemname); - tag->removeItem(itemname); - - return METADATA_EDITOR_ERROR_NONE; - } - metadata_editor_info("The item <%s> will be added", itemname); - tag->setItem(itemname, MP4::Item(String(value, String::UTF8))); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __MP4_updateIntegerItem(MP4::Tag *tag, const char *itemname, const char *value) -{ - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - metadata_editor_retvm_if(!itemname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid itemname"); - - // Check if it is a request for deletion - if ((value == NULL) || value[0] == '\0') { - metadata_editor_info("Request for deleting of item <%s>", itemname); - tag->removeItem(itemname); - - return METADATA_EDITOR_ERROR_NONE; - } - // Check if the value is integer string then it can be successfully converted into integer - if (isdigit(value[0])) { - metadata_editor_info("The item <%s> will be added", itemname); - int number = atoi(value); - tag->setItem(itemname, MP4::Item(number)); - return METADATA_EDITOR_ERROR_NONE; - } else { // Notify that string is not a number to process - metadata_editor_error("Error. String does not contain a number"); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } -} - -static int __MP4_getNumberOfPictures(MP4::Tag *tag, char **value) -{ - metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); - - if (tag && tag->contains("covr")) - *value = g_strdup_printf("%u", tag->item("covr").toCoverArtList().size()); - else - *value = g_strdup_printf("0"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __xiph_getFieldValue(Ogg::XiphComment *xtag, const char *fieldname, char **value) -{ - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_NONE, "[No-Error] No tag"); - metadata_editor_retvm_if(!fieldname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid fieldname"); - - auto &fieldMap = xtag->fieldListMap(); - auto it = fieldMap.find(fieldname); - - if ((xtag->contains(fieldname)) && (it != fieldMap.end())) - *value = g_strdup(it->second[0].toCString(true)); - else - metadata_editor_info("No field %s in Xiph Comment", fieldname); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __xiph_updateFieldValue(Ogg::XiphComment *xtag, const char *fieldname, const char *value) -{ - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - metadata_editor_retvm_if(!fieldname, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid fieldname"); - - // Check if it is a request for deletion - if ((value == NULL) || value[0] == '\0') { - metadata_editor_info("Request for deleting of field %s", fieldname); - xtag->removeFields(fieldname); - return METADATA_EDITOR_ERROR_NONE; - } - metadata_editor_info("The field %s will be added", fieldname); - // "true" is used to remove other strings of the same "fieldname" first - xtag->addField(fieldname, String(value, String::UTF8), true); - return METADATA_EDITOR_ERROR_NONE; -} - -static int __FLAC_getNumberOfPictures(FLAC::File *file, char **value) -{ - if (file) - *value = g_strdup_printf("%u", file->pictureList().size()); - else - *value = g_strdup("0"); - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __OGG_getNumberOfPictures(Ogg::XiphComment *xtag, char **value) -{ - if (xtag) - *value = g_strdup_printf("%u", xtag->pictureList().size()); - else - *value = g_strdup("0"); - - return METADATA_EDITOR_ERROR_NONE; -} +typedef struct { + FileRef *fref; + metadata_editor_format_e format; +} metadata_editor_s; -static int __metadata_editor_get_file_ext(const char *file_path, char *file_ext, int max_len) +static bool __metadata_editor_get_file_ext(const char *file_path, char *file_ext, int max_len) { - int i = 0; + unsigned int i = 0; unsigned int path_len = strlen(file_path); - for (i = (int)path_len; i >= 0; i--) { - if ((file_path[i] == '.') && (i < (int)path_len)) { + for (i = path_len; i > 0; i--) { + if ((file_path[i] == '.') && (i < path_len)) { strncpy(file_ext, &file_path[i + 1], max_len); - return 0; + return true; } /* meet the dir. no ext */ if (file_path[i] == '/') - return -1; + return false; } - return -1; + return false; } -static int __metadata_editor_get_file_type(const char *path) +static metadata_editor_format_e __metadata_editor_get_file_type(const char *path) { - int ret = 0; - char mimetype[255] = {0, }; + char mimetype[EXT_LEN] = {0, }; + char ext[EXT_LEN] = { 0 }; /* get content type and mime type from file. */ - ret = aul_get_mime_from_file(path, mimetype, sizeof(mimetype)); - if (ret < 0) { + if (aul_get_mime_from_file(path, mimetype, sizeof(mimetype)) < 0) { metadata_editor_debug("aul_get_mime_from_file fail.. Now trying to get type by extension"); - char ext[255] = { 0 }; - int ret = __metadata_editor_get_file_ext(path, ext, sizeof(ext)); - metadata_editor_retvm_if(ret < 0, METADATA_EDITOR_FORMAT_NOTYPE, "__metadata_editor_get_file_ext failed"); + metadata_editor_retvm_if(!__metadata_editor_get_file_ext(path, ext, EXT_LEN), METADATA_EDITOR_FORMAT_NOTYPE, "__metadata_editor_get_file_ext failed"); if (strcasecmp(ext, "MP3") == 0) return METADATA_EDITOR_FORMAT_MP3; @@ -608,7 +103,7 @@ static int __metadata_editor_get_file_type(const char *path) return METADATA_EDITOR_FORMAT_FLAC; else if (strcasecmp(ext, "WAV") == 0) return METADATA_EDITOR_FORMAT_WAV; - else if (strcasecmp(ext, "OGG") == 0) //Fix Me!flac_ogg is unusual. So if file extention of ogg is considered vorbis ogg + else if (strcasecmp(ext, "OGG") == 0) return METADATA_EDITOR_FORMAT_OGG_VORBIS; else return METADATA_EDITOR_FORMAT_NOTYPE; @@ -636,15 +131,14 @@ static int __metadata_editor_get_file_type(const char *path) static int __metadata_editor_get_picture_type(const char *path, char **type) { int ret = 0; - char mimetype[255] = {0, }; + char mimetype[EXT_LEN] = {0, }; + char ext[EXT_LEN] = {0, }; /* get content type and mime type from file. */ - ret = aul_get_mime_from_file(path, mimetype, sizeof(mimetype)); - if (ret < 0) { + if (aul_get_mime_from_file(path, mimetype, sizeof(mimetype)) < 0) { metadata_editor_debug("aul_get_mime_from_file fail.. Now trying to get type by extension"); - char ext[255] = { 0 }; - int ret = __metadata_editor_get_file_ext(path, ext, sizeof(ext)); + ret = __metadata_editor_get_file_ext(path, ext, EXT_LEN); metadata_editor_retvm_if(ret < 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "__metadata_editor_get_file_ext failed"); if (strcasecmp(ext, "JPG") == 0 || strcasecmp(ext, "JPEG") == 0) { @@ -700,12 +194,9 @@ static int __metadata_editor_get_picture_info(const char *path, char **picture, return ret; } - - static int __check_file_validity(const char *path) { metadata_editor_retvm_if(!path, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid path"); - metadata_editor_sec_debug("path : [%s]", path); if (access(path, R_OK) < 0) { @@ -721,97 +212,6 @@ static int __check_file_validity(const char *path) return METADATA_EDITOR_ERROR_NONE; } - -static int __get_ID3_tag(metadata_editor_attr_e attribute, ID3v1::Tag *tag1, ID3v2::Tag *tag2, char **value) -{ - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __ID3_getTwixFrameByName(tag1, tag2, "TPE1", value); - case METADATA_EDITOR_ATTR_TITLE: return __ID3_getTwixFrameByName(tag1, tag2, "TIT2", value); - case METADATA_EDITOR_ATTR_ALBUM: return __ID3_getTwixFrameByName(tag1, tag2, "TALB", value); - case METADATA_EDITOR_ATTR_GENRE: return __ID3_getTwixFrameByName(tag1, tag2, "TCON", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __ID3_getTwixFrameByName(NULL, tag2, "TCOM", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __ID3_getTwixFrameByName(NULL, tag2, "TCOP", value); - case METADATA_EDITOR_ATTR_DATE: return __ID3_getTwixFrameByName(tag1, tag2, "TDRC", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __ID3_getTwixFrameByName(NULL, tag2, "TIT3", value); - case METADATA_EDITOR_ATTR_COMMENT: return __ID3_getTwixFrameByName(tag1, tag2, "COMM", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __ID3_getTwixFrameByName(tag1, tag2, "TRCK", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __ID3_getTwixFrameByName(NULL, tag2, "TPE3", value); - case METADATA_EDITOR_ATTR_PICTURE_NUM: return __ID3_getNumberOfPictures(tag2, value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __ID3_getLyricsFrame(tag2, value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } -} - -static int __get_ogg_metadata(Ogg::XiphComment *xtag, metadata_editor_attr_e attribute, char **value) -{ - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __xiph_getFieldValue(xtag, "ARTIST", value); - case METADATA_EDITOR_ATTR_TITLE: return __xiph_getFieldValue(xtag, "TITLE", value); - case METADATA_EDITOR_ATTR_ALBUM: return __xiph_getFieldValue(xtag, "ALBUM", value); - case METADATA_EDITOR_ATTR_GENRE: return __xiph_getFieldValue(xtag, "GENRE", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __xiph_getFieldValue(xtag, "COMPOSER", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __xiph_getFieldValue(xtag, "COPYRIGHT", value); - case METADATA_EDITOR_ATTR_DATE: return __xiph_getFieldValue(xtag, "DATE", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __xiph_getFieldValue(xtag, "DESCRIPTION", value); - case METADATA_EDITOR_ATTR_COMMENT: return __xiph_getFieldValue(xtag, "COMMENT", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __xiph_getFieldValue(xtag, "TRACKNUMBER", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __xiph_getFieldValue(xtag, "CONDUCTOR", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __xiph_getFieldValue(xtag, "LYRICS", value); - case METADATA_EDITOR_ATTR_PICTURE_NUM: return __OGG_getNumberOfPictures(xtag, value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } -} - -static int __set_ID3_tag(metadata_editor_attr_e attribute, ID3v1::Tag *tag1, ID3v2::Tag *tag2, const char *value) -{ - metadata_editor_retvm_if(!tag2, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __ID3_setTwixFrameByName(tag1, tag2, "TPE1", value); - case METADATA_EDITOR_ATTR_TITLE: return __ID3_setTwixFrameByName(tag1, tag2, "TIT2", value); - case METADATA_EDITOR_ATTR_ALBUM: return __ID3_setTwixFrameByName(tag1, tag2, "TALB", value); - case METADATA_EDITOR_ATTR_GENRE: return __ID3_setTwixFrameByName(tag1, tag2, "TCON", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __ID3v2_setFrameByName(tag2, "TCOM", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __ID3v2_setFrameByName(tag2, "TCOP", value); - case METADATA_EDITOR_ATTR_DATE: return __ID3_setTwixFrameByName(tag1, tag2, "TDRC", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __ID3v2_setFrameByName(tag2, "TIT3", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __ID3_setTwixFrameByName(tag1, tag2, "TRCK", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __ID3v2_setFrameByName(tag2, "TPE3", value); - case METADATA_EDITOR_ATTR_COMMENT: return __ID3_setTwixCommentFrame(tag1, tag2, value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __ID3_setLyricsFrame(tag2, value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } - - return METADATA_EDITOR_ERROR_NONE; -} - -static int __set_ogg_metadata(Ogg::XiphComment *xtag, metadata_editor_attr_e attribute, const char *value) -{ - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __xiph_updateFieldValue(xtag, "ARTIST", value); - case METADATA_EDITOR_ATTR_TITLE: return __xiph_updateFieldValue(xtag, "TITLE", value); - case METADATA_EDITOR_ATTR_ALBUM: return __xiph_updateFieldValue(xtag, "ALBUM", value); - case METADATA_EDITOR_ATTR_GENRE: return __xiph_updateFieldValue(xtag, "GENRE", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __xiph_updateFieldValue(xtag, "COMPOSER", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __xiph_updateFieldValue(xtag, "COPYRIGHT", value); - case METADATA_EDITOR_ATTR_DATE: return __xiph_updateFieldValue(xtag, "DATE", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __xiph_updateFieldValue(xtag, "DESCRIPTION", value); - case METADATA_EDITOR_ATTR_COMMENT: return __xiph_updateFieldValue(xtag, "COMMENT", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __xiph_updateFieldValue(xtag, "TRACKNUMBER", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __xiph_updateFieldValue(xtag, "CONDUCTOR", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __xiph_updateFieldValue(xtag, "LYRICS", value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } -} - static char * __get_mime_type(const String& mime_type) { if (mime_type == MIME_TYPE_JPEG || mime_type == MIME_TYPE_PNG) @@ -834,29 +234,19 @@ static int __is_valid_picture_index(bool is_empty, unsigned int list_size, int i { metadata_editor_debug("list size [%d] picture index[%d]", list_size, index); - if (is_empty) { - metadata_editor_error("No pictures in file"); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } - - if ((index < 0) || (list_size <= (uint)index)) { - metadata_editor_error("Index of picture is out of range"); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } + metadata_editor_retvm_if(is_empty, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "No picture"); + metadata_editor_retvm_if((index < 0) || (list_size <= (uint)index), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Out of range"); return METADATA_EDITOR_ERROR_NONE; } static int __get_APIC(ID3v2::Tag *tag, int index, void **picture, int *size, char **mime_type) { - int ret = METADATA_EDITOR_ERROR_NONE; - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); auto lst = tag->frameListMap()["APIC"]; - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); auto pictureFrame = static_cast(lst[index]); @@ -872,14 +262,11 @@ static int __get_APIC(ID3v2::Tag *tag, int index, void **picture, int *size, cha static int __get_ogg_picture(Ogg::XiphComment *xtag, int index, void **picture, int *size, char **mime_type) { - int ret = METADATA_EDITOR_ERROR_NONE; - - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); + metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid XiphComment"); auto lst = xtag->pictureList(); - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); auto pictureFrame = static_cast(lst[index]); @@ -895,7 +282,7 @@ static int __get_ogg_picture(Ogg::XiphComment *xtag, int index, void **picture, static int __append_APIC(ID3v2::Tag *tag, const char *picture, size_t size, const char *mime_type) { - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); + metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Invalid ID3v2"); auto pictureFrame = new ID3v2::AttachedPictureFrame(); @@ -913,7 +300,7 @@ static int __append_APIC(ID3v2::Tag *tag, const char *picture, size_t size, cons static int __append_ogg_picture(Ogg::XiphComment *xtag, const char *picture, size_t size, const char *mime_type) { - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); + metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Invalid XiphComment"); auto frontCover = new FLAC::Picture; @@ -928,14 +315,11 @@ static int __append_ogg_picture(Ogg::XiphComment *xtag, const char *picture, siz static int __remove_APIC(ID3v2::Tag *tag, int index) { - int ret = METADATA_EDITOR_ERROR_NONE; - - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); + metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid ID3v2"); auto lst = tag->frameListMap()["APIC"]; - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); tag->removeFrame(lst[index]); @@ -944,14 +328,11 @@ static int __remove_APIC(ID3v2::Tag *tag, int index) static int __remove_ogg_picture(Ogg::XiphComment *xtag, int index) { - int ret = METADATA_EDITOR_ERROR_NONE; - - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); + metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid XiphComment"); auto lst = xtag->pictureList(); - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); TagLib::List::Iterator it = lst.begin(); std::advance(it, index); @@ -960,463 +341,306 @@ static int __remove_ogg_picture(Ogg::XiphComment *xtag, int index) return METADATA_EDITOR_ERROR_NONE; } - -int Mp3MetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __append_APIC(_file->ID3v2Tag(true), picture, size, mime_type); -} - -int Mp3MetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __get_APIC(_file->ID3v2Tag(), index, picture, size, mime_type); -} - -int Mp3MetadataFile::removePicture(int index) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __remove_APIC(_file->ID3v2Tag(true), index); -} - -int Mp3MetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) +static int __append_picture(File *f, metadata_editor_format_e format, const char *picture, size_t size, const char *mime_type) { - metadata_editor_retvm_if(file->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "File is readonly. Unable to modify"); + metadata_editor_retvm_if(!f, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __set_ID3_tag(attribute, _file->ID3v1Tag(), _file->ID3v2Tag(true), value); -} - -int Mp3MetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __get_ID3_tag(attribute, _file->ID3v1Tag(), _file->ID3v2Tag(), value); -} + switch (format) { + case METADATA_EDITOR_FORMAT_MP3: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __append_APIC(_file->ID3v2Tag(true), picture, size, mime_type); + } + case METADATA_EDITOR_FORMAT_MP4: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto tag = dynamic_cast(_file->tag()); + MP4::CoverArtList lst; + auto format = MP4::CoverArt::Unknown; + if (strncmp(mime_type, MIME_TYPE_JPEG, strlen(MIME_TYPE_JPEG)) == 0) + format = MP4::CoverArt::JPEG; + else if (strncmp(mime_type, MIME_TYPE_PNG, strlen(MIME_TYPE_PNG)) == 0) + format = MP4::CoverArt::PNG; -int Mp3MetadataFile::updateMetadata() -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + if (tag->contains("covr")) { + metadata_editor_info("The item exists. Adding picture"); + lst = tag->item("covr").toCoverArtList(); + } - auto tag1 = _file->ID3v1Tag(); + lst.append(MP4::CoverArt(format, ByteVector(picture, size))); + tag->setItem("covr", lst); - if (!tag1 || tag1->isEmpty()) { // If no ID3v1 tag - prevent its creation - if (_file->save(MPEG::File::ID3v2 | MPEG::File::APE)) - return METADATA_EDITOR_ERROR_NONE; - } else { // otherwise - save all tags in file - if (_file->save(MPEG::File::AllTags)) - return METADATA_EDITOR_ERROR_NONE; + return METADATA_EDITOR_ERROR_NONE; } + case METADATA_EDITOR_FORMAT_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto frontCover = new FLAC::Picture; - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} + frontCover->setData(ByteVector(picture, size)); + frontCover->setType(FLAC::Picture::FrontCover); + frontCover->setMimeType(mime_type); -int Mp4MetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - auto tag = dynamic_cast(file->tag()); - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - - MP4::CoverArtList lst; - auto format = MP4::CoverArt::Unknown; - if (strncmp(mime_type, MIME_TYPE_JPEG, strlen(MIME_TYPE_JPEG)) == 0) - format = MP4::CoverArt::JPEG; - else if (strncmp(mime_type, MIME_TYPE_PNG, strlen(MIME_TYPE_PNG)) == 0) - format = MP4::CoverArt::PNG; - - if (tag->contains("covr")) { - metadata_editor_info("The item exists. Adding picture"); - lst = tag->item("covr").toCoverArtList(); + _file->addPicture(frontCover); + return METADATA_EDITOR_ERROR_NONE; } - - lst.append(MP4::CoverArt(format, ByteVector(picture, size))); - tag->setItem("covr", lst); - - return METADATA_EDITOR_ERROR_NONE; -} - -int Mp4MetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) -{ - int ret = METADATA_EDITOR_ERROR_NONE; - - auto tag = dynamic_cast(file->tag()); - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); - - if (!(tag->contains("covr"))) { - metadata_editor_error("No item in file. No pictures in file"); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + case METADATA_EDITOR_FORMAT_OGG_VORBIS: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __append_ogg_picture(_file->tag(), picture, size, mime_type); } - - auto lst = tag->item("covr").toCoverArtList(); - - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); - - auto pictureFrame = static_cast(lst[index]); - - int pictureSize = pictureFrame.data().size(); - metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0"); - - *picture = g_memdup2(pictureFrame.data().data(), pictureSize); - *size = pictureSize; - *mime_type = __get_mime_type_from_cover_art(pictureFrame); - - return METADATA_EDITOR_ERROR_NONE; -} - -int Mp4MetadataFile::removePicture(int index) -{ - int ret = METADATA_EDITOR_ERROR_NONE; - - auto tag = dynamic_cast(file->tag()); - metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Tag does not exist"); - - if (!(tag->contains("covr"))) { - metadata_editor_error("No item in file. No pictures in file"); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + case METADATA_EDITOR_FORMAT_OGG_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __append_ogg_picture(_file->tag(), picture, size, mime_type); } - - auto lst = tag->item("covr").toCoverArtList(); - - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); - - auto picIt = lst.begin(); - std::advance(picIt, index); - lst.erase(picIt); - - tag->setItem("covr", lst); //?? FIX ME! - - return METADATA_EDITOR_ERROR_NONE; -} - -int Mp4MetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) -{ - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""ART", value); - case METADATA_EDITOR_ATTR_TITLE: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""nam", value); - case METADATA_EDITOR_ATTR_ALBUM: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""alb", value); - case METADATA_EDITOR_ATTR_GENRE: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""gen", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""wrt", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __MP4_updateStringItem(dynamic_cast(file->tag()), "cprt", value); - case METADATA_EDITOR_ATTR_DATE: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""day", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __MP4_updateStringItem(dynamic_cast(file->tag()), "desc", value); - case METADATA_EDITOR_ATTR_COMMENT: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""cmt", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __MP4_updateIntegerItem(dynamic_cast(file->tag()), "trkn", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __MP4_updateStringItem(dynamic_cast(file->tag()), "cond", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __MP4_updateStringItem(dynamic_cast(file->tag()), "\xA9""lyr", value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + case METADATA_EDITOR_FORMAT_WAV: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __append_APIC(dynamic_cast(_file->tag()), picture, size, mime_type); } -} - -int Mp4MetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - switch (attribute) { // Check which one of frame types was given to the function for processing - case METADATA_EDITOR_ATTR_ARTIST: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""ART", value); - case METADATA_EDITOR_ATTR_TITLE: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""nam", value); - case METADATA_EDITOR_ATTR_ALBUM: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""alb", value); - case METADATA_EDITOR_ATTR_GENRE: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""gen", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""wrt", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __MP4_getStringItem(dynamic_cast(file->tag()), "cprt", value); - case METADATA_EDITOR_ATTR_DATE: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""day", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __MP4_getStringItem(dynamic_cast(file->tag()), "desc", value); - case METADATA_EDITOR_ATTR_COMMENT: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""cmt", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __MP4_getIntegerItem(dynamic_cast(file->tag()), "trkn", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __MP4_getStringItem(dynamic_cast(file->tag()), "cond", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __MP4_getStringItem(dynamic_cast(file->tag()), "\xA9""lyr", value); - case METADATA_EDITOR_ATTR_PICTURE_NUM: return __MP4_getNumberOfPictures(dynamic_cast(file->tag()), value); default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; - } -} - -int Mp4MetadataFile::updateMetadata() -{ - if (file->save()) return METADATA_EDITOR_ERROR_NONE; - - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} - -int FlacMetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - auto frontCover = new FLAC::Picture; - - frontCover->setData(ByteVector(picture, size)); - frontCover->setType(FLAC::Picture::FrontCover); - frontCover->setMimeType(mime_type); - - _file->addPicture(frontCover); - - return METADATA_EDITOR_ERROR_NONE; -} - -int FlacMetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) -{ - int ret = METADATA_EDITOR_ERROR_NONE; - - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - auto lst = _file->pictureList(); - - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); - - auto pictureFrame = static_cast(lst[index]); - - int pictureSize = pictureFrame->data().size(); - metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0"); - - *picture = g_memdup2(pictureFrame->data().data(), pictureSize); - *size = pictureSize; - *mime_type = __get_mime_type(pictureFrame->mimeType()); - - return METADATA_EDITOR_ERROR_NONE; + } } -int FlacMetadataFile::removePicture(int index) +static int __remove_picture(File *f, metadata_editor_format_e format, int index) { - int ret = METADATA_EDITOR_ERROR_NONE; + metadata_editor_retvm_if(!f, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + switch (format) { + case METADATA_EDITOR_FORMAT_MP3: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __remove_APIC(_file->ID3v2Tag(true), index); + } + case METADATA_EDITOR_FORMAT_MP4: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto tag = dynamic_cast(_file->tag()); - auto lst = _file->pictureList(); + metadata_editor_retvm_if(!(tag->contains("covr")), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "No picture"); - ret = __is_valid_picture_index(lst.isEmpty(), lst.size(), index); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid picture index"); + auto lst = tag->item("covr").toCoverArtList(); - _file->removePicture(lst[index], true); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); - return METADATA_EDITOR_ERROR_NONE; -} + auto picIt = lst.begin(); + std::advance(picIt, index); + lst.erase(picIt); -int FlacMetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - auto xtag = _file->xiphComment(true); - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to create Xiph Comment. Can not proceed metadata updating"); + tag->setItem("covr", lst); //?? FIX ME! - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __xiph_updateFieldValue(xtag, "ARTIST", value); - case METADATA_EDITOR_ATTR_TITLE: return __xiph_updateFieldValue(xtag, "TITLE", value); - case METADATA_EDITOR_ATTR_ALBUM: return __xiph_updateFieldValue(xtag, "ALBUM", value); - case METADATA_EDITOR_ATTR_GENRE: return __xiph_updateFieldValue(xtag, "GENRE", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __xiph_updateFieldValue(xtag, "COMPOSER", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __xiph_updateFieldValue(xtag, "COPYRIGHT", value); - case METADATA_EDITOR_ATTR_DATE: return __xiph_updateFieldValue(xtag, "DATE", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __xiph_updateFieldValue(xtag, "DESCRIPTION", value); - case METADATA_EDITOR_ATTR_COMMENT: return __xiph_updateFieldValue(xtag, "COMMENT", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __xiph_updateFieldValue(xtag, "TRACKNUMBER", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __xiph_updateFieldValue(xtag, "CONDUCTOR", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __xiph_updateFieldValue(xtag, "LYRICS", value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + return METADATA_EDITOR_ERROR_NONE; } -} - -int FlacMetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + case METADATA_EDITOR_FORMAT_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto lst = _file->pictureList(); - auto xtag = _file->xiphComment(false); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); - switch (attribute) { - case METADATA_EDITOR_ATTR_ARTIST: return __xiph_getFieldValue(xtag, "ARTIST", value); - case METADATA_EDITOR_ATTR_TITLE: return __xiph_getFieldValue(xtag, "TITLE", value); - case METADATA_EDITOR_ATTR_ALBUM: return __xiph_getFieldValue(xtag, "ALBUM", value); - case METADATA_EDITOR_ATTR_GENRE: return __xiph_getFieldValue(xtag, "GENRE", value); - case METADATA_EDITOR_ATTR_AUTHOR: return __xiph_getFieldValue(xtag, "COMPOSER", value); - case METADATA_EDITOR_ATTR_COPYRIGHT: return __xiph_getFieldValue(xtag, "COPYRIGHT", value); - case METADATA_EDITOR_ATTR_DATE: return __xiph_getFieldValue(xtag, "DATE", value); - case METADATA_EDITOR_ATTR_DESCRIPTION: return __xiph_getFieldValue(xtag, "DESCRIPTION", value); - case METADATA_EDITOR_ATTR_COMMENT: return __xiph_getFieldValue(xtag, "COMMENT", value); - case METADATA_EDITOR_ATTR_TRACK_NUM: return __xiph_getFieldValue(xtag, "TRACKNUMBER", value); - case METADATA_EDITOR_ATTR_CONDUCTOR: return __xiph_getFieldValue(xtag, "CONDUCTOR", value); - case METADATA_EDITOR_ATTR_UNSYNCLYRICS: return __xiph_getFieldValue(xtag, "LYRICS", value); - case METADATA_EDITOR_ATTR_PICTURE_NUM: return __FLAC_getNumberOfPictures(_file, value); - default: - metadata_editor_error("Invalid attribute [%d]", attribute); - return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + _file->removePicture(lst[index], true); + return METADATA_EDITOR_ERROR_NONE; } -} - -int FlacMetadataFile::updateMetadata() -{ - if (file->save()) + case METADATA_EDITOR_FORMAT_OGG_VORBIS: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __remove_ogg_picture(_file->tag(), index); + } + case METADATA_EDITOR_FORMAT_OGG_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __remove_ogg_picture(_file->tag(), index); + } + case METADATA_EDITOR_FORMAT_WAV: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __remove_APIC(dynamic_cast(_file->tag()), index); + } + default: return METADATA_EDITOR_ERROR_NONE; - - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} - -int OggVorbisMetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __append_ogg_picture(_file->tag(), picture, size, mime_type); + } } -int OggVorbisMetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) +static int __get_picture(File *f, metadata_editor_format_e format, int index, void **picture, int *size, char **mime_type) { - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __get_ogg_picture(_file->tag(), index, picture, size, mime_type); -} + metadata_editor_retvm_if(!f, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + metadata_editor_retvm_if(!picture, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture"); + metadata_editor_retvm_if(!size, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid size"); + metadata_editor_retvm_if(!mime_type, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid mime_type"); -int OggVorbisMetadataFile::removePicture(int index) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + switch (format) { + case METADATA_EDITOR_FORMAT_MP3: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __get_APIC(_file->ID3v2Tag(), index, picture, size, mime_type); + } + case METADATA_EDITOR_FORMAT_MP4: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto tag = dynamic_cast(_file->tag()); - return __remove_ogg_picture(_file->tag(), index); -} + metadata_editor_retvm_if(!(tag->contains("covr")), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "No picture"); -int OggVorbisMetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + auto lst = tag->item("covr").toCoverArtList(); - auto xtag = _file->tag(); - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); - return __set_ogg_metadata(xtag, attribute, value); -} + auto pictureFrame = static_cast(lst[index]); -int OggVorbisMetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + int pictureSize = pictureFrame.data().size(); + metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0"); - return __get_ogg_metadata(_file->tag(), attribute, value); -} + *picture = g_memdup2(pictureFrame.data().data(), pictureSize); + *size = pictureSize; + *mime_type = __get_mime_type_from_cover_art(pictureFrame); -int OggVorbisMetadataFile::updateMetadata() -{ - if (file->save()) return METADATA_EDITOR_ERROR_NONE; + } + case METADATA_EDITOR_FORMAT_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto lst = _file->pictureList(); - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} - -int OggFlacMetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - return __append_ogg_picture(_file->tag(), picture, size, mime_type); -} + metadata_editor_retvm_if(__is_valid_picture_index(lst.isEmpty(), lst.size(), index) != METADATA_EDITOR_ERROR_NONE, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture index"); -int OggFlacMetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + auto pictureFrame = static_cast(lst[index]); - return __get_ogg_picture(_file->tag(), index, picture, size, mime_type); -} + int pictureSize = pictureFrame->data().size(); + metadata_editor_retvm_if(pictureSize == 0, METADATA_EDITOR_ERROR_OPERATION_FAILED, "Size of picture is 0"); -int OggFlacMetadataFile::removePicture(int index) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + *picture = g_memdup2(pictureFrame->data().data(), pictureSize); + *size = pictureSize; + *mime_type = __get_mime_type(pictureFrame->mimeType()); - return __remove_ogg_picture(_file->tag(), index); + return METADATA_EDITOR_ERROR_NONE; + } + case METADATA_EDITOR_FORMAT_OGG_VORBIS: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __get_ogg_picture(_file->tag(), index, picture, size, mime_type); + } + case METADATA_EDITOR_FORMAT_OGG_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __get_ogg_picture(_file->tag(), index, picture, size, mime_type); + } + case METADATA_EDITOR_FORMAT_WAV:{ + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + return __get_APIC(_file->tag(), index, picture, size, mime_type); + } + default: + return METADATA_EDITOR_ERROR_NONE; + } } -int OggFlacMetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) +static int __get_picture_number(File *f, metadata_editor_format_e format, char **value) { - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); - - auto xtag = _file->tag(); - metadata_editor_retvm_if(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Tag does not exist"); - - return __set_ogg_metadata(xtag, attribute, value); -} + metadata_editor_retvm_if(!f, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); -int OggFlacMetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + switch (format) { + case METADATA_EDITOR_FORMAT_MP3: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + *value = g_strdup_printf("%u", _file->ID3v2Tag() ? _file->ID3v2Tag()->frameListMap()["APIC"].size() : 0); + break; + } + case METADATA_EDITOR_FORMAT_MP4: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + if (_file->tag() && _file->tag()->contains("covr")) + *value = g_strdup_printf("%u", _file->tag()->item("covr").toCoverArtList().size()); + else + *value = g_strdup_printf("0"); + break; + } + case METADATA_EDITOR_FORMAT_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + *value = g_strdup_printf("%u", _file ? _file->pictureList().size() : 0); + break; + } + case METADATA_EDITOR_FORMAT_OGG_VORBIS: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + *value = g_strdup_printf("%u", _file->tag() ? _file->tag()->pictureList().size() : 0); + break; + } + case METADATA_EDITOR_FORMAT_OGG_FLAC: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + *value = g_strdup_printf("%u", _file->tag() ? _file->tag()->pictureList().size() : 0); + break; + } + case METADATA_EDITOR_FORMAT_WAV: { + auto _file = dynamic_cast(f); + metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + auto tag = dynamic_cast(_file->tag()); + metadata_editor_retvm_if(!tag, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid tag"); + *value = g_strdup_printf("%u", tag ? tag->frameListMap()["APIC"].size() : 0); + break; + } + default: + break; + } - return __get_ogg_metadata(_file->tag(), attribute, value); + return METADATA_EDITOR_ERROR_NONE; } -int OggFlacMetadataFile::updateMetadata() +static int __set_to_property_map(File *file, String key, const char *value) { - if (file->save()) - return METADATA_EDITOR_ERROR_NONE; + metadata_editor_retvm_if(!file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file"); + metadata_editor_retvm_if(key.isEmpty(), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid key"); - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} + PropertyMap tags = file->properties(); -int WavMetadataFile::appendPicture(const char *picture ,size_t size, const char *mime_type) -{ - return __append_APIC(dynamic_cast(file->tag()), picture, size, mime_type); -} + if (value == NULL || strlen(value) == 0) + tags.erase(key); + else + tags.replace(key, StringList(String(value, String::UTF8))); -int WavMetadataFile::getPicture(int index, void **picture, int *size, char **mime_type) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + file->setProperties(tags); - return __get_APIC(_file->tag(), index, picture, size, mime_type); + return METADATA_EDITOR_ERROR_NONE; } -int WavMetadataFile::removePicture(int index) +static int __get_from_property_map(PropertyMap tags, String key, char **value) { - return __remove_APIC(dynamic_cast(file->tag()), index); -} + metadata_editor_retvm_if(key.isEmpty(), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid field_name"); + metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); -int WavMetadataFile::setMetadata(metadata_editor_attr_e attribute, const char *value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + if (tags.isEmpty()) + return METADATA_EDITOR_ERROR_NONE; - return __set_ID3_tag(attribute, NULL, _file->tag(), value); -} + PropertyMap::ConstIterator found = tags.find(key); -int WavMetadataFile::getMetadata(metadata_editor_attr_e attribute, char **value) -{ - auto _file = dynamic_cast(file); - metadata_editor_retvm_if(!_file, METADATA_EDITOR_ERROR_OPERATION_FAILED, "fail to dynamic_cast"); + if (found != tags.end()) + *value = g_strdup(found->second[0].toCString(true)); - return __get_ID3_tag(attribute, NULL, _file->tag(), value); + return METADATA_EDITOR_ERROR_NONE; } -int WavMetadataFile::updateMetadata() -{ - if (file->save()) - return METADATA_EDITOR_ERROR_NONE; - - return METADATA_EDITOR_ERROR_OPERATION_FAILED; -} +class OggFileTypeResolver : public TagLib::FileRef::FileTypeResolver { + TagLib::File *createFile(TagLib::FileName fileName, bool, AudioProperties::ReadStyle) const { + char ext[EXT_LEN] = {0, }; + if (__metadata_editor_get_file_ext(fileName, ext, EXT_LEN)) { + if (strcasecmp(ext, "OGG") == 0) { + File *file = new Ogg::FLAC::File(fileName); + if(file->isValid()) + return file; + delete file; + return new Ogg::Vorbis::File(fileName); + } + } + return 0; + } +}; extern "C" int metadata_editor_create(metadata_editor_h *metadata) { - metadata_editor_debug_fenter(); - metadata_editor_retvm_if(!metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); metadata_editor_s* _metadata = (metadata_editor_s*)malloc(sizeof(metadata_editor_s)); @@ -1432,7 +656,7 @@ extern "C" int metadata_editor_destroy(metadata_editor_h metadata) auto _metadata = static_cast(metadata); metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); - delete _metadata->intf; + delete _metadata->fref; free(_metadata); return METADATA_EDITOR_ERROR_NONE; @@ -1441,62 +665,36 @@ extern "C" int metadata_editor_destroy(metadata_editor_h metadata) extern "C" int metadata_editor_set_path(metadata_editor_h metadata, const char *path) { int ret = METADATA_EDITOR_ERROR_NONE; - int media_type = METADATA_EDITOR_FORMAT_NOTYPE; + metadata_editor_format_e media_type = METADATA_EDITOR_FORMAT_NOTYPE; auto _metadata = static_cast(metadata); - metadata_editor_debug_fenter(); - metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); ret = __check_file_validity(path); metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid path"); media_type = __metadata_editor_get_file_type(path); + metadata_editor_retvm_if(media_type == METADATA_EDITOR_FORMAT_NOTYPE, ret, "Not supported type [%d]", media_type); - if (_metadata->intf) { - metadata_editor_info("file free [%p]", _metadata->intf); - delete _metadata->intf; + if (_metadata->fref) { + metadata_editor_info("file free [%p]", _metadata->fref); + delete _metadata->fref; } metadata_editor_debug("media_type : [%d]", media_type); - + _metadata->format = media_type; try { - switch (media_type) { - case METADATA_EDITOR_FORMAT_MP3: - _metadata->intf = new Mp3MetadataFile(path); - break; - - case METADATA_EDITOR_FORMAT_MP4: - _metadata->intf = new Mp4MetadataFile(path); - break; - - case METADATA_EDITOR_FORMAT_FLAC: - _metadata->intf = new FlacMetadataFile(path); - break; - - case METADATA_EDITOR_FORMAT_OGG_VORBIS: - _metadata->intf = new OggVorbisMetadataFile(path); - break; - - case METADATA_EDITOR_FORMAT_OGG_FLAC: - _metadata->intf = new OggFlacMetadataFile(path); - break; - - case METADATA_EDITOR_FORMAT_WAV: - _metadata->intf = new WavMetadataFile(path); - break; - - default: - metadata_editor_error("Not supported file type [%d]", media_type); - return METADATA_EDITOR_ERROR_NOT_SUPPORTED; - } + //FileTypeResolver is not deleted until terminated. So, it should be called only once. + static auto oggResolver = FileRef::addFileTypeResolver(new OggFileTypeResolver); + metadata_editor_info("%p", oggResolver); + _metadata->fref = new FileRef(path); } catch (const std::bad_alloc &ex) { - metadata_editor_retvm_if(!_metadata->intf, METADATA_EDITOR_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY"); } - if (!_metadata->intf->isOpen()) { - delete _metadata->intf; - _metadata->intf = nullptr; + if (!_metadata->fref->file()->isOpen()) { + delete _metadata->fref; + _metadata->fref = nullptr; return METADATA_EDITOR_ERROR_PERMISSION_DENIED; } @@ -1505,13 +703,15 @@ extern "C" int metadata_editor_set_path(metadata_editor_h metadata, const char * extern "C" int metadata_editor_append_picture(metadata_editor_h metadata, const char *path) { + int ret = METADATA_EDITOR_ERROR_NONE; char *picture = NULL; size_t size = 0; char *mime_type = NULL; auto _metadata = static_cast(metadata); - int ret = __check_metadata_set_parameter(_metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_set_parameter() [%d]", ret); + metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); + metadata_editor_retvm_if(_metadata->fref->file()->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "Readonly error"); metadata_editor_retvm_if(!path, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid path"); ret = __check_file_validity(path); @@ -1520,7 +720,7 @@ extern "C" int metadata_editor_append_picture(metadata_editor_h metadata, const ret = __metadata_editor_get_picture_info(path, &picture, &size, &mime_type); metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "File does not exist or you have no rights to open it"); - ret = _metadata->intf->appendPicture(picture, size, mime_type); + ret = __append_picture(_metadata->fref->file(), _metadata->format, picture, size, mime_type); g_free(picture); g_free(mime_type); @@ -1532,51 +732,118 @@ extern "C" int metadata_editor_remove_picture(metadata_editor_h metadata, int in { auto _metadata = static_cast(metadata); - int ret = __check_metadata_set_parameter(_metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_set_parameter() [%d]", ret); + metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); + metadata_editor_retvm_if(_metadata->fref->file()->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "Readonly error"); - return _metadata->intf->removePicture(index); + return __remove_picture(_metadata->fref->file(), _metadata->format, index); } extern "C" int metadata_editor_get_picture(metadata_editor_h metadata, int index, void **picture, int *size, char **mime_type) { auto _metadata = static_cast(metadata); - int 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(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); metadata_editor_retvm_if(!picture, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture"); metadata_editor_retvm_if(!size, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid size"); + metadata_editor_retvm_if(!mime_type, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid mime_type"); - return _metadata->intf->getPicture(index, picture, size, mime_type); + return __get_picture(_metadata->fref->file(), _metadata->format, index, picture, size, mime_type); } extern "C" int metadata_editor_set_metadata(metadata_editor_h metadata, metadata_editor_attr_e attribute, const char *value) { auto _metadata = static_cast(metadata); - int ret = __check_metadata_set_parameter(_metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_set_parameter() [%d]", ret); + metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); + metadata_editor_retvm_if(_metadata->fref->file()->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "Readonly error"); - return _metadata->intf->setMetadata(attribute, value); + switch (attribute) { + case METADATA_EDITOR_ATTR_ARTIST: + return __set_to_property_map(_metadata->fref->file(), String("ARTIST"), value); + case METADATA_EDITOR_ATTR_TITLE: + return __set_to_property_map(_metadata->fref->file(), String("TITLE"), value); + case METADATA_EDITOR_ATTR_ALBUM: + return __set_to_property_map(_metadata->fref->file(), String("ALBUM"), value); + case METADATA_EDITOR_ATTR_GENRE: + return __set_to_property_map(_metadata->fref->file(), String("GENRE"), value); + case METADATA_EDITOR_ATTR_AUTHOR: + return __set_to_property_map(_metadata->fref->file(), String("COMPOSER"), value); + case METADATA_EDITOR_ATTR_COPYRIGHT: + return __set_to_property_map(_metadata->fref->file(), String("COPYRIGHT"), value); + case METADATA_EDITOR_ATTR_DATE: + return __set_to_property_map(_metadata->fref->file(), String("DATE"), value); + case METADATA_EDITOR_ATTR_DESCRIPTION: + return __set_to_property_map(_metadata->fref->file(), String("DESCRIPTION"), value); + case METADATA_EDITOR_ATTR_COMMENT: + return __set_to_property_map(_metadata->fref->file(), String("COMMENT"), value); + case METADATA_EDITOR_ATTR_TRACK_NUM: + return __set_to_property_map(_metadata->fref->file(), String("TRACKNUMBER"), value); + case METADATA_EDITOR_ATTR_CONDUCTOR: + return __set_to_property_map(_metadata->fref->file(), String("CONDUCTOR"), value); + case METADATA_EDITOR_ATTR_UNSYNCLYRICS: + return __set_to_property_map(_metadata->fref->file(), String("LYRICS"), value); + default: + metadata_editor_error("Invalid attribute"); + return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + } } extern "C" int metadata_editor_get_metadata(metadata_editor_h metadata, metadata_editor_attr_e attribute, char **value) { auto _metadata = static_cast(metadata); - int ret = __check_metadata_get_parameter(_metadata, value); + metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); + metadata_editor_retvm_if(!value, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid value"); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_get_parameter() [%d]", ret); + PropertyMap tags = _metadata->fref->file()->properties(); - return _metadata->intf->getMetadata(attribute, value); + switch (attribute) { + case METADATA_EDITOR_ATTR_ARTIST: + return __get_from_property_map(tags, String("ARTIST"), value); + case METADATA_EDITOR_ATTR_TITLE: + return __get_from_property_map(tags, String("TITLE"), value); + case METADATA_EDITOR_ATTR_ALBUM: + return __get_from_property_map(tags, String("ALBUM"), value); + case METADATA_EDITOR_ATTR_GENRE: + return __get_from_property_map(tags, String("GENRE"), value); + case METADATA_EDITOR_ATTR_AUTHOR: + return __get_from_property_map(tags, String("COMPOSER"), value); + case METADATA_EDITOR_ATTR_COPYRIGHT: + return __get_from_property_map(tags, String("COPYRIGHT"), value); + case METADATA_EDITOR_ATTR_DATE: + return __get_from_property_map(tags, String("DATE"), value); + case METADATA_EDITOR_ATTR_DESCRIPTION: + return __get_from_property_map(tags, String("DESCRIPTION"), value); + case METADATA_EDITOR_ATTR_COMMENT: + return __get_from_property_map(tags, String("COMMENT"), value); + case METADATA_EDITOR_ATTR_TRACK_NUM: + return __get_from_property_map(tags, String("TRACKNUMBER"), value); + case METADATA_EDITOR_ATTR_CONDUCTOR: + return __get_from_property_map(tags, String("CONDUCTOR"), value); + case METADATA_EDITOR_ATTR_UNSYNCLYRICS: + return __get_from_property_map(tags, String("LYRICS"), value); + case METADATA_EDITOR_ATTR_PICTURE_NUM: + return __get_picture_number(_metadata->fref->file(), _metadata->format, value); + default: + metadata_editor_error("Invalid attribute [%d]", attribute); + return METADATA_EDITOR_ERROR_INVALID_PARAMETER; + } } extern "C" int metadata_editor_update_metadata(metadata_editor_h metadata) { auto _metadata = static_cast(metadata); - int ret = __check_metadata_set_parameter(_metadata); - metadata_editor_retvm_if(ret != METADATA_EDITOR_ERROR_NONE, ret, "fail to __check_metadata_set_parameter() [%d]", ret); + metadata_editor_retvm_if(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata"); + metadata_editor_retvm_if(!_metadata->fref, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "File loading fail"); + metadata_editor_retvm_if(_metadata->fref->file()->readOnly(), METADATA_EDITOR_ERROR_PERMISSION_DENIED, "Readonly error"); - return _metadata->intf->updateMetadata(); -} + if (!_metadata->fref->file()->save()) + return METADATA_EDITOR_ERROR_OPERATION_FAILED; + + return METADATA_EDITOR_ERROR_NONE; +} \ No newline at end of file