Sophie

Sophie

distrib > Altlinux > 4.1 > i586 > media > core-src > by-pkgid > c83966534c5316f49967fdde4a116614 > files > 2

xmms-in-mad-0.8-alt1.src.rpm

--- xmms-mad-0.7/src/xmms-mad.c.orig	2004-10-30 14:20:05 +0400
+++ xmms-mad-0.7/src/xmms-mad.c	2005-02-19 21:33:42 +0300
@@ -76,12 +76,125 @@ xmmsmad_set_eq (int on, float preamp, fl
   //printf("set_eq\n");
 }
 
+/* needed for read_wav_id() */
+static int read_n_bytes(FILE * file, guint8 * buf, int n)
+{
+
+	if (fread(buf, 1, n, file) != n)
+	{
+		return FALSE;
+	}
+	return TRUE;
+}
+
+static guint32 convert_to_header(guint8 * buf)
+{
+
+	return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
+}
+
+static guint32 convert_to_long(guint8 * buf)
+{
+
+	return (buf[3] << 24) + (buf[2] << 16) + (buf[1] << 8) + buf[0];
+}
+
+static guint16 read_wav_id(char *filename)
+{
+	FILE *file;
+	guint16 wavid;
+	guint8 buf[4];
+	guint32 head;
+	long seek;
+
+	if (!(file = fopen(filename, "rb")))
+	{			/* Could not open file */
+		return 0;
+	}
+	if (!(read_n_bytes(file, buf, 4)))
+	{
+		fclose(file);
+		return 0;
+	}
+	head = convert_to_header(buf);
+	if (head == ('R' << 24) + ('I' << 16) + ('F' << 8) + 'F')
+	{			/* Found a riff -- maybe WAVE */
+		if (fseek(file, 4, SEEK_CUR) != 0)
+		{		/* some error occured */
+			fclose(file);
+			return 0;
+		}
+		if (!(read_n_bytes(file, buf, 4)))
+		{
+			fclose(file);
+			return 0;
+		}
+		head = convert_to_header(buf);
+		if (head == ('W' << 24) + ('A' << 16) + ('V' << 8) + 'E')
+		{		/* Found a WAVE */
+			seek = 0;
+			do
+			{
+				/* we'll be looking for the fmt-chunk which comes before the data-chunk */
+				/* A chunk consists of an header identifier (4 bytes), the length of the chunk
+				   (4 bytes), and the chunkdata itself, padded to be an even number of bytes.
+				   We'll skip all chunks until we find the "data"-one which could contain
+				   mpeg-data */
+				if (seek != 0)
+				{
+					if (fseek(file, seek, SEEK_CUR) != 0)
+					{	/* some error occured */
+						fclose(file);
+						return 0;
+					}
+				}
+				if (!(read_n_bytes(file, buf, 4)))
+				{
+					fclose(file);
+					return 0;
+				}
+				head = convert_to_header(buf);
+				if (!(read_n_bytes(file, buf, 4)))
+				{
+					fclose(file);
+					return 0;
+				}
+				seek = convert_to_long(buf);
+				seek = seek + (seek % 2);	/* Has to be even (padding) */
+				if (seek >= 2 && head == ('f' << 24) + ('m' << 16) + ('t' << 8) + ' ')
+				{
+					if (!(read_n_bytes(file, buf, 2)))
+					{
+						fclose(file);
+						return 0;
+					}
+					wavid = buf[0] + 256 * buf[1];
+					seek -= 2;
+					/* we could go on looking for
+					   other things, but all we
+					   wanted was the wavid */
+					fclose(file);
+					return wavid;
+				}
+			}
+			while (head != ('d' << 24) + ('a' << 16) + ('t' << 8) + 'a');
+			/* it's RIFF WAVE */
+		}
+		/* it's RIFF */
+	}
+	/* it's not even RIFF */
+	fclose(file);
+	return 0;
+}
+
 static int
 xmmsmad_is_our_file (char *filename)
 {
   int fin = 0;
   int rtn = 0;
   guchar check [4];
+  char *ext;
+  guint16 wavid;
 
   if (strncasecmp ("http://", filename, 7) == 0)
     {
@@ -94,41 +207,24 @@ xmmsmad_is_our_file (char *filename)
   else
     {
       fin = open (filename, O_RDONLY);
-      if (fin >= 0 && read (fin, check, 4) == 4)
+      ext = strrchr(filename, '.');
+      if (ext) 
 	{
-	  /* If first two bytes are a sync header or three bytes are "ID3" */
-	  if ( (check[0] == 0xff && (check[1] & 0x70) == 0x70) 
-	       || memcmp (check, "ID3", 3) == 0) 
+          if (!strncasecmp(ext, ".mp3", 4) && fin >= 0)
 	    {
 	      rtn = 1;
+	      /* do more proper wave header checks than old one */
 	    }
-	  else if (memcmp (check, "RIFF", 4) == 0) /* RIFF data */
-	    {        
-	      lseek (fin, 4, SEEK_CUR);
-	      read (fin, check, 4);
-
-	      if (memcmp (check, "RMP3", 4) == 0)
-		{
-		  rtn = 1;
-		}
-#if 0
-	      /* FIXME: make this test endian safe */
-	      else if (memcmp (check, "WAVE"))
-	        {
-		  /* seek to codec ID and see if it's MP3 */
-		  lseek (fin, 20, SEEK_SET);
-		  check = 0L;
-		  read (fin, &check, 2);
-		  if (check == 0x55)
-		    {
-		      rtn = 1;
-		    }
-		}
-#endif 
+	  else if (!strncasecmp(ext, ".wav", 4)) 
+	    {
+	      wavid = read_wav_id(filename);
+	      if (wavid == 85 || wavid == 80)
+	        {	/* Microsoft says 80, files say 85... */
+	           rtn = 1;
+	        }
 	    }
-	}
+        }
     }
-
   close (fin);
   return rtn;
 }