Source

libtaginfo / libtaginfo / aiffinfo.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>
 * 
 */





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


#include <asfattribute.h>
#include <popularimeterframe.h>

using namespace TagInfo;



AiffInfo::AiffInfo(const String &filename) : Info(filename) {
    taglib_tagId3v2 = NULL;
    if(!file_name.isEmpty() && !create_file_ref()) {
        printf("Error creating file ref! %s\n", filename.toCString(false));
    }
    if(taglib_file) {
        taglib_tagId3v2 = ((TagLib::RIFF::AIFF::File *) taglib_file)->tag();
        if(!taglib_tagId3v2 || taglib_tagId3v2->isEmpty()) { // Use fallback for id3v1 or extended header
            taglib_tag = taglib_file->tag();
            if(!taglib_tag) {
                printf("Cant get tag object from '%s'\n", file_name.toCString(false));
                valid = false;
            }
        }
    }
    else {
        printf("Cant get id3 tag from '%s'\n", file_name.toCString(false));
        taglib_tagId3v2 = NULL;
        valid = false;
    }
}


AiffInfo::~AiffInfo() {
}

bool AiffInfo::create_file_ref() {
    if(file_name.isEmpty())
        return false;
    taglib_file = 
        new TagLib::RIFF::AIFF::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 AiffInfo::read(void) {
    if(Info::read()) {
            // If its a ID3v2 Tag try to load the labels
        if(taglib_tagId3v2 && !taglib_tagId3v2->isEmpty()) {
            if(!taglib_tag)
                read_virtual_tags((TagLib::Tag *)taglib_tagId3v2);
            if(taglib_tagId3v2->frameListMap().contains("TPOS")) {
                disk_number = 
                    atol(taglib_tagId3v2->frameListMap()[ "TPOS" ].front()->toString().toCString(false));
                if(disk_number <= 0)
                    disk_number = 1;
            }
            if(taglib_tagId3v2->frameListMap().contains("TCOM")) {
                composer = taglib_tagId3v2->frameListMap()[ "TCOM" ].front()->toString();
            }
            if(taglib_tagId3v2->frameListMap().contains("TPE2")) {
                album_artist = taglib_tagId3v2->frameListMap()[ "TPE2" ].front()->toString();
            }
            if(taglib_tagId3v2->frameListMap().contains("TCMP")) {
                is_compilation = (taglib_tagId3v2->frameListMap()["TCMP"].front()->toString()) == String("1");
            }
            TagLib::ID3v2::PopularimeterFrame * popularity_frame = NULL;

            popularity_frame = get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
            if(!popularity_frame)
                popularity_frame = get_popularity_frame(taglib_tagId3v2, "");
            
            if(popularity_frame) {
                rating    = popularity_to_rating(popularity_frame->rating());
                playcount = popularity_frame->counter();
            }
            if(track_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "TRACK_LABELS");
                if(!frame)
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "TRACKLABELS");
                if(frame) {
                    StringList track_labels_list = frame->fieldList();
                    if(track_labels_list.size()) {
                        track_labels_string = track_labels_list[1];
                        track_labels = split(track_labels_string, "|");
                    }
                }
            }
            if(artist_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ARTIST_LABELS");
                if(!frame)
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ARTISTLABELS");
                if(frame) {
                    StringList artist_labels_list = frame->fieldList();
                    if(artist_labels_list.size()) {
                        artist_labels_string = artist_labels_list[1];//.toCString(true);
                        artist_labels = split(artist_labels_string, "|");
                    }
                }
            }
            if(album_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ALBUM_LABELS");
                if(!frame)
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ALBUMLABELS");
                if(frame) {
                    StringList album_labels_list = frame->fieldList();
                    if(album_labels_list.size()) {
                        album_labels_string = album_labels_list[1];//.toCString(true);
                        album_labels = split(album_labels_string, "|");
                    }
                }
            }
            // Image availability
            TagLib::ID3v2::FrameList frame_list = taglib_tagId3v2->frameListMap()["APIC"];
            has_image = (frame_list.size() > 0); //something is there
        }
    }
    else {
          cout  << "Error: Could not read tags from file '" << file_name.toCString(true) << "'" <<  endl;
        return false; 
    }
    return true;
}


