#include <taglib/vorbisfile.h>
#include <taglib/wavfile.h>
#include <taglib/attachedpictureframe.h>
+#include <taglib/tfilestream.h>
using namespace TagLib;
return METADATA_EDITOR_FORMAT_NOTYPE;
}
-static char * __get_picture_type(const char *path)
+static const String __get_picture_type(const char *path)
{
String ext = __get_file_ext(path);
if (ext == "JPG" || ext == "JPEG") {
- return g_strdup(MIME_TYPE_JPEG);
+ return MIME_TYPE_JPEG;
} else if (ext == "PNG") {
- return g_strdup(MIME_TYPE_PNG);
+ return MIME_TYPE_PNG;
}
-
- return NULL;
+ return "";
}
-static int __metadata_editor_get_picture_info(const char *path, char **picture, size_t *size, char **type)
+class PictureFrame
{
- int ret = METADATA_EDITOR_ERROR_NONE;
- GError *error = NULL;
- char *mime_type = NULL;
-
- mime_type = __get_picture_type(path);
- ME_RETVM_IF(!mime_type, METADATA_EDITOR_ERROR_NOT_SUPPORTED, "Unsupported type");
-
- if (!g_file_get_contents(path, picture, size, &error)) {
- ME_ERR("Unable to read [%s], error [%s]", path, error->message);
- if (error->code == G_FILE_ERROR_NOENT || error->code == G_FILE_ERROR_ISDIR)
- ret = METADATA_EDITOR_ERROR_FILE_EXISTS;
+public:
+ explicit PictureFrame(const char *path) : stream(path, true) {}
+ ~PictureFrame() = default;
+ TagLib::ByteVector data() {
+ return stream.readBlock(stream.length());
+ }
+ TagLib::String mime() const {
+ return __get_picture_type(stream.name());
+ }
+ bool opened() {
+ return stream.isOpen();
+ }
+ MP4::CoverArt::Format mp4format() {
+ if (mime() == MIME_TYPE_JPEG)
+ return MP4::CoverArt::JPEG;
+ else if (mime() == MIME_TYPE_PNG)
+ return MP4::CoverArt::PNG;
else
- ret = METADATA_EDITOR_ERROR_PERMISSION_DENIED;
-
- g_error_free(error);
- g_free(mime_type);
-
- return ret;
+ return MP4::CoverArt::Unknown;
}
-
- *type = mime_type;
-
- return ret;
-}
+private:
+ TagLib::FileStream stream;
+};
static int __check_file_validity(const char *path)
{
return METADATA_EDITOR_ERROR_NONE;
}
-static int __append_APIC(ID3v2::Tag *tag, const char *picture, size_t size, const char *mime_type)
+static int __append_APIC(ID3v2::Tag *tag, PictureFrame& pic)
{
ME_RETVM_IF(!tag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Invalid ID3v2");
auto pictureFrame = new ID3v2::AttachedPictureFrame();
-
- ME_INFO("New APIC frame will be added to the ID3v2 tag");
-
- pictureFrame->setPicture(ByteVector(picture, size));
- pictureFrame->setType(ID3v2::AttachedPictureFrame::FrontCover);
- pictureFrame->setMimeType(mime_type);
-
+ pictureFrame->setPicture(pic.data());
+ pictureFrame->setMimeType(pic.mime());
tag->addFrame(pictureFrame);
return METADATA_EDITOR_ERROR_NONE;
-
}
-static int __append_ogg_picture(Ogg::XiphComment *xtag, const char *picture, size_t size, const char *mime_type)
+static int __append_ogg_picture(Ogg::XiphComment *xtag, PictureFrame& pic)
{
ME_RETVM_IF(!xtag, METADATA_EDITOR_ERROR_METADATA_UPDATE_NOT_POSSIBLE, "Invalid XiphComment");
auto frontCover = new FLAC::Picture;
-
- frontCover->setData(ByteVector(picture, size));
- frontCover->setType(FLAC::Picture::FrontCover);
- frontCover->setMimeType(mime_type);
-
+ frontCover->setData(pic.data());
+ frontCover->setMimeType(pic.mime());
xtag->addPicture(frontCover);
return METADATA_EDITOR_ERROR_NONE;
return METADATA_EDITOR_ERROR_NONE;
}
-static int __append_picture(File *f, metadata_editor_format_e format, const char *picture, size_t size, const char *mime_type)
+static int __append_picture(File *f, metadata_editor_format_e format, const char *path)
{
ME_RETVM_IF(!f, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
+ PictureFrame pic(path);
+ ME_RETVM_IF(!pic.opened(), METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid picture");
+
switch (format) {
case METADATA_EDITOR_FORMAT_MP3: {
auto _file = dynamic_cast<MPEG::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
- return __append_APIC(_file->ID3v2Tag(true), picture, size, mime_type);
+ return __append_APIC(_file->ID3v2Tag(true), pic);
}
case METADATA_EDITOR_FORMAT_MP4: {
auto _file = dynamic_cast<MP4::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
- auto tag = dynamic_cast<MP4::Tag*>(_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;
- if (tag->contains("covr")) {
+ if (_file->tag()->contains("covr")) {
ME_INFO("The item <covr> exists. Adding picture");
- lst = tag->item("covr").toCoverArtList();
+ lst = _file->tag()->item("covr").toCoverArtList();
}
- lst.append(MP4::CoverArt(format, ByteVector(picture, size)));
- tag->setItem("covr", lst);
+ lst.append(MP4::CoverArt(pic.mp4format(), pic.data()));
+ _file->tag()->setItem("covr", lst);
return METADATA_EDITOR_ERROR_NONE;
}
auto _file = dynamic_cast<FLAC::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
auto frontCover = new FLAC::Picture;
-
- frontCover->setData(ByteVector(picture, size));
- frontCover->setType(FLAC::Picture::FrontCover);
- frontCover->setMimeType(mime_type);
-
+ frontCover->setData(pic.data());
+ frontCover->setMimeType(pic.mime());
_file->addPicture(frontCover);
return METADATA_EDITOR_ERROR_NONE;
}
case METADATA_EDITOR_FORMAT_OGG_VORBIS: {
auto _file = dynamic_cast<Ogg::Vorbis::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
- return __append_ogg_picture(_file->tag(), picture, size, mime_type);
+ return __append_ogg_picture(_file->tag(), pic);
}
case METADATA_EDITOR_FORMAT_OGG_FLAC: {
auto _file = dynamic_cast<Ogg::FLAC::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
- return __append_ogg_picture(_file->tag(), picture, size, mime_type);
+ return __append_ogg_picture(_file->tag(), pic);
}
case METADATA_EDITOR_FORMAT_WAV: {
auto _file = dynamic_cast<RIFF::WAV::File *>(f);
ME_RETVM_IF(!_file, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid file");
- return __append_APIC(dynamic_cast<ID3v2::Tag*>(_file->tag()), picture, size, mime_type);
+ return __append_APIC(dynamic_cast<ID3v2::Tag*>(_file->tag()), pic);
}
default:
return METADATA_EDITOR_ERROR_NONE;
if (_file->tag() && _file->tag()->contains("covr"))
*value = g_strdup_printf("%u", _file->tag()->item("covr").toCoverArtList().size());
else
- *value = g_strdup_printf("0");
+ *value = g_strdup("0");
break;
}
case METADATA_EDITOR_FORMAT_FLAC: {
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_editor_s*>(metadata);
ME_RETVM_IF(!_metadata, METADATA_EDITOR_ERROR_INVALID_PARAMETER, "Invalid metadata");
ret = __check_file_validity(path);
ME_RETVM_IF(ret != METADATA_EDITOR_ERROR_NONE, ret, "Invalid path");
- ret = __metadata_editor_get_picture_info(path, &picture, &size, &mime_type);
- ME_RETVM_IF(ret != METADATA_EDITOR_ERROR_NONE, ret, "File does not exist or you have no rights to open it");
-
- ret = __append_picture(_metadata->fref->file(), _metadata->format, picture, size, mime_type);
-
- g_free(picture);
- g_free(mime_type);
-
- return ret;
+ return __append_picture(_metadata->fref->file(), _metadata->format, path);
}
extern "C" int metadata_editor_remove_picture(metadata_editor_h metadata, int index)