tracker r2298 - in trunk: . src/tracker-extract



Author: mottela
Date: Thu Oct  2 18:26:41 2008
New Revision: 2298
URL: http://svn.gnome.org/viewvc/tracker?rev=2298&view=rev

Log:
Added extraction of embedded album art

Added:
   trunk/src/tracker-extract/tracker-albumart.c
   trunk/src/tracker-extract/tracker-albumart.h
Modified:
   trunk/ChangeLog
   trunk/INSTALL
   trunk/configure.ac
   trunk/src/tracker-extract/Makefile.am
   trunk/src/tracker-extract/tracker-extract-mp3.c

Modified: trunk/INSTALL
==============================================================================
--- trunk/INSTALL	(original)
+++ trunk/INSTALL	Thu Oct  2 18:26:41 2008
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
 
 This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -10,10 +10,7 @@
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
+These are generic installation instructions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -26,9 +23,9 @@
 
    It can also use an optional file (typically called `config.cache'
 and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
+the results of its tests to speed up reconfiguring.  (Caching is
 disabled by default to prevent problems with accidental use of stale
-cache files.
+cache files.)
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
@@ -38,17 +35,20 @@
 may remove or edit it.
 
    The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
 
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -67,9 +67,6 @@
      all sorts of other programs in order to regenerate files that came
      with the distribution.
 
-  6. Often, you can also type `make uninstall' to remove the installed
-     files again.
-
 Compilers and Options
 =====================
 
@@ -81,7 +78,7 @@
 by setting variables in the command line or in the environment.  Here
 is an example:
 
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
 
    *Note Defining Variables::, for more details.
 
@@ -90,15 +87,17 @@
 
 You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
 
 Installation Names
 ==================
@@ -191,12 +190,12 @@
      ./configure CC=/usr/local2/bin/gcc
 
 causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
+overridden in the site shell script).  Here is a another example:
 
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug.  Until the bug is fixed you can use this workaround:
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
 
