2016-08-25 09:56 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0001415MPDOtherpublic2009-01-04 16:03
Reporterlostclus 
Assigned Tometyl 
PrioritylowSeverityfeatureReproducibilityN/A
StatusclosedResolutionfixed 
Product Version 
Target VersionFixed in Versiongit 
Summary0001415: [PATCH] pkzip, gzip and bzip2 on-fly decompression
DescriptionThis patch adds pkzip, gzip and bzip2 decompression feature in mod_plugin.c. Also fixes module infinitive loops.
Tagsarchive, zip
Attached Files
  • patch file icon mpd-0.12.1-unpack.patch (25,433 bytes) 2006-12-14 07:48 -
    diff -Naur mpd-0.12.1.orig/configure.ac mpd-0.12.1/configure.ac
    --- mpd-0.12.1.orig/configure.ac	2006-10-11 02:56:58.000000000 +0300
    +++ mpd-0.12.1/configure.ac	2006-12-14 00:49:29.000000000 +0200
    @@ -78,6 +78,8 @@
     AC_ARG_ENABLE(aac,[  --disable-aac           disable AAC support (default: enable)],[enable_aac=$enableval],[enable_aac=yes])
     AC_ARG_ENABLE(audiofile,[  --disable-audiofile     disable audiofile support, disables wave support (default: enable)],[enable_audiofile=$enableval],[enable_audiofile=yes])
     AC_ARG_ENABLE(mod,[  --enable-mod            enable MOD support (default: disable],[enable_mod=$enableval],[enable_mod=yes])
    +AC_ARG_ENABLE(zlib,[  --disable-zlib           disable gzip and pkzip decompression support (default: enable)],[enable_zlib=$enableval],[enable_zlib=yes])
    +AC_ARG_ENABLE(bzip2,[  --disable-bzip2           disable bzip2 decompression support (default: enable)],[enable_bzip2=$enableval],[enable_bzip2=yes])
     AC_ARG_ENABLE(mpc,[  --disable-mpc           disable musepack (MPC) support (default: enable)],[enable_mpc=$enableval],[enable_mpc=yes])
     AC_ARG_ENABLE(id3,[  --disable-id3           disable id3 support (default: enable)],[enable_id3=$enableval],[enable_id3=yes])
     
    @@ -101,6 +103,14 @@
     AC_ARG_WITH(faad-libraries,[  --with-faad-libraries=DIR   Directory where faad2 library is installed (optional)], faad_libraries="$withval", faad_libraries="")
     AC_ARG_WITH(faad-includes,[  --with-faad-includes=DIR    Directory where faad2 header files are installed (optional)], faad_includes="$withval", faad_includes="")
     
    +AC_ARG_WITH(bzip2,[  --with-bzip2=PFX             Prefix where bzip2 is installed], bzip2_prefix="$withval", bzip2_prefix="")
    +AC_ARG_WITH(bzip2-libraries,[  --with-bzip2-libraries=DIR   Directory where bzip2 library is installed (optional)], bzip2_libraries="$withval", bzip2_libraries="")
    +AC_ARG_WITH(bzip2-includes,[  --with-bzip2-includes=DIR    Directory where bzip2 header files are installed (optional)], bzip2_includes="$withval", bzip2_includes="")
    +
    +AC_ARG_WITH(zlib,[  --with-zlib=PFX             Prefix where zlib is installed], zlib_prefix="$withval", zlib_prefix="")
    +AC_ARG_WITH(zlib-libraries,[  --with-zlib-libraries=DIR   Directory where zlib library is installed (optional)], zlib_libraries="$withval", zlib_libraries="")
    +AC_ARG_WITH(zlib-includes,[  --with-zlib-includes=DIR    Directory where zlib header files are installed (optional)], zlib_includes="$withval", zlib_includes="")
    +
     AC_C_BIGENDIAN
     
     AC_CHECK_SIZEOF(short)
    @@ -576,6 +586,84 @@
     	fi
     fi
     
    +if test x$enable_zlib = xyes; then
    +  	if test "x$zlib_libraries" != "x" ; then
    +  		ZLIB_LIBS="-L$zlib_libraries"
    +  	elif test "x$zlib_prefix" != "x" ; then
    +		ZLIB_LIBS="-L$zlib_prefix/lib"
    +  	elif test "x$prefix" != "xNONE"; then
    +    		ZLIB_LIBS="-L$libdir"
    +  	fi
    +
    + 	ZLIB_LIBS="$ZLIB_LIBS -lz"
    +
    +  	if test "x$zlib_includes" != "x" ; then
    +  		ZLIB_CFLAGS="-I$zlib_includes"
    +  	elif test "x$zlib_prefix" != "x" ; then
    +    		ZLIB_CFLAGS="-I$zlib_prefix/include"
    +  	elif test "x$prefix" != "xNONE"; then
    +    		ZLIB_CFLAGS="-I$includedir"
    +  	fi
    +
    +	oldcflags=$CFLAGS
    +	oldlibs=$LIBS
    +	oldcppflags=$CPPFLAGS
    +	CFLAGS="$CFLAGS $MPD_CFLAGS $ZLIB_CFLAGS -I."
    +	LIBS="$LIBS $MPD_LIBS $ZLIB_LIBS"
    +	CPPFLAGS=$CFLAGS
    +	AC_CHECK_HEADER(zlib.h,,enable_zlib=no)
    +	if test x$enable_zlib = xyes; then
    +		AC_CHECK_LIB(z,inflate,[MPD_LIBS="$MPD_LIBS $ZLIB_LIBS";MPD_CFLAGS="$MPD_CFLAGS $ZLIB_CFLAGS";],enable_zlib=no)
    +	fi
    +	if test x$enable_zlib = xyes; then
    +		AC_DEFINE(HAVE_ZLIB,1,[Define to use gzip and pkzip decompression])
    +	else
    +		AC_MSG_WARN([zlib lib needed for gzip and pkzip decompression support -- disabling zlib support])
    +	fi
    +	CFLAGS=$oldcflags
    +	LIBS=$oldlibs
    +	CPPFLAGS=$oldcppflags
    +fi
    +
    +if test x$enable_bzip2 = xyes; then
    +  	if test "x$bzip2_libraries" != "x" ; then
    +  		BZIP2_LIBS="-L$bzip2_libraries"
    +  	elif test "x$bzip2_prefix" != "x" ; then
    +		BZIP2_LIBS="-L$bzip2_prefix/lib"
    +  	elif test "x$prefix" != "xNONE"; then
    +    		BZIP2_LIBS="-L$libdir"
    +  	fi
    +
    + 	BZIP2_LIBS="$BZIP2_LIBS -lbz2"
    +
    +  	if test "x$bzip2_includes" != "x" ; then
    +  		BZIP2_CFLAGS="-I$bzip2_includes"
    +  	elif test "x$bzip2_prefix" != "x" ; then
    +    		BZIP2_CFLAGS="-I$bzip2_prefix/include"
    +  	elif test "x$prefix" != "xNONE"; then
    +    		BZIP2_CFLAGS="-I$includedir"
    +  	fi
    +
    +	oldcflags=$CFLAGS
    +	oldlibs=$LIBS
    +	oldcppflags=$CPPFLAGS
    +	CFLAGS="$CFLAGS $MPD_CFLAGS $BZIP2_CFLAGS -I."
    +	LIBS="$LIBS $MPD_LIBS $BZIP2_LIBS"
    +	CPPFLAGS=$CFLAGS
    +	AC_CHECK_HEADER(bzlib.h,,enable_bzip2=no)
    +	if test x$enable_bzip2 = xyes; then
    +		AC_CHECK_LIB(bz2,BZ2_bzdopen,[MPD_LIBS="$MPD_LIBS $BZIP2_LIBS";MPD_CFLAGS="$MPD_CFLAGS $BZIP2_CFLAGS";],enable_bzip2=no)
    +	fi
    +	if test x$enable_bzip2 = xyes; then
    +		AC_DEFINE(HAVE_BZIP2,1,[Define to use bzip2 decompression])
    +	else
    +		AC_MSG_WARN([bzip2 lib needed for bzip2 decompression support -- disabling bzip2 support])
    +	fi
    +	CFLAGS=$oldcflags
    +	LIBS=$oldlibs
    +	CPPFLAGS=$oldcppflags
    +fi
    +
     AC_OUTPUT(src/mp4ff/Makefile doc/Makefile src/Makefile Makefile )
     
     echo ""
    @@ -705,6 +793,18 @@
     	echo " MOD support ...................disabled"
     fi
     
    +if test x$enable_zlib = xyes; then
    +	echo " zlib support ..................enabled"
    +else
    +	echo " zlib support ..................disabled"
    +fi
    +
    +if test x$enable_bzip2 = xyes; then
    +	echo " bzip2 support .................enabled"
    +else
    +	echo " bzip2 support .................disabled"
    +fi
    +
     if
     	test x$enable_mp3 = xno &&
     	test x$enable_oggvorbis = xno &&
    diff -Naur mpd-0.12.1.orig/src/bunzip2.c mpd-0.12.1/src/bunzip2.c
    --- mpd-0.12.1.orig/src/bunzip2.c	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/bunzip2.c	2006-12-14 02:08:52.000000000 +0200
    @@ -0,0 +1,56 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include "bunzip2.h"
    +
    +#ifdef HAVE_BZIP2
    +
    +#include <bzlib.h>
    +#include <stdlib.h>
    +
    +int bunzip2(char *path, void **data, size_t *size)
    +{
    +	BZFILE* bf;
    +	int nr;
    +
    +	if (!(bf = BZ2_bzopen(path, "rb"))) {
    +		ERROR("unbzip2: not bzip2 file\n");
    +		return 0;
    +	}
    +
    +	*data = NULL;
    +	*size = 0;
    +
    +	for(;;) {
    +		*data = realloc(*data, *size + 2048);
    +		if (!*data) {
    +			ERROR("unbzip2: out of memory\n");
    +			BZ2_bzclose(bf);
    +			return 0;
    +		}
    +		nr = BZ2_bzread(bf, (char *)(*data) + *size, 2048);
    +		if (nr <= 0) break;
    +		*size += nr;
    +	}
    +
    +	BZ2_bzclose(bf);
    +
    +	return 1;
    +}
    +
    +#endif
    diff -Naur mpd-0.12.1.orig/src/bunzip2.h mpd-0.12.1/src/bunzip2.h
    --- mpd-0.12.1.orig/src/bunzip2.h	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/bunzip2.h	2006-12-14 01:17:11.000000000 +0200
    @@ -0,0 +1,30 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include "../config.h"
    +
    +#ifdef HAVE_BZIP2
    +
    +#include <stdlib.h>
    +int bunzip2(char *path, void **data, size_t *size);
    +
    +#else
    +
    +#define bunzip2(path, data, size) 0
    +
    +#endif
    diff -Naur mpd-0.12.1.orig/src/gunzip.c mpd-0.12.1/src/gunzip.c
    --- mpd-0.12.1.orig/src/gunzip.c	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/gunzip.c	2006-12-14 02:08:31.000000000 +0200
    @@ -0,0 +1,230 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include "gunzip.h"
    +
    +#ifdef HAVE_ZLIB
    +
    +#include <zlib.h>
    +#include <stdlib.h>
    +#include <stdio.h>
    +#include <sys/types.h>
    +
    +#define MAGIC_SIZE     2
    +#define MODE_DEFLATE   8
    +
    +#define	GZIP_MAGIC     "\037\213"
    +
    +#define GZIP_MODE      2
    +#define GZIP_FLAGS     3
    +#define GZIP_FLAG_ASCII        0x01 /* bit 0 set: file probably ascii text */
    +#define GZIP_FLAG_HEAD_CRC     0x02 /* bit 1 set: header CRC present */
    +#define GZIP_FLAG_EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
    +#define GZIP_FLAG_ORIG_NAME    0x08 /* bit 3 set: original file name present */
    +#define GZIP_FLAG_COMMENT      0x10 /* bit 4 set: file comment present */
    +#define GZIP_FLAG_RESERVED     0xE0 /* bits 5..7: reserved */
    +
    +#define GZIP_HEADER_SIZE 10
    +#define GZIP_FOOTER_SIZE 8
    +
    +#define PKZIP_MAGIC    "\120\113\003\004" /* Magic header for pkzip files */
    +/* PKZIP header definitions */
    +#define PKZIP_LOCSIG 0x04034b50L      /* four-byte lead-in (lsb first) */
    +#define PKZIP_LOCFLG 6                /* offset of bit flag */
    +#define PKZIP_CRPFLG 1                /*  bit for encrypted entry */
    +#define PKZIP_EXTFLG 8                /*  bit for extended local header */
    +#define PKZIP_LOCHOW 8                /* offset of compression method */
    +#define PKZIP_LOCTIM 10               /* file mod time (for decryption) */
    +#define PKZIP_LOCCRC 14               /* offset of crc */
    +#define PKZIP_LOCSIZ 18               /* offset of compressed size */
    +#define PKZIP_LOCLEN 22               /* offset of uncompressed length */
    +#define PKZIP_LOCFIL 26               /* offset of file name field length */
    +#define PKZIP_LOCEXT 28               /* offset of extra field length */
    +#define PKZIP_LOCHDR 30               /* size of local header, including sig */
    +#define PKZIP_EXTHDR 16               /* size of extended local header, inc sig */
    +#define PKZIP_RAND_HEAD_LEN  12       /* length of encryption random header */
    +
    +/* Macros for getting two-byte and four-byte header values */
    +#define SH(p) ((unsigned short)(unsigned char)((p)[0]) | \
    +        ((unsigned short)(unsigned char)((p)[1]) << 8))
    +#define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16))
    +
    +static int skip_string(FILE *fp)
    +{
    +	char c;
    +
    +	do {
    +		if (fread(&c, 1, 1, fp) != 1)
    +		    return 0;
    +	} while (c != 0);
    +
    +	return 1;
    +}
    +
    +static size_t skip(FILE *fp, size_t num_bytes)
    +{
    +	unsigned char buf[32];
    +	size_t bytes_read;
    +
    +	while (num_bytes != 0) {
    +	    bytes_read = fread(buf, 1,
    +		    (num_bytes > sizeof(buf)) ?
    +		    sizeof(buf) : num_bytes, fp);
    +	    num_bytes -= bytes_read;
    +	    if (bytes_read == 0) return 0;
    +	}
    +
    +	return 1;
    +}
    +
    +static int read_header(FILE *fp)
    +{
    +	unsigned char buffer[100];
    +
    +	if (fread(buffer, MAGIC_SIZE, 1, fp) != 1)
    +		return 0;
    +
    +	if (!memcmp(buffer, GZIP_MAGIC, MAGIC_SIZE)) {
    +		/* gzip format */
    +		unsigned char flags;
    +
    +		if (fread(&buffer[MAGIC_SIZE],
    +			    GZIP_HEADER_SIZE - MAGIC_SIZE,
    +			    1, fp) != 1)
    +			return 0;
    +
    +		if (buffer[GZIP_MODE] != MODE_DEFLATE)
    +			return 0;
    +
    +		flags = buffer[GZIP_FLAGS];
    +
    +		if (flags & GZIP_FLAG_RESERVED)
    +			return 0;
    +
    +		if (flags & GZIP_FLAG_EXTRA_FIELD) {
    +			unsigned char tmp[2];
    +
    +			if (fread(tmp, 2, 1, fp) != 1)
    +				return 0;
    +			if (!skip(fp, tmp[0] | (tmp[0] << 8)))
    +				return 0;
    +		}
    +
    +		if (flags & GZIP_FLAG_ORIG_NAME)
    +			if (!skip_string(fp))
    +				return 0;
    +
    +		if (flags & GZIP_FLAG_COMMENT)
    +			if (!skip_string(fp))
    +				return 0;
    +
    +		if (flags & GZIP_FLAG_HEAD_CRC)
    +			if (!skip(fp, 2))
    +				return 0;
    +
    +		return 1;
    +	}
    +	else if (!memcmp(buffer, PKZIP_MAGIC, MAGIC_SIZE)) {
    +		/* pkzip format */
    +		if (fread(&buffer[MAGIC_SIZE],
    +			    PKZIP_LOCHDR - MAGIC_SIZE, 1, fp) != 1)
    +			return 0;
    +
    +		if (LG(buffer) != PKZIP_LOCSIG)
    +			return 0;
    +		if (buffer[PKZIP_LOCHOW] != MODE_DEFLATE)
    +			return 0;
    +		if (!skip(fp, SH(buffer + PKZIP_LOCFIL)))
    +			return 0;
    +		if (!skip(fp, SH(buffer + PKZIP_LOCEXT)))
    +			return 0;
    +
    +		return 1;
    +	}
    +
    +	return 0;
    +}
    +
    +int gunzip(char *path, void **data, size_t *size)
    +{
    +	int nr, ao, zr;
    +	FILE *fp;
    +	z_stream zs;
    +	unsigned char buf[2048];
    +
    +	if (!(fp = fopen(path, "rb")))
    +		return 0;
    +
    +	if (!read_header(fp)) {
    +		ERROR("gunzip: no gzip file\n");
    +		fclose(fp);
    +		return 0;
    +	}
    +
    +	zs.zalloc = NULL;
    +	zs.zfree = NULL;
    +	zs.opaque = NULL;
    +	zs.avail_in = 0;
    +	zs.avail_out = 0;
    +
    +	if (inflateInit2(&zs, -MAX_WBITS) != Z_OK) {
    +		ERROR("error while initializing zlib\n");
    +		fclose(fp);
    +		return 0;
    +	}
    +
    +	*data = NULL;
    +	*size = 0;
    +
    +	for (;;) {
    +		if (zs.avail_in == 0) {
    +			nr = fread(buf, 1, sizeof(buf), fp);
    +			if (nr <= 0)
    +				break;
    +			zs.next_in = buf;
    +			zs.avail_in = nr;
    +		}
    +
    +		if (zs.avail_out == 0) {
    +			*data = realloc(*data, *size + 2048);
    +			if (!*data)
    +			{
    +				ERROR("gunzip: out of memory\n");
    +				inflateEnd(&zs);
    +				fclose(fp);
    +				return 0;
    +			}
    +			zs.next_out = (char *)(*data) + *size;
    +			zs.avail_out = 2048;
    +		}
    +
    +		ao = zs.avail_out;
    +		zr = inflate(&zs, Z_NO_FLUSH);
    +		*size += ao - zs.avail_out;
    +
    +		if (zr != Z_OK)
    +			break;
    +	}
    +
    +	inflateEnd(&zs);
    +	fclose(fp);
    +
    +	return 1;
    +}
    +
    +#endif
    diff -Naur mpd-0.12.1.orig/src/gunzip.h mpd-0.12.1/src/gunzip.h
    --- mpd-0.12.1.orig/src/gunzip.h	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/gunzip.h	2006-12-14 01:17:40.000000000 +0200
    @@ -0,0 +1,31 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include "../config.h"
    +
    +#ifdef HAVE_ZLIB
    +
    +#include <stdlib.h>
    +
    +int gunzip(char *path, void **data, size_t *size);
    +
    +#else
    +
    +#define gunzip(path, data, size) 0
    +
    +#endif
    diff -Naur mpd-0.12.1.orig/src/inputPlugins/mod_plugin.c mpd-0.12.1/src/inputPlugins/mod_plugin.c
    --- mpd-0.12.1.orig/src/inputPlugins/mod_plugin.c	2006-10-11 02:56:56.000000000 +0300
    +++ mpd-0.12.1/src/inputPlugins/mod_plugin.c	2006-12-14 02:11:00.000000000 +0200
    @@ -25,6 +25,7 @@
     #include "../log.h"
     #include "../pcm_utils.h"
     #include "../playerData.h"
    +#include "../unpack.h"
     
     #include <stdio.h>
     #include <unistd.h>
    @@ -130,6 +131,95 @@
     	MikMod_Exit();
     }
     
    +typedef struct _mod_Buffer {
    +	MREADER reader;
    +	SBYTE *data;
    +	size_t size;
    +	size_t offset;
    +	int eof;
    +} mod_Buffer;
    +
    +static BOOL mod_buf_seek(struct MREADER * reader, long offset, int whence)
    +{
    +	mod_Buffer *b = (mod_Buffer*)(reader);
    +	long new_offset;
    +
    +	switch (whence) {
    +		case SEEK_SET: new_offset = offset; break;
    +		case SEEK_CUR: new_offset = b->offset + offset; break;
    +		case SEEK_END: new_offset = b->size + offset; break;
    +		default: return -1;
    +	}
    +	if (new_offset < 0 || new_offset > b->size)
    +		return -1;
    +
    +	b->offset = new_offset;
    +	b->eof = 0;
    +
    +	return 0;
    +}
    +
    +static long mod_buf_tell(struct MREADER * reader)
    +{
    +	mod_Buffer *b = (mod_Buffer*)(reader);
    +
    +	return b->offset;
    +}
    +  
    +static BOOL mod_buf_read(struct MREADER * reader, void * ptr, size_t size)
    +{
    +	mod_Buffer *b = (mod_Buffer*)(reader);
    +	size_t bytes_read = 0;
    +
    +	if (b->offset + size > b->size) {
    +		bytes_read = b->size - b->offset;
    +		b->eof = 1;
    +	} else bytes_read = size;
    +
    +	memcpy(ptr, b->data + b->offset, bytes_read);
    +	b->offset += bytes_read;
    +
    +	return bytes_read;
    +}
    +
    +static int mod_buf_get(struct MREADER * reader)
    +{
    +	mod_Buffer *b = (mod_Buffer*)(reader);
    +
    +	if (b->offset == b->size) {
    +		b->eof = 1;
    +		return EOF;
    +	}
    +	return (unsigned char)b->data[b->offset++];
    +}
    +
    +static BOOL mod_buf_eof(struct MREADER * reader)
    +{
    +	mod_Buffer *b = (mod_Buffer*)(reader);
    +
    +	return b->eof;
    +}
    +
    +static MODULE *mod_load(char *path, int maxchan, BOOL curious)
    +{
    +	mod_Buffer buf;
    +	MODULE *result;
    +
    +	if (unpack(path, &buf.data, &buf.size)) {
    +		buf.reader.Seek = &mod_buf_seek;
    +		buf.reader.Tell = &mod_buf_tell;
    +		buf.reader.Read = &mod_buf_read;
    +		buf.reader.Get = &mod_buf_get;
    +		buf.reader.Eof = &mod_buf_eof;
    +		result = Player_LoadGeneric((MREADER*)(&buf),
    +			maxchan, curious);
    +		free(buf.data);
    +	} else 
    +		result = Player_Load(path, maxchan, curious);
    +
    +	return result;
    +}
    +
     typedef struct _mod_Data {
     	MODULE *moduleHandle;
     	SBYTE *audio_buffer;
    @@ -140,7 +230,7 @@
     	MODULE *moduleHandle;
     	mod_Data *data;
     
    -	if (!(moduleHandle = Player_Load(path, 128, 0)))
    +	if (!(moduleHandle = mod_load(path, 128, 0)))
     		return NULL;
     
     	data = xmalloc(sizeof(mod_Data));
    @@ -148,6 +238,9 @@
     	data->audio_buffer = xmalloc(MIKMOD_FRAME_SIZE);
     	data->moduleHandle = moduleHandle;
     
    +	data->moduleHandle->loop = 0; /* some modules fall in infinite loop */
    +	data->moduleHandle->wrap = 0; /* so we need to prevent this */
    +
     	Player_Start(data->moduleHandle);
     
     	return data;
    @@ -166,6 +259,7 @@
     	mod_Data *data;
     	float time = 0.0;
     	int ret;
    +	int prev_sngpos;
     	float secPerByte;
     
     	if (mod_initMikMod() < 0)
    @@ -177,6 +271,8 @@
     		return -1;
     	}
     
    +	prev_sngpos = data->moduleHandle->sngpos;
    +
     	dc->audioFormat.bits = 16;
     	dc->audioFormat.sampleRate = 44100;
     	dc->audioFormat.channels = 2;
    @@ -199,6 +295,11 @@
     		if (!Player_Active())
     			break;
     
    +		if (prev_sngpos < data->moduleHandle->sngpos)
    +			prev_sngpos = data->moduleHandle->sngpos;
    +		else if (prev_sngpos > data->moduleHandle->sngpos)
    +			break; /* disable looping any way */
    +
     		ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
     		time += ret * secPerByte;
     		sendDataToOutputBuffer(cb, NULL, dc, 0,
    @@ -225,48 +326,62 @@
     {
     	MpdTag *ret = NULL;
     	MODULE *moduleHandle;
    -	char *title;
    +	char *title = NULL;
     
     	if (mod_initMikMod() < 0) {
     		DEBUG("modTagDup: Failed to initialize MikMod\n");
     		return NULL;
     	}
     
    -	if (!(moduleHandle = Player_Load(file, 128, 0))) {
    +	if (!(moduleHandle = mod_load(file, 128, 0))) {
     		DEBUG("modTagDup: Failed to open file: %s\n", file);
     		MikMod_Exit();
     		return NULL;
     
     	}
    -	Player_Free(moduleHandle);
     
     	ret = newMpdTag();
     
     	ret->time = 0;
    -	title = xstrdup(Player_LoadTitle(file));
    +	if (moduleHandle->songname)
    +		title = xstrdup(moduleHandle->songname);
     	if (title)
     		addItemToMpdTag(ret, TAG_ITEM_TITLE, title);
     
    +	Player_Free(moduleHandle);
    +
     	MikMod_Exit();
     
     	return ret;
     }
     
    -static char *modSuffixes[] = { "amf",
    -	"dsm",
    -	"far",
    -	"gdm",
    -	"imf",
    -	"it",
    -	"med",
    -	"mod",
    -	"mtm",
    -	"s3m",
    -	"stm",
    -	"stx",
    -	"ult",
    -	"uni",
    -	"xm",
    +#define MOD_SUFFIXES(z) \
    +	"669" z, \
    +	"amf" z, \
    +	"dsm" z, \
    +	"far" z, \
    +	"gdm" z, \
    +	"imf" z, \
    +	"it" z, \
    +	"med" z, \
    +	"mod" z, \
    +	"mtm" z, \
    +	"s3m" z, \
    +	"stm" z, \
    +	"stx" z, \
    +	"ult" z, \
    +	"uni" z, \
    +	"xm" z
    +
    +static char *modSuffixes[] = {
    +        MOD_SUFFIXES(""),
    +#ifdef HAVE_ZLIB
    +        MOD_SUFFIXES(".gz"),
    +        MOD_SUFFIXES(".zip"),
    +#endif
    +#ifdef HAVE_BZIP2
    +        MOD_SUFFIXES(".bz2"),
    +#endif
     	NULL
     };
     
    diff -Naur mpd-0.12.1.orig/src/ls.c mpd-0.12.1/src/ls.c
    --- mpd-0.12.1.orig/src/ls.c	2006-10-11 02:56:58.000000000 +0300
    +++ mpd-0.12.1/src/ls.c	2006-12-14 03:48:16.000000000 +0200
    @@ -27,6 +27,7 @@
     #include <dirent.h>
     #include <stdio.h>
     #include <errno.h>
    +#include <string.h>
     
     static char *remoteUrlPrefixes[] = {
     	"http://",
    @@ -215,13 +216,21 @@
     char *getSuffix(char *utf8file)
     {
     	char *ret = NULL;
    +	char *prev = NULL;
     
     	while (*utf8file) {
    -		if (*utf8file == '.')
    +		if (*utf8file == '.') {
    +			prev = ret;
     			ret = utf8file + 1;
    +		}
     		utf8file++;
     	}
     
    +	if (prev && (!strcasecmp(ret, "zip") ||
    +		    !strcasecmp(ret, "gz") ||
    +		    !strcasecmp(ret, "bz2")))
    +		ret = prev;
    +
     	return ret;
     }
     
    diff -Naur mpd-0.12.1.orig/src/Makefile.am mpd-0.12.1/src/Makefile.am
    --- mpd-0.12.1.orig/src/Makefile.am	2006-10-11 02:56:58.000000000 +0300
    +++ mpd-0.12.1/src/Makefile.am	2006-12-14 00:40:01.000000000 +0200
    @@ -29,6 +29,7 @@
     	audio.h \
     	audioOutput.h \
     	buffer2array.h \
    +	bunzip2.h \
     	charConv.h \
     	command.h \
     	conf.h \
    @@ -36,6 +37,7 @@
     	decode.h \
     	directory.h \
     	gcc.h \
    +	gunzip.h \
     	inputPlugin.h \
     	inputPlugins/_flac_common.h \
     	inputPlugins/_ogg_common.h \
    @@ -69,6 +71,7 @@
     	tag.h \
     	tagTracker.h \
     	tree.h \
    +	unpack.h \
     	utf8.h \
     	utils.h \
     	volume.h
    @@ -81,12 +84,14 @@
     	audio.c \
     	audioOutput.c \
     	buffer2array.c \
    +	bunzip2.c \
     	charConv.c \
     	command.c \
     	conf.c \
     	dbUtils.c \
     	decode.c \
     	directory.c \
    +	gunzip.c \
     	inputPlugin.c \
     	inputStream.c \
     	inputStream_file.c \
    @@ -120,6 +125,7 @@
     	tree.c \
     	utils.c \
     	volume.c \
    +	unpack.c \
     	utf8.c
     
     
    diff -Naur mpd-0.12.1.orig/src/unpack.c mpd-0.12.1/src/unpack.c
    --- mpd-0.12.1.orig/src/unpack.c	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/unpack.c	2006-12-14 01:33:14.000000000 +0200
    @@ -0,0 +1,40 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + * 
    + * Unpack file contents from various of archives to memory.
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include "unpack.h"
    +#include "gunzip.h"
    +#include "bunzip2.h"
    +
    +#include <string.h>
    +
    +int unpack(char *path, void **data, size_t *size)
    +{
    +    char *s;
    +
    +    if (!(s = strrchr(path, '.')))
    +	    return 0;
    +
    +    if (!strcasecmp(s, ".gz") || !strcasecmp(s, ".zip"))
    +	    return gunzip(path, data, size);
    +    if (!strcasecmp(s, ".bz2"))
    +	    return bunzip2(path, data, size);
    +
    +    return 0;
    +}
    diff -Naur mpd-0.12.1.orig/src/unpack.h mpd-0.12.1/src/unpack.h
    --- mpd-0.12.1.orig/src/unpack.h	1970-01-01 03:00:00.000000000 +0300
    +++ mpd-0.12.1/src/unpack.h	2006-12-14 00:56:23.000000000 +0200
    @@ -0,0 +1,23 @@
    +/* the Music Player Daemon (MPD)
    + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
    + * This project's homepage is: http://www.musicpd.org
    + *
    + * Unpack file contents from various of archives to memory.
    + * 
    + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + */
    +
    +#include <stdlib.h>
    +
    +int unpack(char *path, void **data, size_t *size);
    
    patch file icon mpd-0.12.1-unpack.patch (25,433 bytes) 2006-12-14 07:48 +
  • gz file icon mpd-archiveapi-preview.tar.gz (46,972 bytes) 2008-11-23 10:30
  • gz file icon mpd-archiveapi-v1.tar.gz (55,506 bytes) 2008-11-27 20:59
  • gz file icon mpd-archiveapi-v2.tar.gz (64,602 bytes) 2008-12-07 16:13

-Relationships
has duplicate 0000454closedAvuton Olrich Adding ZIP-Support for mod-files 
has duplicate 0000566closedcirrus Adding new inputStream into mpd 
+Relationships

-Notes

~0001138

Avuton Olrich (administrator)

lostclus: I'd like to see this patch make it in. Would you please split this patch into two patches, one for each cause? It will probably take a little longer to get the decompression stuff in, but I'd like to get the fix for module infinite loops in now, if possible. Thanks.

~0001143

Avuton Olrich (administrator)

lostclus: Also, Tried adding a mod zip directly from modarchive.org, which didn't initially add to the database, I guess it requires recursive unarchiving. Looks like:

TMA2006-snapshot-1_9.zip

When I ran an update didn't work. When I unzipped it I saw:

1_9/106.xm.zip
...

It did work after this update. Any chance on extending this patch to get something like this working? Thanks again.

~0001144

lostclus (reporter)

Avuton Olrich: please give me a link to the file on modarchive.org that require recursive unarchiving.

~0001145

lostclus (reporter)

Sorry. I have found it in http://tracker.modarchive.org/. So, this is snapshot of entire directory, that contains multiple files. Archives with multiple files is not supported by patch. Only first file will be extracted from multifile zip archive and this file MUST be in one of formats that libmikmod can recognize.

~0001146

Avuton Olrich (administrator)

You didn't respond to the request to split out the patch to

1) fix
2) features

Secondly, that means this patch has /very/ limited audience, to be honest seems like a ton of trouble for no gain, that doesn't mean I'm totally opposed but I'm not left with any reason to go and support it. I just bzip -8 >1000 mods and they hardly compressed in the first place. On the other hand, if it was more general where it would 'find' things such as mp3s in zips, or where I could zip 18,000 mods in a zip (which would keep my disk from allocating alot more space for it then it needs). I just need to understand why I'm going upto bat for a 902 line patch that has very limited functionality, perhaps I'm missing the point? Thanks.

~0001151

lostclus (reporter)

> You didn't respond to the request to split out the patch to
> 1) fix
> 2) features

