Source

libtaginfo / libtaginfo / apeinfo.cc

Full commit
/*
 * Copyright (C) 2013 Jörn Magens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This Program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file LICENSE.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth 
 * Floor, Boston, MA  02110-1301  USA
 * https://www.gnu.org/licenses/lgpl-2.1.txt
 *
 * Author:
 * 	Jörn Magens <shuerhaaken@googlemail.com>
 * 	Pavel Vasin <rat4vier@gmail.com>
 */



#include "taginfo.h"
#include "taginfo_internal.h"

#define APE_TAG_DISKNO              "DISCNUMBER"
#define APE_TAG_COMPILATION         "COMPILATION"
#define APE_TAG_ALBUMARTIST         "ALBUM ARTIST" 
#define APE_TAG_TRACK               "TRACK"
#define APE_TAG_COMPOSER            "COMPOSER" 
#define APE_TAG_COMMENT             "COMMENT" 
#define APE_TAG_FILE                "FILE" 
#define APE_TAG_FILE_URL            "FILE URL" 
#define APE_TAG_YEAR                "YEAR" 
#define APE_TAG_MEDIA               "MEDIA" 
#define APE_TAG_INDEX               "INDEX" 
#define APE_TAG_COVER_ART_FRONT     "COVER ART (FRONT)" 
#define APE_TAG_COVER_ART_OTHER     "COVER ART (OTHER)" 
#define APE_TAG_NOTES               "NOTES" 
#define APE_TAG_LYRICS              "LYRICS" 
#define APE_TAG_RATING              "RATING"
#define APE_TAG_PLAYCNT             "PLAY_COUNTER"

using namespace TagInfo;
using namespace TagLib;



ApeInfo::ApeInfo(const String &filename) : Info(filename) {
    if(!file_name.isEmpty() && !create_file_ref())
        printf("Error creating file ref! %s\n", filename.toCString(false));
    if(taglib_file) {
        taglib_apetag = ((TagLib::APE::File *) taglib_file)->APETag(true);
        if(!taglib_apetag || taglib_apetag->isEmpty()) { // Use fallback
            taglib_tag = ((TagLib::APE::File *) taglib_file)->tag();
            if(!taglib_tag) {
                printf("Cant get tag object from '%s'\n", file_name.toCString(false));
                valid = false;
            }
        }
    }
    else {
        printf("Cant get tag from '%s'\n", file_name.toCString(false));
        taglib_apetag = NULL;
        valid = false;
    }
}


ApeInfo::~ApeInfo() {
}


bool ApeInfo::create_file_ref() {
    if(file_name.isEmpty())
        return false;
    taglib_file = new TagLib::APE::File(file_name.toCString(false), true, TagLib::AudioProperties::Fast);
    if(taglib_file) {
        return true;
    }
    else {
        printf("TagLib::File creation failed for '%s'\n", file_name.toCString(false));
        return false;
    }
}