-     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
 
 `configure' Invocation
 ======================

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Thu Oct  2 18:26:41 2008
@@ -124,6 +124,12 @@
 AC_SUBST(GMIME_CFLAGS)
 AC_SUBST(GMIME_LIBS)
 
+# Check GdkPixbuf
+GDK_PIXBUF_CHECK="gdk-pixbuf-2.0 >= 2.12.0"
+PKG_CHECK_MODULES(GDK_PIXBUF, $GDK_PIXBUF_CHECK)
+AC_SUBST(GDK_PIXBUF_LIBS)
+AC_SUBST(GDK_PIXBUF_CFLAGS)
+
 # Check for Dbus 0.50 or higher
 PKG_CHECK_MODULES(DBUS, [dbus-1 >= $DBUS_REQUIRED dbus-glib-1 >= $DBUS_REQUIRED])
 AC_SUBST(DBUS_CFLAGS)
@@ -391,6 +397,7 @@
 
 AM_CONDITIONAL(HAVE_HAL, test "x$have_hal" = "xyes")
 
+
 ####################################################################
 # check for GStreamer or Xine. Otherwise, call an external video
 # player (Totem or MPlayer).

Modified: trunk/src/tracker-extract/Makefile.am
==============================================================================
--- trunk/src/tracker-extract/Makefile.am	(original)
+++ trunk/src/tracker-extract/Makefile.am	Thu Oct  2 18:26:41 2008
@@ -16,6 +16,7 @@
 	$(POPPLER_GLIB_CFLAGS) 						\
 	$(GSTREAMER_CFLAGS) 						\
 	$(XINE_CFLAGS) 							\
+	$(GDK_PIXBUF_CFLAGS)						\
 	-I$(top_srcdir)/src 						\
 	-DMODULES_DIR=\"$(modulesdir)\"
 
@@ -66,6 +67,11 @@
 	tracker-xmp.c							\
 	tracker-xmp.h
 
+# Common AlbumArt sources
+albumart_sources =							\
+	tracker-albumart.c						\
+	tracker-albumart.h
+
 # ABW
 libextract_abw_la_SOURCES = tracker-extract-abw.c
 libextract_abw_la_LDFLAGS = $(module_flags)
@@ -77,9 +83,9 @@
 libextract_imagemagick_la_LIBADD = $(GLIB2_LIBS) $(EXEMPI_LIBS)
 
 # MP3
-libextract_mp3_la_SOURCES = tracker-extract-mp3.c
+libextract_mp3_la_SOURCES = tracker-extract-mp3.c $(albumart_sources)
 libextract_mp3_la_LDFLAGS = $(module_flags)
-libextract_mp3_la_LIBADD = $(GLIB2_LIBS)
+libextract_mp3_la_LIBADD = $(GLIB2_LIBS) $(GDK_PIXBUF_LIBS)
 
 # MPlayer
 libextract_mplayer_la_SOURCES = tracker-extract-mplayer.c

Added: trunk/src/tracker-extract/tracker-albumart.c
==============================================================================
--- (empty file)
+++ trunk/src/tracker-extract/tracker-albumart.c	Thu Oct  2 18:26:41 2008
@@ -0,0 +1,114 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Tracker AlbumArt - Album art helper functions
+ * Copyright (C) 2008, Nokia
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <gio/gio.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "config.h"
+#include "tracker-albumart.h"
+
+gboolean
+tracker_save_albumart (const unsigned char *buffer,
+		       size_t len,
+		       const gchar *artist, 
+		       const gchar *album,
+		       const gchar *uri)
+{
+	GdkPixbufLoader *loader;
+	GdkPixbuf       *pixbuf = NULL;
+	gchar            name[128];
+	gchar           *filename;
+	gchar           *dir;
+	gchar           *checksum;
+	GError          *error = NULL;
+
+	g_type_init();
+
+	if (artist && album) {
+		g_sprintf (name, "%s %s", album, artist);
+	} else if (uri) {
+		g_sprintf (name, "%s", uri);
+	} else {
+		g_warning ("No identification data for embedded image");		
+		return FALSE;
+	}
+
+	checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, name, -1);
+	g_sprintf (name, "%s.png", checksum);
+	g_free (checksum);
+
+	dir = g_build_filename (g_get_home_dir (),
+				".album_art",
+				NULL);
+
+	filename = g_build_filename (dir,
+				     name,
+				     NULL);
+
+	if(g_file_test (filename, G_FILE_TEST_EXISTS)) {
+		g_free (filename);
+		g_free (dir);
+
+		return TRUE;
+	}
+
+	if(!g_file_test (dir, G_FILE_TEST_EXISTS)) {
+		g_mkdir_with_parents (dir, 0770);
+	}
+
+	g_free (dir);
+
+	loader = gdk_pixbuf_loader_new();
+
+	if (!gdk_pixbuf_loader_write (loader, buffer, len, &error)) {
+		g_warning("%s\n", error->message);
+		g_error_free(error);
+
+		gdk_pixbuf_loader_close (loader, NULL);
+		g_free (filename);
+		return FALSE;
+	}
+
+	pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+	if (!gdk_pixbuf_save (pixbuf, filename, "jpeg", &error, NULL)) {
+		g_warning("%s\n", error->message);
+		g_error_free(error);
+
+		g_free (filename);
+		g_object_unref(pixbuf);
+
+		gdk_pixbuf_loader_close (loader, NULL);
+		return FALSE;
+	}
+
+	g_free (filename);
+	g_object_unref(pixbuf);
+
+	if (!gdk_pixbuf_loader_close (loader, &error)) {
+		g_warning("%s\n", error->message);
+		g_error_free(error);
+		return FALSE;
+	}
+
+	return TRUE;
+}

Added: trunk/src/tracker-extract/tracker-albumart.h
==============================================================================
--- (empty file)
+++ trunk/src/tracker-extract/tracker-albumart.h	Thu Oct  2 18:26:41 2008
@@ -0,0 +1,31 @@
+/* Tracker Xmp - Album art helper functions
+ * Copyright (C) 2008, Nokia
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _TRACKER_ALBUMART_H_
+#define _TRACKER_ALBUMART_H_
+
+#include <glib.h>
+
+gboolean tracker_save_albumart (const unsigned char *buffer, 
+				size_t len, 
+				const char *artist, 
+				const char *album,
+				const gchar *uri);
+
+#endif /* _TRACKER_ALBUMART_H_ */

Modified: trunk/src/tracker-extract/tracker-extract-mp3.c
==============================================================================
--- trunk/src/tracker-extract/tracker-extract-mp3.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-mp3.c	Thu Oct  2 18:26:41 2008
@@ -41,6 +41,7 @@
 #endif
 
 #include "tracker-extract.h"
+#include "tracker-albumart.h"
 
 #define MAX_FILE_READ	  1024 * 1024 * 10
 #define MAX_MP3_SCAN_DEEP 16768
@@ -59,6 +60,11 @@
 	gchar *genre;
 } id3tag;
 
+typedef struct {
+	unsigned char *data;
+	size_t         size;
+} album_art;
+
 enum {
 	MPEG_ERR,
 	MPEG_V1,
@@ -499,7 +505,8 @@
 static void
 get_id3v24_tags (const gchar *data,
 		 size_t       size,
-		 GHashTable  *metadata)
+		 GHashTable  *metadata,
+		 album_art   *albumart)
 {
 	gint	unsync;
 	gint	extendedHdr;
@@ -666,6 +673,29 @@
 			i++;
 		}
 
+		/* Check for embedded images */
+		if (strncmp (&data[pos], "APIC", 4) == 0) {
+			gchar          text_type;
+			const gchar   *mime;
+			gchar          pic_type;
+			const gchar   *desc;
+			guint          offset;
+
+
+			text_type =  data[pos+10];
+			mime      = &data[pos+11];
+			pic_type  =  data[pos+11+strlen(mime)+1];
+			desc      = &data[pos+11+strlen(mime)+1+1];
+
+			if (pic_type == 3) {
+
+				offset = pos+11+strlen(mime)+2+strlen(desc)+1;
+
+				albumart->data = (unsigned char *)&data[offset];
+				albumart->size = csize;
+			}
+		}
+
 		pos += 10 + csize;
 	}
 }
@@ -673,7 +703,8 @@
 static void
 get_id3v23_tags (const gchar *data,
 		 size_t       size,
-		 GHashTable  *metadata)
+		 GHashTable  *metadata,
+		 album_art   *albumart)
 {
 	gint	unsync;
 	gint	extendedHdr;
@@ -838,6 +869,29 @@
 			i++;
 		}
 
+		/* Check for embedded images */
+		if (strncmp (&data[pos], "APIC", 4) == 0) {
+			gchar          text_type;
+			const gchar   *mime;
+			gchar          pic_type;
+			const gchar   *desc;
+			guint          offset;
+
+
+			text_type =  data[pos+10];
+			mime      = &data[pos+11];
+			pic_type  =  data[pos+11+strlen(mime)+1];
+			desc      = &data[pos+11+strlen(mime)+1+1];
+
+			if (pic_type == 3) {
+
+				offset = pos+11+strlen(mime)+2+strlen(desc)+1;
+
+				albumart->data = (unsigned char *)&data[offset];
+				albumart->size = csize;
+			}
+		}
+
 		pos += 10 + csize;
 	}
 }
@@ -845,7 +899,8 @@
 static void
 get_id3v2_tags (const gchar *data,
 		size_t	     size,
-		GHashTable  *metadata)
+		GHashTable  *metadata,
+		album_art   *albumart)
 {
 	gint	unsync;
 	guint	tsize;
@@ -968,6 +1023,25 @@
 			i++;
 		}
 
+		/* Check for embedded images */
+		if (strncmp (&data[pos], "PIC", 3) == 0) {
+			gchar          pic_type;
+			const gchar   *desc;
+			guint          offset;
+
+			pic_type  =  data[pos+6+3+1+3];
+			desc      = &data[pos+6+3+1+3+1];
+
+			if (pic_type == 3) {
+
+				offset = pos+6+3+1+3+1+strlen(desc)+1;
+
+				albumart->data = (unsigned char *)&data[offset];
+				albumart->size = csize;
+			}
+		}
+
+
 		pos += 6 + csize;
 	}
 }
@@ -981,6 +1055,7 @@
 	struct stat  fstatbuf;
 	size_t	     size;
 	id3tag	     info;
+	album_art    albumart;
 
 	info.title = NULL;
 	info.artist = NULL;
@@ -989,6 +1064,9 @@
 	info.comment = NULL;
 	info.genre = NULL;
 
+	albumart.data = NULL;
+	albumart.size = 0;
+
 #if defined(__linux__)
 	file = g_open (filename, (O_RDONLY | O_NOATIME), 0);
 #else
@@ -1066,13 +1144,21 @@
 	free (info.comment);
 
 	/* Get other embedded tags */
-	get_id3v2_tags (buffer, size, metadata);
-	get_id3v23_tags (buffer, size, metadata);
-	get_id3v24_tags (buffer, size, metadata);
+	get_id3v2_tags (buffer, size, metadata, &albumart);
+	get_id3v23_tags (buffer, size, metadata, &albumart);
+	get_id3v24_tags (buffer, size, metadata, &albumart);
 
 	/* Get mp3 stream info */
 	mp3_parse (buffer, size, metadata);
 
+	/* Save embedded album art */
+	if (albumart.data && albumart.size) {
+		tracker_save_albumart (albumart.data, albumart.size,
+				       g_hash_table_lookup (metadata, "Audio:Artist") ,
+				       g_hash_table_lookup (metadata, "Audio:Album"),
+				       filename);
+	}
+	
 	/* Check that we have the minimum data. FIXME We should not need to do this */
 	if (!g_hash_table_lookup (metadata, "Audio:Title")) {
 		g_hash_table_insert (metadata,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]