Explicitly pass MIME type to OpenEnc when adding cover artwork via "--picture" option.

This commit is contained in:
LoRd_MuldeR 2015-08-27 22:52:00 +02:00
parent 6bc9126295
commit 281c94026d
10 changed files with 118 additions and 57 deletions

View File

@ -439,6 +439,7 @@ copy /Y "$(SolutionDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\i
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
</CustomBuild>
<ClInclude Include="src\MimeTypes.h" />
<ClInclude Include="tmp\LameXP\UIC_AboutDialog.h" />
<ClInclude Include="tmp\LameXP\UIC_CueSheetImport.h" />
<ClInclude Include="tmp\LameXP\UIC_DropBox.h" />

View File

@ -552,6 +552,9 @@
<ClInclude Include="src\IPCCommands.h">
<Filter>Header Files\Misc</Filter>
</ClInclude>
<ClInclude Include="src\MimeTypes.h">
<Filter>Header Files\Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="gui\DropBox.ui">

View File

@ -439,6 +439,7 @@ copy /Y "$(SolutionDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\i
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
</CustomBuild>
<ClInclude Include="src\MimeTypes.h" />
<ClInclude Include="tmp\LameXP\UIC_AboutDialog.h" />
<ClInclude Include="tmp\LameXP\UIC_CueSheetImport.h" />
<ClInclude Include="tmp\LameXP\UIC_DropBox.h" />

View File

@ -552,6 +552,9 @@
<ClInclude Include="src\IPCCommands.h">
<Filter>Header Files\Misc</Filter>
</ClInclude>
<ClInclude Include="src\MimeTypes.h">
<Filter>Header Files\Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="gui\DropBox.ui">

View File

@ -35,7 +35,7 @@
#define VER_LAMEXP_MINOR_LO 2
#define VER_LAMEXP_TYPE Beta
#define VER_LAMEXP_PATCH 5
#define VER_LAMEXP_BUILD 1794
#define VER_LAMEXP_BUILD 1795
#define VER_LAMEXP_CONFG 1700
///////////////////////////////////////////////////////////////////////////////

View File

@ -22,9 +22,15 @@
#include "Encoder_Opus.h"
//MUtils
#include <MUtils/Global.h>
//Internal
#include "Global.h"
#include "Model_Settings.h"
#include "MimeTypes.h"
//Qt
#include <QProcess>
#include <QDir>
#include <QUUid>
@ -183,8 +189,7 @@ bool OpusEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInf
if(metaInfo.year()) args << "--date" << QString::number(metaInfo.year());
if(metaInfo.position()) args << "--comment" << QString("tracknumber=%1").arg(QString::number(metaInfo.position()));
if(!metaInfo.comment().isEmpty()) args << "--comment" << QString("comment=%1").arg(cleanTag(metaInfo.comment()));
if(!metaInfo.cover().isEmpty()) args << "--picture" << QDir::toNativeSeparators(metaInfo.cover());
if(!metaInfo.cover().isEmpty()) args << "--picture" << makeCoverParam(metaInfo.cover());
if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
@ -259,6 +264,29 @@ bool OpusEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInf
return true;
}
QString OpusEncoder::detectMimeType(const QString &coverFile)
{
const QString suffix = QFileInfo(coverFile).suffix();
for (size_t i = 0; MIME_TYPES[i].type; i++)
{
for (size_t k = 0; MIME_TYPES[i].ext[k]; k++)
{
if (suffix.compare(QString::fromLatin1(MIME_TYPES[i].ext[k]), Qt::CaseInsensitive) == 0)
{
return QString::fromLatin1(MIME_TYPES[i].type);
}
}
}
qWarning("Unknown MIME type for extension '%s' -> using default!", MUTILS_UTF8(coverFile));
return QString::fromLatin1(MIME_TYPES[0].type);
}
QString OpusEncoder::makeCoverParam(const QString &coverFile)
{
return QString("3|%1|||%2").arg(detectMimeType(coverFile), QDir::toNativeSeparators(coverFile));
}
void OpusEncoder::setOptimizeFor(int optimizeFor)
{
m_configOptimizeFor = qBound(0, optimizeFor, 2);

View File

@ -55,4 +55,7 @@ private:
int m_configOptimizeFor;
int m_configEncodeComplexity;
int m_configFrameSize;
static inline QString detectMimeType(const QString &coverFile);
static inline QString makeCoverParam(const QString &coverFile);
};