bool ApeInfo::read(void) {
    if(Info::read()) {
        if(taglib_apetag && !taglib_apetag->isEmpty()) {
            if(!taglib_tag)
                read_virtual_tags((TagLib::Tag *)taglib_apetag);
            if(taglib_apetag->itemListMap().contains(APE_TAG_COMPOSER)) {
                composer = taglib_apetag->itemListMap()[APE_TAG_COMPOSER].toStringList().front();
            }
            if(taglib_apetag->itemListMap().contains(APE_TAG_DISKNO)) {
                disk_number = 
                  atol(taglib_apetag->itemListMap()[APE_TAG_DISKNO].toStringList().front().toCString(false));
                if(disk_number <= 0)
                    disk_number = 1;
            }
            if(taglib_apetag->itemListMap().contains(APE_TAG_COMPILATION)) {
                is_compilation = 
                    taglib_apetag->itemListMap()[APE_TAG_COMPILATION].toStringList().front() == String("1");
            }
            if(taglib_apetag->itemListMap().contains(APE_TAG_ALBUMARTIST)) {
                album_artist = taglib_apetag->itemListMap()[APE_TAG_ALBUMARTIST].toStringList().front();
            }
            else if(taglib_apetag->itemListMap().contains("ALBUMARTIST")) {
                album_artist = taglib_apetag->itemListMap()["ALBUMARTIST"].toStringList().front();
            }
            
            // Rating
            if(taglib_apetag->itemListMap().contains(APE_TAG_RATING)) {
                long rat = 0;
                rat = atol(taglib_apetag->itemListMap()[APE_TAG_RATING].toStringList().front().toCString(true));
                if(rat) {
                    if(rat > 5) {
                        rating = popularity_to_rating(rat);
                    }
                    else {
                        rating = rat;
                    }
                }
            }
            if(taglib_apetag->itemListMap().contains(APE_TAG_PLAYCNT)) {
                playcount = 
                    atol(taglib_apetag->itemListMap()[APE_TAG_PLAYCNT].toStringList().front().toCString(false));
                if(playcount < 0)
                    playcount = 0;
            }
            // Labels
            if(track_labels.size() == 0) {
                if(taglib_apetag->itemListMap().contains("TRACK_LABELS")) {
                    track_labels_string = taglib_apetag->itemListMap()["TRACK_LABELS"].toStringList().front();
                    track_labels = split(track_labels_string, "|");
                }
            }
            if(artist_labels.size() == 0) {
                if(taglib_apetag->itemListMap().contains("ARTIST_LABELS")) {
                    artist_labels_string = taglib_apetag->itemListMap()["ARTIST_LABELS"].toStringList().front();
                    artist_labels = split(artist_labels_string, "|");
                }
            }
            if(album_labels.size() == 0) {
                if(taglib_apetag->itemListMap().contains("ALBUM_LABELS")) {
                    album_labels_string = taglib_apetag->itemListMap()["ALBUM_LABELS"].toStringList().front();
                    album_labels = split(album_labels_string, "|");
                }
            }
            if(taglib_apetag->itemListMap().contains(APE_TAG_COVER_ART_FRONT)) {
                has_image = true;
            }
            else if(taglib_apetag->itemListMap().contains(APE_TAG_COVER_ART_OTHER)) {
                has_image = true;
            }
            return true;
        }
    }
    return false;
}


bool ApeInfo::write(void) {
    if(taglib_apetag) {
        if(changedflag) {
            if(changedflag & CHANGED_COMPOSER_TAG)
                taglib_apetag->addValue(APE_TAG_COMPOSER, composer);
            if(changedflag & CHANGED_DATA_DISK_NUM)
                taglib_apetag->addValue(APE_TAG_DISKNO, format("%u", disk_number));
            
            if(changedflag & CHANGED_IS_COMPILATION_TAG) {
                if(is_compilation) {
                    taglib_apetag->addValue(APE_TAG_COMPILATION, "1");
                }
                else {
                    taglib_apetag->addValue(APE_TAG_COMPILATION, "0");
                }
            }
            if(changedflag & CHANGED_DATA_ALBUMARTIST)
                taglib_apetag->addValue(APE_TAG_ALBUMARTIST, album_artist);
            
            if(changedflag & CHANGED_DATA_RATING) {
                taglib_apetag->addValue(APE_TAG_RATING, format("%u", rating_to_popularity(rating)));
            }
            if(changedflag & CHANGED_DATA_PLAYCOUNT) {
                taglib_apetag->addValue("PLAY_COUNTER", format("%u", playcount));
            }
            if(changedflag & CHANGED_TRACK_LABELS)
                check_ape_label_frame(taglib_apetag, "TRACK_LABELS",  track_labels_string);
            if(changedflag & CHANGED_ARTIST_LABELS)
                check_ape_label_frame(taglib_apetag, "ARTIST_LABELS", artist_labels_string);
            if(changedflag & CHANGED_ALBUM_LABELS)
                check_ape_label_frame(taglib_apetag, "ALBUM_LABELS",  album_labels_string);
            write_virtual_tags((TagLib::Tag *)taglib_apetag);
        }
    }
    return Info::write();
}


bool ApeInfo::can_handle_lyrics(void) const {
    return true;
}


String ApeInfo::get_lyrics(void) const {
    if(taglib_apetag->itemListMap().contains(APE_TAG_LYRICS)) {
        return taglib_apetag->itemListMap()[APE_TAG_LYRICS].toStringList().front();
    }
    return "";
}


bool ApeInfo::set_lyrics(const String &lyrics) {
    if(taglib_apetag) {
        taglib_apetag->addValue(APE_TAG_LYRICS, lyrics);
        return true;
    }
    return false;
}

bool ApeInfo::can_handle_images(void) const {
    return true;
}

bool ApeInfo::get_image(char*& data, int &data_length, ImageType &image_type) const {
    if(taglib_apetag && !taglib_apetag->isEmpty()) {
        return get_ape_image(taglib_apetag, data, data_length, image_type);
    }
    return false;
}

bool ApeInfo::set_image(const char* data, int data_length, ImageType image_type) {
    return taglib_apetag && set_ape_image(taglib_apetag, data, data_length, image_type);
}