First, there is http://www.musicpd.org/mantis/view.php?id=1392 but it still
without any attention. Second, I posted in 2004
http://lostclus.linux.kiev.ua/patches/all/mpd-SVN20041115-nomodloops.patch .
Ignored.

> On the other hand, if it was more general where it would 'find' things such
> as mp3s in zips, or where I could zip 18,000 mods in a zip (which would keep
> my disk from allocating alot more space for it then it needs). I just need to
> understand why I'm going upto bat for a 902 line patch that has very limited
> functionality

http://lostclus.linux.kiev.ua/patches/all/mpd-SVN20041115-bzip2.patch .
Rejected in 2004.

~0001153

Avuton Olrich (administrator)

I understand things have gotten ignored in the past. We get busy, things get pushed aside. But everything aside, I'm *trying* to get things done here. I *will* do everything in my power to get this into the trunk. I do have some qualms at the moment though.

I can get the fix imported near-immediately. I can get the feature queued for review, but I need you to work with me here. I can probably even do this stuff myself, but with my limited coding ability it maybe bug worthy and take even longer. I *will* get this into testing at least. I would like to host this on my personal MPD branch. I *have* been testing this for a few days now, myself. What I do need at this point is the attached patch split in

1) Fix
2) Feature

It's going to make it easier to review, easier to sync, and it's really appreciated. If you don't get around to it I may or may not.