39
src/MimeTypes.h Normal file
View File

@ -0,0 +1,39 @@
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version, but always including the *additional*
// restrictions defined in the "License.txt" file.
//
// 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; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
static const struct
{
const char *type;
const char *ext[8];
}
MIME_TYPES[] =
{
{ "image/jpeg", { "jpg", "jpeg", "jpe", NULL } },
{ "image/png", { "png", NULL } },
{ "image/gif", { "gif", NULL } },
{ "image/tiff", { "tif", "tiff", NULL } },
{ NULL, { NULL } }
};
static const size_t MIME_TYPES_MAX = (sizeof(MIME_TYPES) / sizeof(MIME_TYPES[0])) - 2;

View File

@ -26,6 +26,7 @@
#include "Global.h"
#include "LockedFile.h"
#include "Model_AudioFile.h"
#include "MimeTypes.h"
//MUtils
#include <MUtils/Global.h>
@ -178,8 +179,8 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
readTest.close();
bool skipNext = false;
unsigned int id_val[2] = {UINT_MAX, UINT_MAX};
cover_t coverType = coverNone;
QPair<quint32, quint32> id_val(UINT_MAX, UINT_MAX);
quint32 coverType = UINT_MAX;
QByteArray coverData;
QStringList params;
@ -236,7 +237,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
QString val = line.mid(index+1).trimmed();
if(!key.isEmpty())
{
updateInfo(audioFile, &skipNext, id_val, &coverType, &coverData, key, val);
updateInfo(audioFile, skipNext, id_val, coverType, coverData, key, val);
}
}
}
@ -271,7 +272,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
process.waitForFinished(-1);
}
if((coverType != coverNone) && (!coverData.isEmpty()))
if((coverType != UINT_MAX) && (!coverData.isEmpty()))
{
retrieveCover(audioFile, coverType, coverData);
}
@ -284,7 +285,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
return audioFile;
}
void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value)
void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool &skipNext, QPair<quint32, quint32> &id_val, quint32 &coverType, QByteArray &coverData, const QString &key, const QString &value)
{
//qWarning("'%s' -> '%s'", MUTILS_UTF8(key), MUTILS_UTF8(value));
@ -293,7 +294,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
{
if(value.isEmpty())
{
*skipNext = false;
skipNext = false;
}
else
{
@ -302,15 +303,15 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
unsigned int id = value.toUInt(&ok);
if(ok)
{
if(IS_KEY("Gen_ID")) { id_val[0] = qMin(id_val[0], id); *skipNext = (id > id_val[0]); }
if(IS_KEY("Aud_ID")) { id_val[1] = qMin(id_val[1], id); *skipNext = (id > id_val[1]); }
if(IS_KEY("Gen_ID")) { id_val.first = qMin(id_val.first, id); skipNext = (id > id_val.first); }
if(IS_KEY("Aud_ID")) { id_val.second = qMin(id_val.second, id); skipNext = (id > id_val.second); }
}
else
{
*skipNext = true;
skipNext = true;
}
}
if(*skipNext)
if(skipNext)
{
qWarning("Skipping info for non-primary stream!");
}
@ -318,7 +319,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
}
/*Skip or empty?*/
if((*skipNext) || value.isEmpty())
if((skipNext) || value.isEmpty())
{
return;
}
@ -326,7 +327,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
/*Playlist file?*/
if(IS_KEY("Aud_Source"))
{
*skipNext = true;
skipNext = true;
audioFile.techInfo().setContainerType(QString());
audioFile.techInfo().setAudioType(QString());
qWarning("Skipping info for playlist file!");
@ -382,22 +383,27 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
}
else if(IS_KEY("Gen_Cover") || IS_KEY("Gen_Cover_Type"))
{
if(*coverType == coverNone)
if(coverType == UINT_MAX)
{
*coverType = coverJpeg;
coverType = 0;
}
}
else if(IS_KEY("Gen_Cover_Mime"))
{
QString temp = FIRST_TOK(value);
if(!temp.compare("image/jpeg", Qt::CaseInsensitive)) *coverType = coverJpeg;
else if(!temp.compare("image/png", Qt::CaseInsensitive)) *coverType = coverPng;
else if(!temp.compare("image/gif", Qt::CaseInsensitive)) *coverType = coverGif;
for (quint32 i = 0; MIME_TYPES[i].type; i++)
{
if (temp.compare(QString::fromLatin1(MIME_TYPES[i].type), Qt::CaseInsensitive) == 0)
{
coverType = i;
break;
}
}
}
else if(IS_KEY("Gen_Cover_Data"))
{
if(!coverData->isEmpty()) coverData->clear();
coverData->append(QByteArray::fromBase64(FIRST_TOK(value).toLatin1()));
if(!coverData.isEmpty()) coverData.clear();
coverData.append(QByteArray::fromBase64(FIRST_TOK(value).toLatin1()));
}
else
{
@ -483,27 +489,14 @@ bool AnalyzeTask::checkFile_CDDA(QFile &file)
return ((i >= 0) && (j >= 0) && (k >= 0) && (k > j) && (j > i));
}
void AnalyzeTask::retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData)
void AnalyzeTask::retrieveCover(AudioFileModel &audioFile, const quint32 coverType, const QByteArray &coverData)
{
qDebug("Retrieving cover!");
QString extension;
qDebug("Retrieving cover! (MIME_TYPES_MAX=%u)", MIME_TYPES_MAX);
switch(coverType)
static const QString ext = QString::fromLatin1(MIME_TYPES[qBound(0U, coverType, MIME_TYPES_MAX)].ext[0]);
if(!(QImage::fromData(coverData, ext.toUpper().toLatin1().constData()).isNull()))
{
case coverPng:
extension = QString::fromLatin1("png");
break;
case coverGif:
extension = QString::fromLatin1("gif");
break;
default:
extension = QString::fromLatin1("jpg");
break;
}
if(!(QImage::fromData(coverData, extension.toUpper().toLatin1().constData()).isNull()))
{
QFile coverFile(QString("%1/%2.%3").arg(MUtils::temp_folder(), MUtils::rand_str(), extension));
QFile coverFile(QString("%1/%2.%3").arg(MUtils::temp_folder(), MUtils::rand_str(), ext));
if(coverFile.open(QIODevice::WriteOnly))
{
coverFile.write(coverData);

View File

@ -28,6 +28,7 @@
#include <QStringList>
#include <QMutex>
#include <QSemaphore>
#include <QPair>
class AudioFileModel;
class QFile;
@ -56,9 +57,6 @@ public:
fileTypeUnknown = 4
};
//Wait until there is a free slot in the queue
static bool waitForFreeSlot(volatile bool *abortFlag);
signals:
void fileAnalyzed(const unsigned int taskId, const int fileType, const AudioFileModel &file);
void taskCompleted(const unsigned int taskId);
@ -68,20 +66,12 @@ protected:
void run_ex(void);
private:
enum cover_t
{
coverNone,
coverJpeg,
coverPng,
coverGif
};
const AudioFileModel analyzeFile(const QString &filePath, int *type);
void updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value);
void updateInfo(AudioFileModel &audioFile, bool &skipNext, QPair<quint32, quint32> &id_val, quint32 &coverType, QByteArray &coverData, const QString &key, const QString &value);
unsigned int parseYear(const QString &str);
unsigned int parseDuration(const QString &str);
bool checkFile_CDDA(QFile &file);
void retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData);
void retrieveCover(AudioFileModel &audioFile, const quint32 coverType, const QByteArray &coverData);
bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info);
const unsigned int m_taskId;