OSDN Git Service

Fixed detection of AAC streams with latest MediaInfo version. AAC profile is now...
[lamexp/LameXP.git] / src / Global_Tools.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2018 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Global.h"
24
25 //LameXP includes
26 #include "LockedFile.h"
27
28 //Qt includes
29 #include <QApplication>
30 #include <QHash>
31 #include <QReadWriteLock>
32 #include <QString>
33 #include <QStringList>
34 #include <QFileInfo>
35 #include <QPair>
36 #include <QResource>
37 #include <QDir>
38
39 //MUtils
40 #include <MUtils/Global.h>
41 #include <MUtils/Exception.h>
42
43 //CRT
44 #include <stdint.h>
45
46 ///////////////////////////////////////////////////////////////////////////////
47 // GLOBAL VARS
48 ///////////////////////////////////////////////////////////////////////////////
49
50 //Typedef
51 typedef QPair<quint32,QString>          tool_info_t;
52 typedef QPair<LockedFile*, tool_info_t> tool_data_t;
53 typedef QHash<QString, tool_data_t>     tool_hash_t;
54
55 //Tool registry
56 static QScopedPointer<tool_hash_t> g_lamexp_tools_data;
57 static QReadWriteLock              g_lamexp_tools_lock;
58
59 //Null String
60 static const QString g_null_string;
61
62 //UINT_MAX
63 static const quint32 g_max_uint32 = UINT32_MAX;
64
65
66 //Resource file lock
67 static QScopedPointer<LockedFile> g_lamexp_rcc_lock;
68
69 //Helper Macro
70 #define MAKE_ENTRY(LOCK_FILE,VER,TAG) \
71         qMakePair((LOCK_FILE),qMakePair((VER),(TAG)))
72
73 ///////////////////////////////////////////////////////////////////////////////
74 // GLOBAL FUNCTIONS
75 ///////////////////////////////////////////////////////////////////////////////
76
77 /*
78  * Clean-up *all* registered tools
79  */
80 static void lamexp_tools_clean_up(void)
81 {
82         QWriteLocker writeLock(&g_lamexp_tools_lock);
83
84         if(!g_lamexp_tools_data.isNull())
85         {
86                 const QStringList keys = g_lamexp_tools_data->keys();
87                 for(QStringList::ConstIterator iter = keys.constBegin(); iter != keys.constEnd(); iter++)
88                 {
89                         tool_data_t currentTool = (*g_lamexp_tools_data)[*iter];
90                         MUTILS_DELETE(currentTool.first);
91                 }
92                 g_lamexp_tools_data->clear();
93         }
94 }
95
96 /*
97  * Register tool
98  */
99 void lamexp_tools_register(const QString &toolName, LockedFile *const file, const quint32 &version, const QString &tag)
100 {
101         QWriteLocker writeLock(&g_lamexp_tools_lock);
102         
103         if(!file)
104         {
105                 MUTILS_THROW("lamexp_register_tool: Tool file must not be NULL!");
106         }
107
108         if(g_lamexp_tools_data.isNull())
109         {
110                 g_lamexp_tools_data.reset(new tool_hash_t());
111                 atexit(lamexp_tools_clean_up);
112         }
113
114         const QString key = toolName.simplified().toLower();
115         if(g_lamexp_tools_data->contains(key))
116         {
117                 MUTILS_THROW("lamexp_register_tool: Tool is already registered!");
118         }
119
120         g_lamexp_tools_data->insert(key, MAKE_ENTRY(file, version, tag));
121 }
122
123 /*
124  * Check for tool
125  */
126 bool lamexp_tools_check(const QString &toolName)
127 {
128         QReadLocker readLock(&g_lamexp_tools_lock);
129
130         if(!g_lamexp_tools_data.isNull())
131         {
132                 const QString key = toolName.simplified().toLower();
133                 return g_lamexp_tools_data->contains(key);
134         }
135
136         return false;
137 }
138
139 /*
140  * Lookup tool path
141  */
142 const QString lamexp_tools_lookup(const QString &toolName)
143 {
144         QReadLocker readLock(&g_lamexp_tools_lock);
145
146         if(!g_lamexp_tools_data.isNull())
147         {
148                 const QString key = toolName.simplified().toLower();
149                 if(g_lamexp_tools_data->contains(key))
150                 {
151                         return (*g_lamexp_tools_data)[key].first->filePath();
152                 }
153         }
154
155         return g_null_string;
156 }
157
158 /*
159  * Lookup tool version
160  */
161 const quint32 &lamexp_tools_version(const QString &toolName, QString *const tagOut)
162 {
163         QReadLocker readLock(&g_lamexp_tools_lock);
164
165         if(!g_lamexp_tools_data.isNull())
166         {
167                 const QString key = toolName.simplified().toLower();
168                 if(g_lamexp_tools_data->contains(key))
169                 {
170                         const tool_info_t &info = (*g_lamexp_tools_data)[key].second;
171                         if(tagOut)
172                         {
173                                 *tagOut = info.second;
174                         }
175                         return info.first;
176                 }
177         }
178
179         if(tagOut)
180         {
181                 tagOut->clear();
182         }
183         return g_max_uint32;
184 }
185
186 /*
187 * Initialize external resources (RCC file)
188 */
189 void lamexp_initialize_resources(void)
190 {
191         //Load the external RCC file
192 #ifndef QT_NODLL
193         if (g_lamexp_rcc_lock.isNull())
194         {
195                 const QFileInfo appPath(QCoreApplication::applicationFilePath());
196                 const QString rccPath = QString("%1/%2.rcc").arg(appPath.canonicalPath(), appPath.completeBaseName());
197                 try
198                 {
199                         qDebug("Using resource file:\n%s\n", MUTILS_UTF8(rccPath));
200                         g_lamexp_rcc_lock.reset(new LockedFile(rccPath));
201                         QResource::registerResource(g_lamexp_rcc_lock->filePath());
202                 }
203                 catch (std::runtime_error&)
204                 {
205                         qFatal("Failed to load the resource file:\n%s\n", MUTILS_UTF8(QDir::toNativeSeparators(rccPath)));
206                 }
207         }
208 #endif //!QT_NODLL
209
210         //Make sure resources are accessible!
211         static const char *const RESOURCES[] = { ":/images/Logo.png", ":/tools/lame.x86-i686.exe", NULL };
212         for (size_t i = 0U; RESOURCES[i]; ++i)
213         {
214                 QResource resourceCheck(QString::fromLatin1(RESOURCES[i]));
215                 if ((!resourceCheck.isValid()) || (resourceCheck.size() <= 0))
216                 {
217                         qFatal("Qt resource system initialization has failed:\nResource \"%s\" not found!", RESOURCES[i]);
218                 }
219         }
220 }