So here's the list of things that I need or need to understand.
1) Patch split in two parts.
2) I also see that if --disable-mod configured, bzip2/zip support still gets compiled in. It's be great to see that configured out if mod is disabled, until/unless the compression patch becomes more powerful.
3) It would be *nice* to see a patch from the latest svn.

Please understand this is all appreciated, I will work on getting this included. Thanks!

~0001154

Avuton Olrich (administrator)

Is the patch in 1392 a complete fix for the looping problems, lostclus? Thanks.

~0001170

lostclus (reporter)

English is not my native language, so that I will not speak about all things
that I have. Whether or not this changes will be accepted is all the same for
me. I give you the idea, moreover I give you the code, that even works. Rest is
your matter. If you want, you can simply include this changes as is. If you
want, you can modify it to fit your desires. If you want, you can reject it. I
consider, if you can read and understand program code, then you can spit this
patch into so much pieces as you like without any difficulties. If you can't
(don't want) to read and understand the program code, then we can't understand
one another.

~0002420

metyl (reporter)

Last edited: 2008-11-27 23:21

in my opinon on compression in mpd. compression containerts should be implemented on the inputfile_* / directory level. so that every gz/bz2/zip archive can be transparently scanned for containing files and any decoder then can use the corresponsing feature of taring album files together.

There should be some un/archive api proposal on which we can add future compression methods. I would like to see .zip and .rar support along with unarchive api for mpd proposal. I would like to cooperate on this thema.

from mpd browser point of view an archive should look like directory, for. ex
> On the other hand, if it was more general where it would 'find' things such
> as mp3s in zips, or where I could zip 18,000 mods in a zip (which would keep
> my disk from allocating alot more space for it then it needs). I just need to
> understand why I'm going upto bat for a 902 line patch that has very limited
> functionality
/musicroot/Talco - Combat Circus.zip/Talco/11 - A LA Pachenka.mp3

Free music for free people
http://www.jamendo.com/en/track/39231

~0002421

cirrus (administrator)

metyl: agree. A good API which abstracts this stuff would be great, and could provide an input_stream implementation, as well as enumeration (for database update). Nobody is currently working on that - if you have ideas, please share them - the IRC channel or the developer mailing list would be the best medium for discussion.

~0002424

metyl (reporter)

Last edited: 2008-11-19 21:58

i have written some stuff today, trying to put api together. the main issues are listed here:

1.) archive plugins needs to be stackable. For example on top of gzip/bzip2 plugin can sit tar plugin which lists / reads the files. While this looks easy it also adds a new level of problems (when seeking is imposible, tar plugin needs to read and process all data in stream as it goes).

