Source

libtaginfo / libtaginfo / flacinfo.cc

/*
 * Copyright (C) 2008-2013 J.Rios <anonbeat@gmail.com>
 * 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>
 * 	Matias De lellis <mati86dl@gmail.com>
 * 	Pavel Vasin <rat4vier@gmail.com>
 */



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


#include <flacfile.h>
#include <flacpicture.h>


using namespace TagInfo;



FlacInfo::FlacInfo(const String &filename) : XiphInfo(filename) {
    if(file_name.isEmpty()) {
        valid = false;
        flac_file = NULL;
        printf("File name empty!\n");
    }
    else {
        taglib_file = new TagLib::FLAC::File(file_name.toCString(false), true, TagLib::AudioProperties::Fast);
        if(taglib_file) {
            flac_file = ((TagLib::FLAC::File *) taglib_file);
        }
        else {
            printf("TagLib::File creation failed for '%s'\n", file_name.toCString(false));
            printf("Cant get xiphcomment from '%s'\n", file_name.toCString(false));
        }
    }
    if(flac_file) {
        xiphcomment = flac_file->xiphComment(); 
        if(!xiphcomment || xiphcomment->isEmpty()) {
            taglib_tag = flac_file->tag();
            if(!taglib_tag) {
                printf("Cant get tag object from '%s'\n", file_name.toCString(false));
                valid = false;
            }
        }
    }
    else {
        xiphcomment = NULL;
        valid = false;
    }
}


FlacInfo::~FlacInfo() {
    //std::cout << "FlacInfo dtor" << std::endl;
}



bool FlacInfo::load(void) {
    if(XiphInfo::load()) {
        if(flac_file) {
            List<FLAC::Picture *> plist = flac_file->pictureList();
            if(plist.size() > 0)
                has_image = true;
        }
        return true;
    }
    return false;
}

ImageType flac_image_type_to_image_type(const FLAC::Picture::Type &tpe) {
    switch(tpe) {
        case FLAC::Picture::FrontCover:
            return IMAGE_TYPE_COVER_FRONT;
        case FLAC::Picture::BackCover:
            return IMAGE_TYPE_COVER_BACK;
        case FLAC::Picture::Other:
            return IMAGE_TYPE_OTHER;
        case FLAC::Picture::FileIcon:
            return IMAGE_TYPE_FILE_ICON;
        case FLAC::Picture::OtherFileIcon:
            return IMAGE_TYPE_OTHER_FILE_ICON;
        case FLAC::Picture::LeafletPage:
            return IMAGE_TYPE_LEAFLET_PAGE;
        case FLAC::Picture::Media:
            return IMAGE_TYPE_MEDIA;
        case FLAC::Picture::LeadArtist:
            return IMAGE_TYPE_LEAD_ARTIST;
        case FLAC::Picture::Artist:
            return IMAGE_TYPE_ARTIST;
        case FLAC::Picture::Conductor:
            return IMAGE_TYPE_CONDUCTOR;
        case FLAC::Picture::Band:
            return IMAGE_TYPE_BAND;
        case FLAC::Picture::Composer:
            return IMAGE_TYPE_COMPOSER;
        case FLAC::Picture::Lyricist:
            return IMAGE_TYPE_LYRICIST;
        case FLAC::Picture::RecordingLocation:
            return IMAGE_TYPE_RECORDING_LOCATION;
        case FLAC::Picture::DuringRecording:
            return IMAGE_TYPE_DURING_RECORDING;
        case FLAC::Picture::DuringPerformance:
            return IMAGE_TYPE_DURING_PERFORMANCE;
        case FLAC::Picture::MovieScreenCapture:
            return IMAGE_TYPE_MOVIESCREENCAPTURE;
        case FLAC::Picture::ColouredFish:
            return IMAGE_TYPE_COLOURED_FISH;
        case FLAC::Picture::Illustration:
            return IMAGE_TYPE_ILLUSTRATION;
        case FLAC::Picture::BandLogo:
            return IMAGE_TYPE_ARTIST_LOGO;
        case FLAC::Picture::PublisherLogo:
            return IMAGE_TYPE_PUBLISHER_LOGO;
        default:
            return IMAGE_TYPE_OTHER;
    }
}

Image ** FlacInfo::get_images(int &image_count) const {
    if(flac_file) {
        List<FLAC::Picture *> plist = flac_file->pictureList();
        if(plist.size() > 0) {
            Image** images = new Image*[plist.size()];
            for(List<FLAC::Picture *>::Iterator it = plist.begin(); it != plist.end(); ++it) {
                Image * image = new Image();
                FLAC::Picture * p = (*it);
                image->image_type = flac_image_type_to_image_type(p->type());
                image->description = ::strdup(p->description().toCString(false));
                image->data_length = p->data().size();
                image->data = new char[image->data_length];
                memcpy(image->data, p->data().data(), image->data_length);
                if(image->data) {
                    images[image_count] = image;
                    image_count++;
                }
                else {
                    delete image;
                }
            }
            return images;
        }
    }
    return NULL;
}


void FlacInfo::set_images(const Image ** images, const int image_count) {
    if(flac_file) {
        flac_file->removePictures();
        
        for(int p = 0; p < image_count; p++) {
            if(!images[p]->data || images[p]->data_length == 0)
                continue;
            ByteVector vect((TagLib::uint) images[p]->data_length);
            memcpy(vect.data(), images[p]->data, images[p]->data_length);
            FLAC::Picture * picture = new FLAC::Picture();
            if(!picture) {
                std::cout << "could not create picture" << std::endl;
                continue;
            }
            picture->setData(vect);
            if(images[p]->description) {
                String desc(images[p]->description);
                picture->setDescription(desc);
            }
            picture->setMimeType("image/jpeg"); //TODO
            picture->setType((TagLib::FLAC::Picture::Type) images[p]->image_type);
            //std::cout << "pic size:" << picture->data().size() << std::endl;
            flac_file->addPicture(picture);
        }
    }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.