diff --git a/AUTHORS b/AUTHORS index 06ce4f0..dc6b24f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,3 +28,4 @@ Radoslaw Grzanka Kim Woelders Nick Blievers Mike Castle +R.Ramkumar diff --git a/configure.in b/configure.in index 4d9ff75..8f75997 100644 --- a/configure.in +++ b/configure.in @@ -364,6 +364,31 @@ fi AM_CONDITIONAL(BUILD_BZ2_LOADER, test "$bz2_ok" = yes) AC_SUBST(BZ2LIBS) +AC_CHECK_LIB(id3tag, id3_file_open, + id3_libs="-lz -lid3tag" + id3_ok=yes, + id3_ok=no + AC_MSG_WARN(*** Native mp3 support will not be built (id3tag library not found) ***), + -lz) +if test "$id3_ok" = yes; then + AC_MSG_CHECKING([for id3tag.h]) + AC_TRY_CPP( + [#include + #undef PACKAGE + #undef VERSION + #include ], + id3_ok=yes, + id3_ok=no) + AC_MSG_RESULT($id3_ok) + if test "$id3_ok" = yes; then + ID3LIBS=$id3_libs + else + AC_MSG_WARN(*** Native mp3 support will not be built (id3tag header file not found) ***) + fi +fi +AM_CONDITIONAL(BUILD_ID3_LOADER, test "$id3_ok" = yes) +AC_SUBST(ID3LIBS) + AC_SUBST(requirements) AC_OUTPUT([ @@ -411,6 +436,7 @@ echo " TIFF....................: $tiff_ok" echo " GIF.....................: $gif_ok" echo " ZLIB....................: $zlib_ok" echo " BZIP2...................: $bz2_ok" +echo " MP3.....................: $id3_ok" echo echo echo "Use MMX for extra speed...: $mmx" diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am index 75f3c40..b68f9f7 100644 --- a/src/modules/loaders/Makefile.am +++ b/src/modules/loaders/Makefile.am @@ -27,6 +27,9 @@ endif if BUILD_BZ2_LOADER BZ2_L = bz2.la endif +if BUILD_ID3_LOADER +ID3_L = id3.la +endif pkg_LTLIBRARIES = \ $(JPEG_L) \ @@ -35,6 +38,7 @@ $(TIFF_L) \ $(GIF_L) \ $(ZLIB_L) \ $(BZ2_L) \ +$(ID3_L) \ pnm.la \ argb.la \ bmp.la \ @@ -66,6 +70,10 @@ bz2_la_SOURCES = loader_bz2.c bz2_la_LDFLAGS = -module -avoid-version bz2_la_LIBADD = @BZ2LIBS@ $(top_builddir)/src/lib/libImlib2.la +id3_la_SOURCES = loader_id3.c +id3_la_LDFLAGS = -module -avoid-version +id3_la_LIBADD = @ID3LIBS@ $(top_builddir)/src/lib/libImlib2.la + pnm_la_SOURCES = loader_pnm.c pnm_la_LDFLAGS = -module -avoid-version pnm_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la diff --git a/src/modules/loaders/loader_id3.c b/src/modules/loaders/loader_id3.c new file mode 100644 index 0000000..2755f8d --- /dev/null +++ b/src/modules/loaders/loader_id3.c @@ -0,0 +1,153 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "image.h" + +#include + +int extract_pic (struct id3_frame* frame, int dest, char* ext, int extlen) +{ + union id3_field* field; + unsigned char const * data; + long length; + int done = 0; + + field = id3_frame_field (frame, 1); + data = id3_field_getlatin1 (field); + if (! data) { + fprintf (stderr, "No mime type data found for image frame\n"); + return 0; + } + if (strncmp (data, "image/", 6)) { + fprintf (stderr, + "Picture frame with unknown mime-type %s found\n", + data); + return 0; + } + strncpy (ext, data + 6, extlen); + field = id3_frame_field (frame, 4); + data = id3_field_getbinarydata (field, &length); + if (! data) { + fprintf (stderr, "No image data found for frame\n"); + return 0; + } + while (length > 0) { + ssize_t res; + if ((res = write (dest, data + done, length)) < 0) { + if (errno == EINTR) + continue; + perror ("Unable to write to file"); + return 0; + } + length -= res; + done += res; + } + return 1; +} + +/* Loader for ID3v2 tags in audio files. + * ID3v2 allows for 'Attached Picture' frames to be embedded in the file. + * A numeric key is supported, and indicates the zero-based frame index + * to be extracted, in case more than one such frame is found. + * Defaults to 0, or the first picture frame. + */ +char load (ImlibImage *im, ImlibProgressFunction progress, + char progress_granularity, char immediate_load) +{ + ImlibLoader *loader; + char *file, tmp[] = "/tmp/imlib2_loader_id3-XXXXXX", *p; + char real_ext[16]; + int res, dest, pic_index = 0; + struct id3_file* tagfile; + struct id3_tag* tag; + struct id3_frame* frame; + + assert (im); + + p = strrchr(im->real_file, '.'); + if (! (p && p != im->real_file && !strcmp (p + 1, "mp3"))) { + fprintf (stderr, "Unknown extension %s\n", p + 1); + return 0; + } + + if (im->key) + pic_index = atoi (im->key); + + tagfile = id3_file_open (im->real_file, ID3_FILE_MODE_READONLY); + if (! tagfile) { + fprintf (stderr, "Unable to open tagged file %s: %s", + im->real_file, strerror (errno)); + return 0; + } + tag = id3_file_tag (tagfile); + if (! tag) { + fprintf (stderr, "Unable to find ID3v2 tags in file\n"); + return 0; + } + frame = id3_tag_findframe (tag, "APIC", pic_index); + if (! frame) { + fprintf (stderr, "No picture frame # %d found\n", pic_index); + return 0; + } + + if ((dest = mkstemp (tmp)) < 0) { + fprintf (stderr, "Unable to create a temporary file\n"); + id3_file_close (tagfile); + return 0; + } + + real_ext[15] = '\0'; + real_ext[0] = '.'; + res = extract_pic (frame, dest, real_ext + 1, 14); + close (dest); + id3_file_close (tagfile); + + if (!res) { + unlink (tmp); + return 0; + } + + if (!(loader = __imlib_FindBestLoaderForFile (real_ext, 0))) { + fprintf (stderr, "No loader found for extension %s\n", real_ext); + unlink (tmp); + return 0; + } + + /* remember the original filename */ + file = strdup (im->real_file); + + free (im->real_file); + im->real_file = strdup (tmp); + loader->load (im, progress, progress_granularity, immediate_load); + + free (im->real_file); + im->real_file = file; + unlink (tmp); + + return 1; +} + +void formats (ImlibLoader *l) +{ + /* this is the only bit you have to change... */ + char *list_formats[] = {"mp3"}; + int i; + + /* don't bother changing any of this - it just reads this in + * and sets the struct values and makes copies + */ + l->num_formats = sizeof (list_formats) / sizeof (char *); + l->formats = (char**) malloc (sizeof (char *) * l->num_formats); + + for (i = 0; i < l->num_formats; i++) + l->formats[i] = strdup (list_formats[i]); +}