there could be problem implementing this to work transparently. Imagine, reading files from archive randomly can significally raise load in mpd because whole tar file needs to be decoded (for tar.gz tar.bz2 files)

2.) it looks like compression has no sence at all because music files are generally compressed better. only grouping of multiple files is wanted.

because of this i see sence for implementing support for
.zip .rar .tar containers only when compression is disabled

i made some initial coding without really thinking how big issue this is
going into death end. If anybody interested i'll post patch to git

there is a lot of things todo here

~0002427

cirrus (administrator)

Just a thought: might gnome-vfs be appropriate for us? I don't know it, but maybe it's worth to check.

We don't need to support tarfiles. Like you said, the overhead is huge, since they have no central file listing.

Even supporting compressed zip files could be dropped for simplicity now.

~0002430

metyl (reporter)

Last edited: 2008-11-22 17:12

i'm working currently on simplified design. As for first plugin i'm using unrarlib which supports rar only format v 2.0 (newest winrar is using v3). I've droped tar support and plugin stacking to make it easier and less intrusive to get into master branch.

plan is to make support for zip (via zlib) files possibly any other true archive (with separate extract possibility)

\i'm not familiar with gnome-vfs but it will add too much dependency i think

~0002457

metyl (reporter)

Last edited: 2008-11-27 23:29

