@@ -8,47 +8,50 @@ namespace audio_tools {
8
8
9
9
/* *
10
10
* @brief Abstract interface for classes that can provide MIME type information.
11
- *
12
- * This class defines a simple interface for objects that can determine and provide
13
- * MIME type strings. It serves as a base class for various MIME detection and
14
- * source identification implementations within the audio tools framework.
15
- *
11
+ *
12
+ * This class defines a simple interface for objects that can determine and
13
+ * provide MIME type strings. It serves as a base class for various MIME
14
+ * detection and source identification implementations within the audio tools
15
+ * framework.
16
+ *
16
17
* Classes implementing this interface should provide logic to determine the
17
18
* appropriate MIME type based on their specific context (e.g., file content,
18
19
* stream headers, file extensions, etc.).
19
- *
20
- * @note This is a pure virtual interface class and cannot be instantiated directly.
20
+ *
21
+ * @note This is a pure virtual interface class and cannot be instantiated
22
+ * directly.
21
23
* @ingroup codecs
22
- * @ingroup decoder
24
+ * @ingroup decoder
23
25
* @author Phil Schatzmann
24
26
* @copyright GPLv3
25
27
*/
26
28
class MimeSource {
27
- public:
29
+ public:
28
30
/* *
29
31
* @brief Get the MIME type string.
30
- *
32
+ *
31
33
* Pure virtual method that must be implemented by derived classes to return
32
34
* the appropriate MIME type string for the current context.
33
- *
34
- * @return const char* Pointer to a null-terminated string containing the MIME type.
35
- * The string should follow standard MIME type format (e.g., "audio/mpeg").
36
- * Returns nullptr if MIME type cannot be determined.
37
- *
38
- * @note The returned pointer should remain valid for the lifetime of the object
39
- * or until the next call to this method.
35
+ *
36
+ * @return const char* Pointer to a null-terminated string containing the MIME
37
+ * type. The string should follow standard MIME type format (e.g.,
38
+ * "audio/mpeg"). Returns nullptr if MIME type cannot be determined.
39
+ *
40
+ * @note The returned pointer should remain valid for the lifetime of the
41
+ * object or until the next call to this method.
40
42
*/
41
43
virtual const char * mime () = 0;
42
44
};
43
45
44
46
/* *
45
47
* @brief Logic to detemine the mime type from the content.
46
48
* By default the following mime types are supported (audio/aac, audio/mpeg,
47
- * audio/vnd.wave, audio/ogg, audio/flac). You can register your own custom detection logic
48
- * to cover additional file types.
49
+ * audio/vnd.wave, audio/ogg, audio/flac). You can register your own custom
50
+ * detection logic to cover additional file types.
49
51
*
50
52
* Please note that the distinction between mp3 and aac is difficult and might
51
- * fail in some cases. FLAC detection supports both native FLAC and OGG FLAC formats.
53
+ * fail in some cases. FLAC detection supports both native FLAC and OGG FLAC
54
+ * formats.
52
55
* @ingroup codecs
53
56
* @ingroup decoder
54
57
* @author Phil Schatzmann
@@ -57,25 +60,35 @@ class MimeSource {
57
60
58
61
class MimeDetector : public MimeSource {
59
62
public:
60
- MimeDetector () {
61
- setCheck (" audio/vnd.wave" , checkWAV);
62
- setCheck (" audio/flac" , checkFLAC);
63
- setCheck (" audio/ogg; codecs=flac" , checkOggFLAC);
64
- setCheck (" audio/ogg; codecs=opus" , checkOggOpus);
65
- setCheck (" audio/ogg; codec=vorbis" , checkOggVorbis);
66
- setCheck (" audio/ogg" , checkOGG);
67
- setCheck (" video/MP2T" , checkMP2T);
68
- setCheck (" audio/prs.sid" , checkSID);
69
- setCheck (" audio/m4a" , checkM4A);
70
- setCheck (" audio/mpeg" , checkMP3Ext);
71
- setCheck (" audio/aac" , checkAACExt);
63
+ MimeDetector (bool setupDefault = true ) {
64
+ if (setupDefault) {
65
+ setCheck (" audio/vnd.wave" , checkWAV);
66
+ setCheck (" audio/flac" , checkFLAC);
67
+ setCheck (" audio/ogg; codecs=flac" , checkOggFLAC);
68
+ setCheck (" audio/ogg; codecs=opus" , checkOggOpus);
69
+ setCheck (" audio/ogg; codec=vorbis" , checkOggVorbis);
70
+ setCheck (" audio/ogg" , checkOGG);
71
+ setCheck (" video/MP2T" , checkMP2T);
72
+ setCheck (" audio/prs.sid" , checkSID);
73
+ setCheck (" audio/m4a" , checkM4A);
74
+ setCheck (" audio/mpeg" , checkMP3Ext);
75
+ setCheck (" audio/aac" , checkAACExt);
76
+ }
72
77
}
73
78
79
+ // / Sets is_first to true
74
80
bool begin () {
75
81
is_first = true ;
76
82
return true ;
77
83
}
78
84
85
+ // / Clears the actual mime and resets the state
86
+ void end (){
87
+ actual_mime = nullptr ;
88
+ is_first = true ;
89
+ }
90
+
91
+
79
92
// / write the header to determine the mime
80
93
size_t write (uint8_t * data, size_t len) {
81
94
actual_mime = default_mime;
@@ -151,7 +164,7 @@ class MimeDetector : public MimeSource {
151
164
152
165
static bool checkFLAC (uint8_t * start, size_t len) {
153
166
if (len < 4 ) return false ;
154
-
167
+
155
168
// Native FLAC streams start with "fLaC" (0x664C6143)
156
169
if (memcmp (start, " fLaC" , 4 ) == 0 ) {
157
170
return true ;
@@ -170,12 +183,13 @@ class MimeDetector : public MimeSource {
170
183
return true ;
171
184
}
172
185
// Also check for the more specific OGG FLAC header
173
- if (i < len - 5 && start[i] == 0x7F && memcmp (start + i + 1 , " FLAC" , 4 ) == 0 ) {
186
+ if (i < len - 5 && start[i] == 0x7F &&
187
+ memcmp (start + i + 1 , " FLAC" , 4 ) == 0 ) {
174
188
return true ;
175
189
}
176
190
}
177
191
}
178
-
192
+
179
193
return false ;
180
194
}
181
195
@@ -202,7 +216,7 @@ class MimeDetector : public MimeSource {
202
216
}
203
217
}
204
218
}
205
-
219
+
206
220
return false ;
207
221
}
208
222
@@ -229,7 +243,7 @@ class MimeDetector : public MimeSource {
229
243
}
230
244
}
231
245
}
232
-
246
+
233
247
return false ;
234
248
}
235
249
@@ -250,10 +264,10 @@ class MimeDetector : public MimeSource {
250
264
251
265
// prevent false detecton by mp3 files
252
266
if (memcmp (header, " ID3" , 3 ) == 0 ) return false ;
253
-
254
- // Special hack when we position to start of mdat box
267
+
268
+ // Special hack when we position to start of mdat box
255
269
if (memcmp (header + 4 , " mdat" , 4 ) != 0 ) return true ;
256
-
270
+
257
271
// Check for "ftyp" at offset 4
258
272
if (memcmp (header + 4 , " ftyp" , 4 ) != 0 ) return false ;
259
273
@@ -269,10 +283,30 @@ class MimeDetector : public MimeSource {
269
283
// / Provides the default mime type if no mime could be determined
270
284
void setDefaultMime (const char * mime) { default_mime = mime; }
271
285
286
+ // / sets the mime rules active or inactive
287
+ int setMimeActive (const char * mimePrefix, bool active) {
288
+ int result = 0 ;
289
+ for (auto & check : checks) {
290
+ if (StrView (check.mime ).startsWith (mimePrefix)) {
291
+ check.is_active = active;
292
+ result++;
293
+ }
294
+ }
295
+ return result;
296
+ }
297
+
298
+ // / Clears all mime rules and resets the actual selection
299
+ void clear () {
300
+ checks.clear ();
301
+ actual_mime = nullptr ;
302
+ is_first = true ;
303
+ }
304
+
272
305
protected:
273
306
struct Check {
274
307
const char * mime = nullptr ;
275
308
bool (*check)(uint8_t * data, size_t len) = nullptr ;
309
+ bool is_active = true ;
276
310
Check (const char * mime, bool (*check)(uint8_t * data, size_t len)) {
277
311
this ->mime = mime;
278
312
this ->check = check;
@@ -300,7 +334,7 @@ class MimeDetector : public MimeSource {
300
334
const char * lookupMime (uint8_t * data, size_t len) {
301
335
for (int j = 0 ; j < checks.size (); j++) {
302
336
Check l_check = checks[j];
303
- if (l_check.check (data, len)) {
337
+ if (l_check.is_active && l_check. check (data, len)) {
304
338
return l_check.mime ;
305
339
}
306
340
}
0 commit comments