summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego 'Flameeyes' Pettenò <flameeyes@gmail.com>2006-12-25 17:39:39 +0000
committerDiego 'Flameeyes' Pettenò <flameeyes@gmail.com>2006-12-25 17:39:39 +0000
commit0a48883b044c3b9b4f1f00a338b1439bfba1ebcc (patch)
tree45d908d8d25366f4ef9f5b0b0fa2a38a532e1bb2 /src
parentfae8a7ffbc1d7f59fc82c133d3e54ec3ae5c5580 (diff)
downloadxine-lib-0a48883b044c3b9b4f1f00a338b1439bfba1ebcc.tar.gz
xine-lib-0a48883b044c3b9b4f1f00a338b1439bfba1ebcc.tar.bz2
* Implement at least a partial content-based detection of ModPlug-decoded
module files, using the magic numbers from GNU file. This allows to open module files based on content rather than on their extension only. [bug #1445746] CVS patchset: 8445 CVS date: 2006/12/25 17:39:39
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_mod.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c
index 185ef5c97..7e0d99556 100644
--- a/src/demuxers/demux_mod.c
+++ b/src/demuxers/demux_mod.c
@@ -50,6 +50,7 @@
#include "demux.h"
#include "group_audio.h"
#include "modplug.h"
+#include "bswap.h"
#define MOD_SAMPLERATE 44100
#define MOD_BITS 16
@@ -89,6 +90,43 @@ typedef struct {
demux_class_t demux_class;
} demux_mod_class_t;
+#define FOURCC_32(a, b, c, d) (d + (c<<8) + (b<<16) + (a<<24))
+
+/**
+ * @brief Probes if the given file can be demuxed using modplug or not
+ * @retval 0 The file is not a valid modplug file (or the probe isn't complete yet)
+ * @retval 1 The file has been identified as a valid modplug file
+ * @todo Just Protracker files are detected right now.
+ */
+static int probe_mod_file(demux_mod_t *this) {
+ /* We need the value present at offset 1080, of size 4 */
+ union {
+ uint8_t buffer[1080+4]; /* The raw buffer */
+ uint32_t values[(1080+4)/sizeof(uint32_t)];
+ } header;
+
+ if (_x_demux_read_header(this->input, header.buffer, 1080+4) != 1080+4)
+ return 0;
+
+ /* Magic numbers taken from GNU file's magic description */
+ switch( ABE_32(header.values + (1080/sizeof(uint32_t))) ) {
+ case FOURCC_32('M', '.', 'K', '.'): /* 4-channel Protracker module sound data */
+ case FOURCC_32('M', '!', 'K', '!'): /* 4-channel Protracker module sound data */
+ case FOURCC_32('F', 'L', 'T', '4'): /* 4-channel Startracker module sound data */
+ case FOURCC_32('F', 'L', 'T', '8'): /* 8-channel Startracker module sound data */
+ case FOURCC_32('4', 'C', 'H', 'N'): /* 4-channel Fasttracker module sound data */
+ case FOURCC_32('6', 'C', 'H', 'N'): /* 6-channel Fasttracker module sound data */
+ case FOURCC_32('8', 'C', 'H', 'N'): /* 8-channel Fasttracker module sound data */
+ case FOURCC_32('C', 'D', '8', '1'): /* 8-channel Octalyser module sound data */
+ case FOURCC_32('O', 'K', 'T', 'A'): /* 8-channel Oktalyzer module sound data */
+ case FOURCC_32('1', '6', 'C', 'N'): /* 16-channel Taketracker module sound data */
+ case FOURCC_32('3', '2', 'C', 'N'): /* 32-channel Taketracker module sound data */
+ return 1;
+ }
+
+ return 0;
+}
+
/* returns 1 if the MOD file was opened successfully, 0 otherwise */
static int open_mod_file(demux_mod_t *this) {
int total_read;
@@ -306,6 +344,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
break;
case METHOD_BY_CONTENT:
+ if (probe_mod_file(this) && open_mod_file(this))
+ break;
+
default:
free (this);
return NULL;