File indexing completed on 2024-04-14 04:40:48

0001 /****************************************************************************************
0002  * Copyright (c) 2005 Martin Aumueller <aumueller@reserv.at>                            *
0003  * Copyright (c) 2011 Ralf Engels <ralf-engels@gmx.de>                                  *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #include "FileTypeResolver.h"
0019 
0020 #include <config.h>
0021 
0022 
0023 
0024 #include <QFile>
0025 #include <QFileInfo>
0026 #include <QtDebug>
0027 
0028 #pragma GCC diagnostic push
0029 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
0030 #ifdef TAGLIB_EXTRAS_FOUND
0031 #include <audiblefile.h>
0032 #include <realmediafile.h>
0033 #endif // TAGLIB_EXTRAS_FOUND
0034 #include <aifffile.h>
0035 #include <asffile.h>
0036 #include <flacfile.h>
0037 #include <mp4file.h>
0038 #include <mpcfile.h>
0039 #include <mpegfile.h>
0040 #include <oggfile.h>
0041 #ifdef TAGLIB_OPUS_FOUND
0042 #include <opusfile.h>
0043 #endif // TAGLIB_OPUS_FOUND
0044 #include <oggflacfile.h>
0045 #include <speexfile.h>
0046 #include <trueaudiofile.h>
0047 #include <vorbisfile.h>
0048 #include <wavfile.h>
0049 #include <wavpackfile.h>
0050 #ifdef TAGLIB_MOD_FOUND
0051 #include <modfile.h>
0052 #include <s3mfile.h>
0053 #include <itfile.h>
0054 #include <xmfile.h>
0055 #include <QMimeDatabase>
0056 #include <QMimeType>
0057 #endif // TAGLIB_MOD_FOUND
0058 #pragma GCC diagnostic pop
0059 
0060 TagLib::File *Meta::Tag::FileTypeResolver::createFile(TagLib::FileName fileName,
0061         bool readProperties,
0062         TagLib::AudioProperties::ReadStyle propertiesStyle) const
0063 {
0064     TagLib::File* result = nullptr;
0065 
0066     QMimeDatabase db;
0067 
0068     QString fn = QFile::decodeName( fileName );
0069     QString suffix = QFileInfo( fn ).suffix();
0070     QMimeType mimetype = db.mimeTypeForFile( fn );
0071 
0072     // -- check by mime type
0073     if( mimetype.inherits( QStringLiteral("audio/mpeg") )
0074             || mimetype.inherits( QStringLiteral("audio/x-mpegurl") )
0075             || mimetype.inherits( QStringLiteral("audio/mpeg") ))
0076     {
0077         result = new TagLib::MPEG::File(fileName, readProperties, propertiesStyle);
0078     }
0079     else if( mimetype.inherits( QStringLiteral("audio/mp4") )
0080              || mimetype.inherits( QStringLiteral("video/mp4") ) )
0081     {
0082         result = new TagLib::MP4::File(fileName, readProperties, propertiesStyle);
0083     }
0084     else if( mimetype.inherits( QStringLiteral("audio/x-ms-wma") )
0085             || mimetype.inherits( QStringLiteral("video/x-ms-asf") )
0086             || mimetype.inherits( QStringLiteral("video/x-msvideo") )
0087             || mimetype.inherits( QStringLiteral("video/x-ms-wmv") ) )
0088     {
0089         result = new TagLib::ASF::File(fileName, readProperties, propertiesStyle);
0090     }
0091 #ifdef TAGLIB_EXTRAS_FOUND
0092     else if( mimetype.inherits( QLatin1String("audio/vnd.rn-realaudio") )
0093             || mimetype.inherits( QLatin1String("audio/x-pn-realaudioplugin") )
0094             || mimetype.inherits( QLatin1String("audio/vnd.rn-realvideo") ) )
0095     {
0096         result = new TagLibExtras::RealMedia::File(fileName, readProperties, propertiesStyle);
0097     }
0098 #endif
0099 #ifdef TAGLIB_OPUS_FOUND
0100     else if( mimetype.inherits( QStringLiteral("audio/opus") )
0101             || mimetype.inherits( QStringLiteral("audio/x-opus+ogg") ) )
0102     {
0103         result = new TagLib::Ogg::Opus::File(fileName, readProperties, propertiesStyle);
0104     }
0105 #endif
0106     else if( mimetype.inherits( QStringLiteral("audio/vorbis") )
0107             || mimetype.inherits( QStringLiteral("audio/x-vorbis+ogg") ) )
0108     {
0109         result = new TagLib::Ogg::Vorbis::File(fileName, readProperties, propertiesStyle);
0110     }
0111     else if( mimetype.inherits( QStringLiteral("audio/x-flac+ogg") ) )
0112     {
0113         result = new TagLib::Ogg::FLAC::File(fileName, readProperties, propertiesStyle);
0114     }
0115     else if( mimetype.inherits( QStringLiteral("audio/x-aiff") ) )
0116     {
0117         result = new TagLib::RIFF::AIFF::File(fileName, readProperties, propertiesStyle);
0118     }
0119     else if( mimetype.inherits( QStringLiteral("audio/x-flac") ) )
0120     {
0121         result = new TagLib::FLAC::File(fileName, readProperties, propertiesStyle);
0122     }
0123     else if( mimetype.inherits( QStringLiteral("audio/x-musepack") ) )
0124     {
0125         result = new TagLib::MPC::File(fileName, readProperties, propertiesStyle);
0126     }
0127     else if( mimetype.inherits( QStringLiteral("audio/x-wav") ) )
0128     {
0129         result = new TagLib::RIFF::WAV::File(fileName, readProperties, propertiesStyle);
0130     }
0131     else if( mimetype.inherits( QStringLiteral("audio/x-wavpack") ) )
0132     {
0133         result = new TagLib::WavPack::File(fileName, readProperties, propertiesStyle);
0134     }
0135     else if( mimetype.inherits( QStringLiteral("audio/x-tta") ) )
0136     {
0137         result = new TagLib::TrueAudio::File(fileName, readProperties, propertiesStyle);
0138     }
0139     else if( mimetype.inherits( QStringLiteral("audio/x-speex") )
0140              || mimetype.inherits( QStringLiteral("audio/x-speex+ogg") ) )
0141     {
0142         result = new TagLib::Ogg::Speex::File(fileName, readProperties, propertiesStyle);
0143     }
0144 #ifdef TAGLIB_MOD_FOUND
0145     else if( mimetype.inherits( QStringLiteral("audio/x-mod") ) )
0146     {
0147         result = new TagLib::Mod::File(fileName, readProperties, propertiesStyle);
0148     }
0149     else if( mimetype.inherits( QStringLiteral("audio/x-s3m") ) )
0150     {
0151         result = new TagLib::S3M::File(fileName, readProperties, propertiesStyle);
0152     }
0153     else if( mimetype.inherits( QStringLiteral("audio/x-it") ) )
0154     {
0155         result = new TagLib::IT::File(fileName, readProperties, propertiesStyle);
0156     }
0157     else if( mimetype.inherits( QStringLiteral("audio/x-xm") ) )
0158     {
0159         result = new TagLib::XM::File(fileName, readProperties, propertiesStyle);
0160     }
0161 #endif
0162 
0163     // -- check by extension
0164     else if( suffix == QLatin1String("m4a")
0165         || suffix == QLatin1String("m4b")
0166         || suffix == QLatin1String("m4p")
0167         || suffix == QLatin1String("mp4")
0168         || suffix == QLatin1String("m4v")
0169         || suffix == QLatin1String("mp4v") )
0170     {
0171         result = new TagLib::MP4::File(fileName, readProperties, propertiesStyle);
0172     }
0173     else if( suffix == QLatin1String("wav") )
0174     {
0175         result = new TagLib::RIFF::WAV::File(fileName, readProperties, propertiesStyle);
0176     }
0177     else if( suffix == QLatin1String("wma")
0178              || suffix == QLatin1String("asf") )
0179     {
0180         result = new TagLib::ASF::File(fileName, readProperties, propertiesStyle);
0181     }
0182 #ifdef TAGLIB_OPUS_FOUND
0183     // this is currently needed because shared-mime-info database doesn't have opus entry (2013-01)
0184     else if( suffix == QLatin1String("opus") )
0185     {
0186         result = new TagLib::Ogg::Opus::File(fileName, readProperties, propertiesStyle);
0187     }
0188 #endif
0189 
0190 #ifndef Q_WS_WIN
0191      if( !result )
0192          qDebug() << QStringLiteral( "FileTypeResolver: file %1 (mimetype %2) not recognized as "
0193                 "Amarok-compatible" ).arg( QString::fromLatin1(fileName), mimetype.name() );
0194 #endif
0195 
0196     if( result && !result->isValid() ) {
0197         delete result;
0198         result = nullptr;
0199     }
0200 
0201     return result;
0202 }