changeset 910:a540829b188a trunk

[svn] Detection of modules by magic bytes instead of by extension. Please let me know of false positives, if any. I would appreciate examples for any of the extensions still listed in the fallback that are not archives.
author chainsaw
date Sun, 02 Apr 2006 11:32:31 -0700
parents 46960fb15ba0
children 8513cbe2ba33
files Plugins/Input/modplug/modplugbmp.cpp Plugins/Input/modplug/modplugbmp.h
diffstat 2 files changed, 115 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/modplug/modplugbmp.cpp	Fri Mar 31 14:55:11 2006 -0800
+++ b/Plugins/Input/modplug/modplugbmp.cpp	Sun Apr 02 11:32:31 2006 -0700
@@ -14,6 +14,7 @@
 #include "stddefs.h"
 #include "archive/open.h"
 #include "libaudacious/configdb.h"
+#include "libaudacious/vfs.h"
 extern "C" {
 #include "audacious/output.h"
 }
@@ -95,6 +96,96 @@
 	string lExt;
 	uint32 lPos;
 
+	VFSFile *file;
+	gchar magic[4];
+
+	if ((file = vfs_fopen(aFilename.c_str(), "rb"))) {
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, UMX_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, XM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, M669_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, IT_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MTM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, PSM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	vfs_fseek(file, 44, SEEK_SET);
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, S3M_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	vfs_fseek(file, 1080, SEEK_SET);
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER6, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_15INSTRUMENT, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+
+	/* We didn't find the magic bytes, fall back to extension check */
+	vfs_fclose(file);
+	} /* end of vfs_open main if statement */
+
 	lPos = aFilename.find_last_of('.');
 	if((int)lPos == -1)
 		return false;
@@ -102,8 +193,6 @@
 	for(uint32 i = 0; i < lExt.length(); i++)
 		lExt[i] = tolower(lExt[i]);
 
-	if (lExt == ".669")
-		return true;
 	if (lExt == ".amf")
 		return true;
 	if (lExt == ".ams")
@@ -116,36 +205,18 @@
 		return true;
 	if (lExt == ".far")
 		return true;
-	if (lExt == ".it")
-		return true;
 	if (lExt == ".mdl")
 		return true;
 	if (lExt == ".med")
 		return true;
-	if (lExt == ".mod")
-		return true;
-	if (lExt == ".mtm")
-		return true;
-	if (lExt == ".okt")
-		return true;
-	if (lExt == ".ptm")
-		return true;
-	if (lExt == ".s3m")
-		return true;
 	if (lExt == ".stm")
 		return true;
 	if (lExt == ".ult")
 		return true;
-	if (lExt == ".umx")      //Unreal rocks!
-		return true;
-	if (lExt == ".xm")
-		return true;
 	if (lExt == ".j2b")
 		return true;
 	if (lExt == ".mt2")
 		return true;
-	if (lExt == ".psm")
-		return true;
 
 	if (lExt == ".mdz")
 		return true;
--- a/Plugins/Input/modplug/modplugbmp.h	Fri Mar 31 14:55:11 2006 -0800
+++ b/Plugins/Input/modplug/modplugbmp.h	Sun Apr 02 11:32:31 2006 -0700
@@ -16,6 +16,30 @@
 
 #include "audacious/plugin.h"
 
+/* Module files have their magic deep inside the file, at offset 1080; source: http://www.onicos.com/staff/iz/formats/mod.html */
+#define MOD_MAGIC_PROTRACKER4	(unsigned char [4]) { 0x4D, 0x2E, 0x4B, 0x2E }  // "M.K." - Protracker 4 channel
+#define MOD_MAGIC_PROTRACKER4X	(unsigned char [4]) { 0x4D, 0x21, 0x4B, 0x21 }  // "M!K!" - Protracker 4 channel
+#define MOD_MAGIC_STARTRACKER4	(unsigned char [4]) { 0x46, 0x4C, 0x54, 0x34 }  // "FLT4" - Startracker 4 channel
+#define MOD_MAGIC_STARTRACKER8	(unsigned char [4]) { 0x46, 0x4C, 0x54, 0x38 }  // "FLT8" - Startracker 8 channel
+#define MOD_MAGIC_FASTTRACKER4	(unsigned char [4]) { 0x34, 0x43, 0x48, 0x4E }  // "4CHN" - Fasttracker 4 channel
+#define MOD_MAGIC_FASTTRACKER6	(unsigned char [4]) { 0x36, 0x43, 0x48, 0x4E }  // "6CHN" - Fasttracker 6 channel
+#define MOD_MAGIC_FASTTRACKER8	(unsigned char [4]) { 0x38, 0x43, 0x48, 0x4E }  // "8CHN" - Fasttracker 8 channel
+#define MOD_MAGIC_OKTALYZER8	(unsigned char [4]) { 0x43, 0x44, 0x38, 0x31 }  // "CD81" - Atari oktalyzer 8 channel
+#define MOD_MAGIC_OKTALYZER8X	(unsigned char [4]) { 0x4F, 0x4B, 0x54, 0x41 }  // "OKTA" - Atari oktalyzer 8 channel
+#define MOD_MAGIC_TAKETRACKER16	(unsigned char [4]) { 0x31, 0x36, 0x43, 0x4E }  // "16CN" - Taketracker 16 channel
+#define MOD_MAGIC_TAKETRACKER32 (unsigned char [4]) { 0x33, 0x32, 0x43, 0x4E }  // "32CN" - Taketracker 32 channel
+#define MOD_MAGIC_15INSTRUMENT	(unsigned char [4]) { 0x20, 0x20, 0x20, 0x20 }  // "    " - 15-instrument 4 channel
+
+#define S3M_MAGIC	(unsigned char [4]) { 0x53, 0x43, 0x52, 0x4D }			/* This is the SCRM string at offset 44 to 47 in the S3M header */
+
+/* These nicer formats have the magic bytes at the front of the file where they belong */
+#define UMX_MAGIC	(unsigned char [4]) { 0xC1, 0x83, 0x2A, 0x9E }
+#define XM_MAGIC	(unsigned char [4]) { 0x45, 0x78, 0x74, 0x65 }			/* Exte(nded Module) */
+#define M669_MAGIC	(unsigned char [4]) { 0x69, 0x66, 0x20, 0x20 }
+#define IT_MAGIC	(unsigned char [4]) { 0x49, 0x4D, 0x50, 0x4D }			/* IMPM */
+#define MTM_MAGIC	(unsigned char [4]) { 0x4D, 0x54, 0x4D, 0x10 }
+#define PSM_MAGIC	(unsigned char [4]) { 0x50, 0x53, 0x4D, 0x20 }
+
 using namespace std;
 
 class CSoundFile;