bool AiffInfo::write(void) {
    if(taglib_tagId3v2) {
        if(changedflag) {
            TagLib::ID3v2::TextIdentificationFrame * frame;
            if(changedflag & CHANGED_DATA_DISK_NUM) {
                taglib_tagId3v2->removeFrames("TPOS");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TPOS");
                frame->setText(format("%u", disk_number));
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_COMPOSER_TAG) {
                taglib_tagId3v2->removeFrames("TCOM");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TCOM");
                frame->setText(composer);
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_DATA_ALBUMARTIST) {
                taglib_tagId3v2->removeFrames("TPE2");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TPE2");
                frame->setText(album_artist);
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_IS_COMPILATION_TAG) {
                taglib_tagId3v2->removeFrames("TCMP");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TCMP");
                if(is_compilation)
                    frame->setText("1");
                else
                    frame->setText("0");
                taglib_tagId3v2->addFrame(frame);
            }
            // I have found several TRCK fields in the mp3s
            if(changedflag & CHANGED_TRACKNO_TAG) {
                taglib_tagId3v2->removeFrames("TRCK");
                taglib_tagId3v2->setTrack(tracknumber);
            }
            TagLib::ID3v2::PopularimeterFrame * popularity_frame;
            if(changedflag & CHANGED_DATA_RATING) {
                popularity_frame = get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
                if(!popularity_frame) {
                    popularity_frame = new TagLib::ID3v2::PopularimeterFrame();
                    taglib_tagId3v2->addFrame(popularity_frame);
                    popularity_frame->setEmail("LibTagInfo");
                }
                if(popularity_frame)
                    popularity_frame->setRating(rating_to_popularity(rating));
            }
            if(changedflag & CHANGED_DATA_PLAYCOUNT) {
                if(!popularity_frame)
                    popularity_frame = get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
                if(!popularity_frame) {
                    popularity_frame = new TagLib::ID3v2::PopularimeterFrame();
                    taglib_tagId3v2->addFrame(popularity_frame);
                    popularity_frame->setEmail("LibTagInfo");
                }
                if(popularity_frame)
                    popularity_frame->setCounter(playcount);
            }
            
            // The Labels
            if(changedflag & CHANGED_TRACK_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "TRACK_LABELS", track_labels_string);
            if(changedflag & CHANGED_ARTIST_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "ARTIST_LABELS", artist_labels_string);
            if(changedflag & CHANGED_ALBUM_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "ALBUM_LABELS", album_labels_string);
            
            write_virtual_tags((TagLib::Tag *)taglib_tagId3v2);
        }
    }
    return Info::write();
//    if(taglib_tag) {
//        if(changedflag) {
//            write_virtual_tags((TagLib::Tag *)taglib_tag);
//        }
//    }
//    return Info::write();
}


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

bool AiffInfo::get_image(char*& data, int &data_length, ImageType &image_type) const {
    data = NULL;
    data_length = 0;
    image_type = IMAGE_TYPE_UNKNOWN;
    
    if(taglib_tagId3v2)
        return get_id3v2_image(taglib_tagId3v2, data, data_length, image_type);
    
    return false;
}

bool AiffInfo::set_image(const char* data, int data_length, ImageType image_type) {
    if(taglib_tagId3v2)
        set_id3v2_image(taglib_tagId3v2, data, data_length, image_type);
    return true;
}


bool AiffInfo::can_handle_lyrics(void) const {
    return false;
}


String AiffInfo::get_lyrics(void) const {
    return "";
}


bool AiffInfo::set_lyrics(const String &lyrics) {
    return false;
}