-> first preview. Only scanning of archive files (zip, rar, bz2) is working as now. Update of mpd database still incomplete. This is more like a backup until i get more familiar with git

-> first working version. Tag reading is not supported. but playing from .zip and .bz2 (not tarred only bzip2'ed) is fully functional... rar support is implemented but only for v rar v 2.0 format and rar plugin is not tested at all (I cant get old rar packer). For the mod files support, mod plugin needs to implement stream_decode instead of file_decode to finally allow grouping of mod files....

~0002600

metyl (reporter)

-> second working version: some fixes in directory update code, new iso reading plugin

~0002696

Avuton Olrich (administrator)

Fixed in git, thanks for the contribution.
+Notes

-Issue History
Date Modified Username Field Change
2006-12-14 07:48 lostclus New Issue
2006-12-14 07:48 lostclus Status new => assigned
2006-12-14 07:48 lostclus Assigned To => shank
2006-12-14 07:48 lostclus File Added: mpd-0.12.1-unpack.patch
2006-12-19 10:36 Avuton Olrich Assigned To shank => Avuton Olrich
2006-12-19 10:38 Avuton Olrich Note Added: 0001138
2006-12-19 10:38 Avuton Olrich Status assigned => feedback
2006-12-19 10:59 Avuton Olrich Relationship added has duplicate 0000454
2006-12-19 11:18 Avuton Olrich Note Added: 0001143
2006-12-19 14:30 lostclus Note Added: 0001144
2006-12-19 14:42 lostclus Note Added: 0001145
2006-12-21 13:29 Avuton Olrich Note Added: 0001146
2006-12-21 14:16 lostclus Note Added: 0001151
2006-12-21 15:03 Avuton Olrich Note Added: 0001153
2006-12-21 15:17 Avuton Olrich Note Added: 0001154
2006-12-22 22:35 lostclus Note Added: 0001170
2006-12-28 23:28 Avuton Olrich Status feedback => assigned
2006-12-28 23:28 Avuton Olrich Assigned To Avuton Olrich => shank
2008-10-25 19:04 Avuton Olrich Assigned To shank => cirrus
2008-10-25 21:57 Avuton Olrich Category => Other
2008-10-27 11:12 cirrus Priority normal => low
2008-11-19 14:14 metyl Note Added: 0002420
2008-11-19 14:18 metyl Note Edited: 0002420
2008-11-19 14:27 cirrus Note Added: 0002421
2008-11-19 21:56 metyl Note Added: 0002424
2008-11-19 21:57 metyl Note Edited: 0002424
2008-11-19 21:57 metyl Note Edited: 0002424
2008-11-19 21:58 metyl Note Edited: 0002424
2008-11-19 21:58 metyl Note Edited: 0002424
2008-11-20 12:53 cirrus Note Added: 0002427
2008-11-20 12:54 cirrus Assigned To cirrus => metyl
2008-11-20 19:47 metyl Note Added: 0002430
2008-11-20 19:48 metyl Note Edited: 0002430
2008-11-22 17:03 metyl Note Edited: 0002420
2008-11-22 17:12 metyl Note Edited: 0002430
2008-11-23 01:19 Avuton Olrich Relationship added has duplicate 0000566
2008-11-23 10:30 metyl File Added: mpd-archiveapi-preview.tar.gz
2008-11-23 10:34 metyl Note Added: 0002457
2008-11-27 20:59 metyl File Added: mpd-archiveapi-v1.tar.gz
2008-11-27 23:21 metyl Note Edited: 0002420
2008-11-27 23:26 metyl Note Edited: 0002457
2008-11-27 23:27 metyl Note Edited: 0002457
2008-11-27 23:29 metyl Note Edited: 0002457
2008-12-07 16:13 metyl File Added: mpd-archiveapi-v2.tar.gz
2008-12-07 16:14 metyl Note Added: 0002600
2008-12-07 16:14 metyl Tag Attached: archive
2008-12-07 16:15 metyl Tag Attached: zip
2008-12-28 08:01 Avuton Olrich Note Added: 0002696
2008-12-28 08:01 Avuton Olrich Status assigned => resolved
2008-12-28 08:01 Avuton Olrich Fixed in Version => git
2008-12-28 08:01 Avuton Olrich Resolution open => fixed
2009-01-04 16:03 Avuton Olrich Status resolved => closed
+Issue History