|
From: Ben O. <ben...@us...> - 2003-08-03 23:10:45
|
Update of /cvsroot/njbfs/njbfs/mpg123
In directory sc8-pr-cvs1:/tmp/cvs-serv3804
Added Files:
Tag: ben
Makefile README id3.c id3.h id3_frame.c id3_frame_content.c
id3_frame_text.c id3_frame_url.c id3_header.h id3_tag.c
mpg123.c mpg123.h
Log Message:
Ben: add id3 support files
--- NEW FILE: Makefile ---
MYCODEDIR := .
MODULESDIR = /lib/modules/$(shell uname -r)
# Directories to search for header files
SEARCHDIRS := -I- -I${MYCODEDIR} -I/usr/src/linux/include
# makemake variables
DEPENDFLAGS := -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -mpreferred-stack-boundary=2 -Wall ${SEARCHDIRS} -DMODULE -D__KERNEL__ -DLINUX -DEXPORT_SYMTAB
# C preprocessor
CPPFLAGS =
# C compiler
CC := gcc
CFLAGS = ${DEPENDFLAGS} -DDEBUG
%.o : %.c
${CC} ${CPPFLAGS} ${CFLAGS} -c $< -o $@
# C linker
LINKER := ld
LDFLAGS = -m elf_i386 -r
LOADLIBES :=
# target for making everything
.PHONY : all
all: id3.o id3_frame.o id3_frame_content.o id3_frame_text.o id3_frame_url.o id3_tag.o mpg123.o
# list of all source files
MM_ALL_SOURCES := ./automount.c ./nomad.c ./cache.c ./dir.c ./file.c ./inode.c ./proc.c ./symlink.c ./njb_usb.c ./track.c ./playlist.c ./driver.c
# target for checking a source file
CHECKSYNTAXFILE := ${basename ${filter %${CHECKSTRING}, ${MM_ALL_SOURCES}}}
.PHONY : checksyntax
checksyntax:
ifneq (${CHECKSYNTAXFILE},)
@${MAKE} ${addsuffix .o, ${CHECKSYNTAXFILE}}
else
@echo No target to make ${CHECKSTRING}
endif
# target for touching appropriate source files
.PHONY : touch
touch::
@list=$$(grep -l ${TOUCHSTRING} ${MM_ALL_SOURCES}); \
for file in $$list; do { echo $$file; touch $$file; } done
--- NEW FILE: README ---
This is the source liberally stolen and modified to work as a kernel module.
We originally grabbed it from the Inputs/Plugins/mp3 directory in the xmms
source distro. Since the id3v2 source isn't patented (and is GPL'ed), there
shouldn't be any licensing problems.
Note about the mpg123 license!
We have permission to release mpg123 source inside xmms as GPL!
Using mpg123 source (at least in a commercial environment) may infringe 3rd party patents.
Also Michael Hipp (hi...@in...) would like to know if you modify
this sourcecode. Send him an email if you do, he would like to have an eye on external developments.
Happy playing!
--- NEW FILE: id3.c ---
/*********************************************************************
*
* Copyright (C) 1999, 2001, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Modified 2002 Ben Osheroff for integration to njbfs
*
* Filename: id3.c
* Description: Code for accessing ID3 tags.
* Author: Espen Skoglund <es...@st...>
* Created at: Fri Feb 5 23:55:13 1999
*
* $Id: id3.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include "id3.h"
#include "id3_header.h"
/*
**
** Functions for accessing the ID3 tag using a memory pointer.
**
*/
/*
* Function id3_seek_mem (id3, offset)
*
* Seek `offset' bytes forward in the indicated ID3-tag. Return 0
* upon success, or -1 if an error occured.
*
*/
static int id3_seek_mem(id3_t * id3, int offset)
{
if (id3->id3_pos + offset > id3->id3_tagsize ||
id3->id3_pos + offset < 0) {
id3_error(id3, "seeking beyond tag boundary");
return -1;
}
id3->s.me.id3_ptr = (char *) id3->s.me.id3_ptr + offset;
id3->id3_pos += offset;
return 0;
}
/*
* Function id3_read_mem (id3, buf, size)
*
* Read `size' bytes from indicated ID3-tag. If `buf' is non-NULL,
* read into that buffer. Return a pointer to the data which was
* read, or NULL upon error.
*
*/
static void *id3_read_mem(id3_t * id3, void *buf, int size)
{
void *ret = id3->s.me.id3_ptr;
/*
* Check boundary.
*/
if (id3->id3_pos + size > id3->id3_tagsize) {
size = id3->id3_tagsize - id3->id3_pos;
}
/*
* If buffer is non-NULL, we have to copy the data.
*/
if (buf != NULL)
memcpy(buf, id3->s.me.id3_ptr, size);
/*
* Update memory pointer.
*/
id3->s.me.id3_ptr = (char *) id3->s.me.id3_ptr + size;
id3->id3_pos += size;
return ret;
}
/*
* Function id3_open_mem (ptr, flags)
*
* Open an ID3 tag using a memory pointer. Return a pointer to a
* structure describing the ID3 tag, or NULL if an error occured.
*
*/
id3_t *id3_open_mem(void *ptr, int flags)
{
id3_t *id3;
/*
* Allocate ID3 structure.
*/
id3 = kmalloc(sizeof(id3_t), GFP_KERNEL);
memset(id3, 0, sizeof(id3_t));
/*
* Initialize access pointers.
*/
id3->id3_seek = id3_seek_mem;
id3->id3_read = id3_read_mem;
id3->id3_oflags = flags;
id3->id3_type = ID3_TYPE_MEM;
id3->id3_pos = 0;
id3->s.me.id3_ptr = ptr;
/*
* Try reading ID3 tag.
*/
if (id3_read_tag(id3) == -1) {
if (~flags & ID3_OPENF_CREATE)
goto Return_NULL;
id3_init_tag(id3);
}
return id3;
Return_NULL:
kfree(id3);
return NULL;
}
/*
* Function id3_close (id3)
*
* Free all resources assoicated with the ID3 tag.
*
*/
int id3_close(id3_t * id3)
{
id3_destroy_frames(id3);
kfree(id3);
return 0;
}
/*
* Function id3_tell (id3)
*
* Return the current position in ID3 tag. This will always be
* directly after the tag.
*
*/
int id3_tell(id3_t * id3)
{
if (id3->id3_newtag) {
return 0;
} else {
return id3->id3_tagsize + 3 + sizeof(id3_taghdr_t);
}
}
/*
* Function id3_alter_file (id3)
*
* When altering a file, some ID3 tags should be discarded. As the ID3
* library has no means of knowing when a file has been altered
* outside of the library, this function must be called manually
* whenever the file is altered.
*
*/
int id3_alter_file(id3_t * id3)
{
/*
* List of frame classes that should be discarded whenever the
* file is altered.
*/
static uint32_t discard_list[] = {
ID3_ETCO, ID3_EQUA, ID3_MLLT, ID3_POSS, ID3_SYLT,
ID3_SYTC, ID3_RVAD, ID3_TENC, ID3_TLEN, ID3_TSIZ,
0
};
id3_frame_t *fr;
uint32_t id, i = 0;
/*
* Go through list of frame types that should be discarded.
*/
while ((id = discard_list[i++]) != 0) {
/*
* Discard all frames of that type.
*/
while ((fr = id3_get_frame(id3, id, 1))) {
id3_delete_frame(fr);
}
}
return 0;
}
EXPORT_SYMBOL(id3_open_mem);
--- NEW FILE: id3.h ---
/*********************************************************************
*
* Copyright (C) 1998, 1999, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3.h
* Description: Include file for accessing the ID3 library.
* Author: Espen Skoglund <es...@st...>
* Created at: Thu Nov 5 15:55:10 1998
*
* $Id: id3.h,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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.
*
********************************************************************/
#ifndef ID3_H
#define ID3_H
#include <linux/list.h>
#include <linux/types.h>
/*
* Option flags to id3_open_*().
*/
#define ID3_OPENF_NONE 0x0000
#define ID3_OPENF_NOCHK 0x0001
#define ID3_OPENF_CREATE 0x0002
/*
* The size of the read buffer used by file operations.
*/
#define ID3_FD_BUFSIZE 8192
typedef struct id3_t id3_t;
typedef struct id3_frame_t id3_frame_t;
typedef struct id3_framedesc_t id3_framedesc_t;
/*
* Structure describing the ID3 tag.
*/
struct id3_t {
int id3_type; /* Memory or file desriptor */
int id3_oflags; /* Flags from open call */
int id3_flags; /* Flags from tag header */
int id3_altered; /* Set when tag has been altered */
int id3_newtag; /* Set if this is a new tag */
int id3_version; /* Major ID3 version number */
int id3_revision; /* ID3 revision number */
int id3_tagsize; /* Total size of ID3 tag */
int id3_pos; /* Current position within tag */
char *id3_error_msg; /* Last error message */
char id3_buffer[256]; /* Used for various strings */
union {
/*
* Memory specific fields.
*/
struct {
void *id3_ptr;
} me;
} s;
/*
* Functions for doing operations within ID3 tag.
*/
int (*id3_seek) (id3_t *, int);
void *(*id3_read) (id3_t *, void *, int);
/*
* Linked list of ID3 frames.
*/
struct list_head id3_frame;
};
#define ID3_TYPE_NONE 0
#define ID3_TYPE_MEM 1
#define ID3_TYPE_FD 2
#define ID3_TYPE_FP 3
/*
* Structure describing an ID3 frame.
*/
struct id3_frame_t {
struct list_head fr_list;
id3_t *fr_owner;
id3_framedesc_t *fr_desc;
int fr_flags;
unsigned char fr_encryption;
unsigned char fr_grouping;
unsigned char fr_altered;
void *fr_data; /* Pointer to frame data, excluding headers */
int fr_size; /* Size of uncompressed frame */
void *fr_raw_data; /* Frame data */
int fr_raw_size; /* Frame size */
void *fr_data_z; /* The decompressed compressed frame */
int fr_size_z; /* Size of decompressed compressed frame */
};
/*
* Structure describing an ID3 frame type.
*/
struct id3_framedesc_t {
uint32_t fd_id;
char fd_idstr[4];
char *fd_description;
};
/*
* Text encodings.
*/
#define ID3_ENCODING_ISO_8859_1 0x00
#define ID3_ENCODING_UTF16 0x01
#define ID3_ENCODING_UTF16BE 0x02
#define ID3_ENCODING_UTF8 0x03
/*
* ID3 frame id numbers.
*/
#define ID3_FRAME_ID(a,b,c,d) ((a << 24) | (b << 16) | (c << 8) | d)
#define ID3_AENC ID3_FRAME_ID('A','E','N','C')
#define ID3_APIC ID3_FRAME_ID('A','P','I','C')
#define ID3_COMM ID3_FRAME_ID('C','O','M','M')
#define ID3_COMR ID3_FRAME_ID('C','O','M','R')
#define ID3_ENCR ID3_FRAME_ID('E','N','C','R')
#define ID3_EQUA ID3_FRAME_ID('E','Q','U','A')
#define ID3_ETCO ID3_FRAME_ID('E','T','C','O')
#define ID3_GEOB ID3_FRAME_ID('G','E','O','B')
#define ID3_GRID ID3_FRAME_ID('G','R','I','D')
#define ID3_IPLS ID3_FRAME_ID('I','P','L','S')
#define ID3_LINK ID3_FRAME_ID('L','I','N','K')
#define ID3_MCDI ID3_FRAME_ID('M','C','D','I')
#define ID3_MLLT ID3_FRAME_ID('M','L','L','T')
#define ID3_OWNE ID3_FRAME_ID('O','W','N','E')
#define ID3_PRIV ID3_FRAME_ID('P','R','I','V')
#define ID3_PCNT ID3_FRAME_ID('P','C','N','T')
#define ID3_POPM ID3_FRAME_ID('P','O','P','M')
#define ID3_POSS ID3_FRAME_ID('P','O','S','S')
#define ID3_RBUF ID3_FRAME_ID('R','B','U','F')
#define ID3_RVAD ID3_FRAME_ID('R','V','A','D')
#define ID3_RVRB ID3_FRAME_ID('R','V','R','B')
#define ID3_SYLT ID3_FRAME_ID('S','Y','L','T')
#define ID3_SYTC ID3_FRAME_ID('S','Y','T','C')
#define ID3_TALB ID3_FRAME_ID('T','A','L','B')
#define ID3_TBPM ID3_FRAME_ID('T','B','P','M')
#define ID3_TCOM ID3_FRAME_ID('T','C','O','M')
#define ID3_TCON ID3_FRAME_ID('T','C','O','N')
#define ID3_TCOP ID3_FRAME_ID('T','C','O','P')
#define ID3_TDAT ID3_FRAME_ID('T','D','A','T')
#define ID3_TDLY ID3_FRAME_ID('T','D','L','Y')
#define ID3_TENC ID3_FRAME_ID('T','E','N','C')
#define ID3_TEXT ID3_FRAME_ID('T','E','X','T')
#define ID3_TFLT ID3_FRAME_ID('T','F','L','T')
#define ID3_TIME ID3_FRAME_ID('T','I','M','E')
#define ID3_TIT1 ID3_FRAME_ID('T','I','T','1')
#define ID3_TIT2 ID3_FRAME_ID('T','I','T','2')
#define ID3_TIT3 ID3_FRAME_ID('T','I','T','3')
#define ID3_TKEY ID3_FRAME_ID('T','K','E','Y')
#define ID3_TLAN ID3_FRAME_ID('T','L','A','N')
#define ID3_TLEN ID3_FRAME_ID('T','L','E','N')
#define ID3_TMED ID3_FRAME_ID('T','M','E','D')
#define ID3_TOAL ID3_FRAME_ID('T','O','A','L')
#define ID3_TOFN ID3_FRAME_ID('T','O','F','N')
#define ID3_TOLY ID3_FRAME_ID('T','O','L','Y')
#define ID3_TOPE ID3_FRAME_ID('T','O','P','E')
#define ID3_TORY ID3_FRAME_ID('T','O','R','Y')
#define ID3_TOWN ID3_FRAME_ID('T','O','W','N')
#define ID3_TPE1 ID3_FRAME_ID('T','P','E','1')
#define ID3_TPE2 ID3_FRAME_ID('T','P','E','2')
#define ID3_TPE3 ID3_FRAME_ID('T','P','E','3')
#define ID3_TPE4 ID3_FRAME_ID('T','P','E','4')
#define ID3_TPOS ID3_FRAME_ID('T','P','O','S')
#define ID3_TPUB ID3_FRAME_ID('T','P','U','B')
#define ID3_TRCK ID3_FRAME_ID('T','R','C','K')
#define ID3_TRDA ID3_FRAME_ID('T','R','D','A')
#define ID3_TRSN ID3_FRAME_ID('T','R','S','N')
#define ID3_TRSO ID3_FRAME_ID('T','R','S','O')
#define ID3_TSIZ ID3_FRAME_ID('T','S','I','Z')
#define ID3_TSRC ID3_FRAME_ID('T','S','R','C')
#define ID3_TSSE ID3_FRAME_ID('T','S','S','E')
#define ID3_TYER ID3_FRAME_ID('T','Y','E','R')
#define ID3_TXXX ID3_FRAME_ID('T','X','X','X')
#define ID3_UFID ID3_FRAME_ID('U','F','I','D')
#define ID3_USER ID3_FRAME_ID('U','S','E','R')
#define ID3_USLT ID3_FRAME_ID('U','S','L','T')
#define ID3_WCOM ID3_FRAME_ID('W','C','O','M')
#define ID3_WCOP ID3_FRAME_ID('W','C','O','P')
#define ID3_WOAF ID3_FRAME_ID('W','O','A','F')
#define ID3_WOAR ID3_FRAME_ID('W','O','A','R')
#define ID3_WOAS ID3_FRAME_ID('W','O','A','S')
#define ID3_WORS ID3_FRAME_ID('W','O','R','S')
#define ID3_WPAY ID3_FRAME_ID('W','P','A','Y')
#define ID3_WPUB ID3_FRAME_ID('W','P','U','B')
#define ID3_WXXX ID3_FRAME_ID('W','X','X','X')
/*
* Prototypes.
*/
/* From id3.c */
id3_t *id3_open_mem(void *, int);
int id3_set_output(id3_t *, char *);
int id3_close(id3_t *);
int id3_tell(id3_t *);
int id3_alter_file(id3_t *);
int id3_write_tag(id3_t *, int);
/* From id3_frame.c */
int id3_read_frame(id3_t * id3);
id3_frame_t *id3_get_frame(id3_t *, uint32_t, int);
int id3_delete_frame(id3_frame_t * frame);
id3_frame_t *id3_add_frame(id3_t *, uint32_t);
int id3_decompress_frame(id3_frame_t *);
void id3_destroy_frames(id3_t * id);
void id3_frame_clear_data(id3_frame_t * frame);
/* From id3_frame_text.c */
int8_t id3_get_encoding(id3_frame_t *);
int id3_set_encoding(id3_frame_t *, int8_t);
char *id3_get_text(id3_frame_t *);
char *id3_get_text_desc(id3_frame_t *);
int id3_get_text_number(id3_frame_t *);
int id3_set_text(id3_frame_t *, char *);
int id3_set_text_number(id3_frame_t *, int);
int id3_frame_is_text(id3_frame_t *);
/* From id3_frame_content.c */
char *id3_get_content(id3_frame_t *);
/* From id3_frame_url.c */
char *id3_get_url(id3_frame_t *);
char *id3_get_url_desc(id3_frame_t *);
/* From id3_tag.c */
void id3_init_tag(id3_t * id3);
int id3_read_tag(id3_t * id3);
#endif /* ID3_H */
--- NEW FILE: id3_frame.c ---
/*********************************************************************
*
* Copyright (C) 1999-2000, 2001, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3_frame.c
* Description: Code for handling ID3 frames.
* Author: Espen Skoglund <es...@st...>
* Created at: Fri Feb 5 23:47:08 1999
*
* $Id: id3_frame.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/list.h>
#include "id3.h"
#include "id3_header.h"
static void *id3_frame_get_dataptr(id3_frame_t * frame);
static int id3_frame_get_size(id3_frame_t * frame);
/*
* Description of all valid ID3v2 frames.
*/
static id3_framedesc_t Framedesc[] = {
{ID3_AENC, "AENC", "Audio encryption"},
{ID3_APIC, "APIC", "Attached picture"},
{ID3_COMM, "COMM", "Comments"},
{ID3_COMR, "COMR", "Commercial frame"},
{ID3_ENCR, "ENCR", "Encryption method registration"},
{ID3_EQUA, "EQUA", "Equalization"},
{ID3_ETCO, "ETCO", "Event timing codes"},
{ID3_GEOB, "GEOB", "General encapsulated object"},
{ID3_GRID, "GRID", "Group identification registration"},
{ID3_IPLS, "IPLS", "Involved people list"},
{ID3_LINK, "LINK", "Linked information"},
{ID3_MCDI, "MCDI", "Music CD identifier"},
{ID3_MLLT, "MLLT", "MPEG location lookup table"},
{ID3_OWNE, "OWNE", "Ownership frame"},
{ID3_PRIV, "PRIV", "Private frame"},
{ID3_PCNT, "PCNT", "Play counter"},
{ID3_POPM, "POPM", "Popularimeter"},
{ID3_POSS, "POSS", "Position synchronisation frame"},
{ID3_RBUF, "RBUF", "Recommended buffer size"},
{ID3_RVAD, "RVAD", "Relative volume adjustment"},
{ID3_RVRB, "RVRB", "Reverb"},
{ID3_SYLT, "SYLT", "Synchronized lyric/text"},
{ID3_SYTC, "SYTC", "Synchronized tempo codes"},
{ID3_TALB, "TALB", "Album/Movie/Show title"},
{ID3_TBPM, "TBPM", "BPM (beats per minute)"},
{ID3_TCOM, "TCOM", "Composer"},
{ID3_TCON, "TCON", "Content type"},
{ID3_TCOP, "TCOP", "Copyright message"},
{ID3_TDAT, "TDAT", "Date"},
{ID3_TDLY, "TDLY", "Playlist delay"},
{ID3_TENC, "TENC", "Encoded by"},
{ID3_TEXT, "TEXT", "Lyricist/Text writer"},
{ID3_TFLT, "TFLT", "File type"},
{ID3_TIME, "TIME", "Time"},
{ID3_TIT1, "TIT1", "Content group description"},
{ID3_TIT2, "TIT2", "Title/songname/content description"},
{ID3_TIT3, "TIT3", "Subtitle/Description refinement"},
{ID3_TKEY, "TKEY", "Initial key"},
{ID3_TLAN, "TLAN", "Language(s)"},
{ID3_TLEN, "TLEN", "Length"},
{ID3_TMED, "TMED", "Media type"},
{ID3_TOAL, "TOAL", "Original album/movie/show title"},
{ID3_TOFN, "TOFN", "Original filename"},
{ID3_TOLY, "TOLY", "Original lyricist(s)/text writer(s)"},
{ID3_TOPE, "TOPE", "Original artist(s)/performer(s)"},
{ID3_TORY, "TORY", "Original release year"},
{ID3_TOWN, "TOWN", "File owner/licensee"},
{ID3_TPE1, "TPE1", "Lead performer(s)/Soloist(s)"},
{ID3_TPE2, "TPE2", "Band/orchestra/accompaniment"},
{ID3_TPE3, "TPE3", "Conductor/performer refinement"},
{ID3_TPE4, "TPE4", "Interpreted, remixed, or otherwise modified by"},
{ID3_TPOS, "TPOS", "Part of a set"},
{ID3_TPUB, "TPUB", "Publisher"},
{ID3_TRCK, "TRCK", "Track number/Position in set"},
{ID3_TRDA, "TRDA", "Recording dates"},
{ID3_TRSN, "TRSN", "Internet radio station name"},
{ID3_TRSO, "TRSO", "Internet radio station owner"},
{ID3_TSIZ, "TSIZ", "Size"},
{ID3_TSRC, "TSRC", "ISRC (international standard recording code)"},
{ID3_TSSE, "TSSE",
"Software/Hardware and settings used for encoding"},
{ID3_TYER, "TYER", "Year"},
{ID3_TXXX, "TXXX", "User defined text information frame"},
{ID3_UFID, "UFID", "Unique file identifier"},
{ID3_USER, "USER", "Terms of use"},
{ID3_USLT, "USLT", "Unsychronized lyric/text transcription"},
{ID3_WCOM, "WCOM", "Commercial information"},
{ID3_WCOP, "WCOP", "Copyright/Legal information"},
{ID3_WOAF, "WOAF", "Official audio file webpage"},
{ID3_WOAR, "WOAR", "Official artist/performer webpage"},
{ID3_WOAS, "WOAS", "Official audio source webpage"},
{ID3_WORS, "WORS", "Official internet radio station homepage"},
{ID3_WPAY, "WPAY", "Payment"},
{ID3_WPUB, "WPUB", "Publishers official webpage"},
{ID3_WXXX, "WXXX", "User defined URL link frame"},
};
/*
* Function id3_read_frame (id3)
*
* Read next frame from the indicated ID3 tag. Return 0 upon
* success, or -1 if an error occured.
*
*/
int id3_read_frame(id3_t * id3)
{
id3_framehdr_t *framehdr;
id3_frame_t *frame;
uint32_t id;
void *p;
int i;
/*
* Read frame header.
*/
framehdr = id3->id3_read(id3, NULL, sizeof(*framehdr));
if (framehdr == NULL) {
printk("error reading the frame header.\n");
return -1;
}
/*
* If we encounter an invalid frame id, we assume that there is
* some padding in the header. We just skip the rest of the ID3
* tag.
*/
i = *((uint8_t *) &framehdr->fh_id);
if (!((i >= '0' && i <= '9') || (i >= 'A' && i <= 'Z'))) {
id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos);
return 0;
}
id = be32_to_cpu(framehdr->fh_id);
/*
* Allocate frame.
*/
frame = kmalloc(sizeof(*frame), GFP_KERNEL);
memset(frame, 0, sizeof(*frame));
frame->fr_owner = id3;
frame->fr_raw_size = be32_to_cpu(framehdr->fh_size);
frame->fr_flags = be16_to_cpu(framehdr->fh_flags);
/*
* Determine the type of the frame.
*/
for (i = 0; i < sizeof(Framedesc) / sizeof(id3_framedesc_t); i++) {
if (Framedesc[i].fd_id == id) {
/*
* Initialize frame.
*/
frame->fr_desc = Framedesc + i;
/*
* When allocating memory to hold a text frame, we
* allocate 2 extra byte. This simplifies retrieval of
* text strings.
*/
frame->fr_raw_data = kmalloc(frame->fr_raw_size +
(id3_frame_is_text
(frame) ? 2 : 0),
GFP_KERNEL);
p =
id3->id3_read(id3, frame->fr_raw_data,
frame->fr_raw_size);
if (p == NULL) {
kfree(frame->fr_raw_data);
kfree(frame);
return -1;
}
/*
* Null-terminate text frames.
*/
if (id3_frame_is_text(frame)) {
((char *) frame->fr_raw_data)[frame->fr_raw_size]
= 0;
((char *) frame->fr_raw_data)[frame->fr_raw_size
+ 1] = 0;
}
break;
}
}
/*
* Check if frame had a valid id.
*/
if (frame->fr_desc == NULL) {
/*
* No. Ignore the frame.
*/
if (id3->id3_seek(id3, frame->fr_raw_size) < 0) {
printk("Invalid frame id: %d\n", id);
kfree(frame);
return -1;
}
return 0;
}
/*
* Check if frame is compressed using zlib.
*/
if (frame->fr_flags & ID3_FHFLAG_COMPRESS)
return 0;
frame->fr_data = id3_frame_get_dataptr(frame);
frame->fr_size = id3_frame_get_size(frame);
/*
* Insert frame into linked list.
*/
list_add(&frame->fr_list, &id3->id3_frame);
return 0;
}
/*
* Function id3_get_frame (id3, type, num)
*
* Search in the list of frames for the ID3-tag, and return a frame
* of the indicated type. If tag contains several frames of the
* indicated type, the third argument tells which of the frames to
* return.
*
*/
id3_frame_t *id3_get_frame(id3_t * id3, uint32_t type, int num)
{
struct list_head *node;
list_for_each(node, &id3->id3_frame) {
id3_frame_t *fr = list_entry(node, id3_frame_t, fr_list);
if (fr->fr_desc && fr->fr_desc->fd_id == type) {
if (--num <= 0)
return fr;
}
}
return NULL;
}
/*
* Function decompress_frame(frame)
*
* Uncompress the indicated frame. Return 0 upon success, or -1 if
* an error occured.
*
*/
static int decompress_frame(id3_frame_t * frame)
{
return -1;
}
/*
* Function id3_decompress_frame(frame)
*
* Check if frame is compressed, and uncompress if necessary.
* Return 0 upon success, or -1 if an error occured.
*
*/
int id3_decompress_frame(id3_frame_t * frame)
{
if (!(frame->fr_flags & ID3_FHFLAG_COMPRESS))
/* Frame not compressed */
return 0;
if (frame->fr_data_z)
/* Frame already decompressed */
return 0;
/* Do decompression */
return decompress_frame(frame);
}
/*
* Function id3_delete_frame (frame)
*
* Remove frame from ID3 tag and release memory ocupied by it.
*
*/
int id3_delete_frame(id3_frame_t * frame)
{
struct list_head *node,
*head = &frame->fr_owner->id3_frame,
*match = &frame->fr_list, *found = NULL;
int ret;
/*
* Search for frame in list.
*/
list_for_each(node, head) {
if (node == match) {
found = node;
break;
}
}
/*
* Remove frame from frame list.
*/
if (!found)
return -1;
list_del(found);
frame->fr_owner->id3_altered = 1;
ret = 0;
/*
* Release memory occupied by frame.
*/
if (frame->fr_raw_data)
kfree(frame->fr_raw_data);
if (frame->fr_data_z)
kfree(frame->fr_data_z);
kfree(frame);
return ret;
}
/*
* Function id3_add_frame (id3, type)
*
* Add a new frame to the ID3 tag. Return a pointer to the new
* frame, or NULL if an error occured.
*
*/
id3_frame_t *id3_add_frame(id3_t * id3, uint32_t type)
{
id3_frame_t *frame;
int i;
/*
* Allocate frame.
*/
frame = kmalloc(sizeof(*frame), GFP_KERNEL);
memset(frame, 0, sizeof(*frame));
/*
* Initialize frame
*/
frame->fr_owner = id3;
/*
* Try finding the correct frame descriptor.
*/
for (i = 0; i < sizeof(Framedesc) / sizeof(id3_framedesc_t); i++) {
if (Framedesc[i].fd_id == type) {
frame->fr_desc = &Framedesc[i];
break;
}
}
/*
* Insert frame into linked list.
*/
list_add(&frame->fr_list, &id3->id3_frame);
id3->id3_altered = 1;
return frame;
}
/*
* Destroy all frames in an id3 tag, and free all data
*/
void id3_destroy_frames(id3_t * id)
{
struct list_head *node, *tmp;
list_for_each_safe(node, tmp, &id->id3_frame) {
id3_frame_t *frame =
list_entry(node, id3_frame_t, fr_list);
/*
* Release memory occupied by frame.
*/
if (frame->fr_raw_data)
kfree(frame->fr_raw_data);
if (frame->fr_data_z)
kfree(frame->fr_data_z);
kfree(frame);
}
}
int id3_frame_is_text(id3_frame_t * frame)
{
if (frame && frame->fr_desc &&
(frame->fr_desc->fd_idstr[0] == 'T' ||
frame->fr_desc->fd_idstr[0] == 'W'))
return 1;
return 0;
}
static int id3_frame_extra_headers(id3_frame_t * frame)
{
int retv = 0;
/*
* If frame is encrypted, we have four extra bytes in the
* header.
*/
if (frame->fr_flags & ID3_FHFLAG_COMPRESS)
retv += 4;
/*
* If frame is encrypted, we have one extra byte in the
* header.
*/
if (frame->fr_flags & ID3_FHFLAG_ENCRYPT)
retv += 1;
/*
* If frame has grouping identity, we have one extra byte in
* the header.
*/
if (frame->fr_flags & ID3_FHFLAG_GROUP)
retv += 1;
return retv;
}
static void *id3_frame_get_dataptr(id3_frame_t * frame)
{
char *ptr = frame->fr_raw_data;
ptr += id3_frame_extra_headers(frame);
return ptr;
}
static int id3_frame_get_size(id3_frame_t * frame)
{
return frame->fr_raw_size - id3_frame_extra_headers(frame);
}
void id3_frame_clear_data(id3_frame_t * frame)
{
if (frame->fr_raw_data)
kfree(frame->fr_raw_data);
if (frame->fr_data_z)
kfree(frame->fr_data_z);
frame->fr_raw_data = NULL;
frame->fr_raw_size = 0;
frame->fr_data = NULL;
frame->fr_size = 0;
frame->fr_data_z = NULL;
frame->fr_size_z = 0;
}
EXPORT_SYMBOL(id3_read_frame);
EXPORT_SYMBOL(id3_get_frame);
EXPORT_SYMBOL(id3_delete_frame);
--- NEW FILE: id3_frame_content.c ---
/*********************************************************************
*
* Copyright (C) 1999, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3_frame_content.c
* Description: Code for handling ID3 content frames.
* Author: Espen Skoglund <es...@st...>
* Created at: Mon Feb 8 17:13:46 1999
*
* $Id: id3_frame_content.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include <linux/string.h>
#include "mpg123.h"
#include "id3.h"
/*
* Function id3_get_content (frame)
*
* Expand content type string of frame and return it. Return NULL
* upon error.
*
*/
char *id3_get_content(id3_frame_t * frame)
{
char *text, *ptr;
char *buffer = frame->fr_owner->id3_buffer;
int spc = sizeof(frame->fr_owner->id3_buffer) - 1;
/* Type check */
if (frame->fr_desc->fd_id != ID3_TCON)
return NULL;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return NULL;
text = (char *) frame->fr_data + 1;
/*
* If content is just plain text, return it.
*/
if (text[0] != '(')
return text;
/*
* Expand ID3v1 genre numbers.
*/
ptr = buffer;
while (text[0] == '(' && text[1] != '(' && spc > 0) {
char *genre;
int num = 0;
if (text[1] == 'R' && text[2] == 'X') {
text += 4;
genre = " (Remix)";
if (ptr == buffer)
genre++;
} else if (text[1] == 'C' && text[2] == 'R') {
text += 4;
genre = " (Cover)";
if (ptr == buffer)
genre++;
} else {
/* Get ID3v1 genre number */
text++;
while (*text != ')') {
num *= 10;
num += *text++ - '0';
}
text++;
/* Boundary check */
if (num >=
sizeof(mpg123_id3_genres) /
sizeof(char *))continue;
genre = (char *) mpg123_id3_genres[num];
if (ptr != buffer && spc-- > 0)
*ptr++ = '/';
}
/* Expand string into buffer */
while (*genre != '\0' && spc > 0) {
*ptr++ = *genre++;
spc--;
}
}
/*
* Add plaintext refinement.
*/
if (*text == '(')
text++;
if (*text != '\0' && ptr != buffer && spc-- > 0)
*ptr++ = ' ';
while (*text != '\0' && spc > 0) {
*ptr++ = *text++;
spc--;
}
*ptr = '\0';
/*
* Return the expanded content string.
*/
return buffer;
}
--- NEW FILE: id3_frame_text.c ---
/*********************************************************************
*
* Copyright (C) 1999, 2001, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3_frame_text.c
* Description: Code for handling ID3 text frames.
* Author: Espen Skoglund <es...@st...>
* Created at: Fri Feb 5 23:50:33 1999
*
* $Id: id3_frame_text.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "id3.h"
#include "id3_header.h"
/*
* Function id3_get_encoding (frame)
*
* Return text encoding for frame, or -1 if frame does not have any
* text encoding.
*
*/
int8_t id3_get_encoding(id3_frame_t * frame)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T' &&
frame->fr_desc->fd_id != ID3_WXXX &&
frame->fr_desc->fd_id != ID3_IPLS &&
frame->fr_desc->fd_id != ID3_USLT &&
frame->fr_desc->fd_id != ID3_SYLT &&
frame->fr_desc->fd_id != ID3_COMM &&
frame->fr_desc->fd_id != ID3_APIC &&
frame->fr_desc->fd_id != ID3_GEOB &&
frame->fr_desc->fd_id != ID3_USER &&
frame->fr_desc->fd_id != ID3_OWNE &&
frame->fr_desc->fd_id != ID3_COMR) return -1;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return -1;
return *(uint8_t *) frame->fr_data;
}
/*
* Function id3_set_encoding (frame, encoding)
*
* Set text encoding for frame. Return 0 upon success, or -1 if an
* error occured.
*
*/
int id3_set_encoding(id3_frame_t * frame, int8_t encoding)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T' &&
frame->fr_desc->fd_id != ID3_WXXX &&
frame->fr_desc->fd_id != ID3_IPLS &&
frame->fr_desc->fd_id != ID3_USLT &&
frame->fr_desc->fd_id != ID3_SYLT &&
frame->fr_desc->fd_id != ID3_COMM &&
frame->fr_desc->fd_id != ID3_APIC &&
frame->fr_desc->fd_id != ID3_GEOB &&
frame->fr_desc->fd_id != ID3_USER &&
frame->fr_desc->fd_id != ID3_OWNE &&
frame->fr_desc->fd_id != ID3_COMR) return -1;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return -1;
/* Changing the encoding of frames is not supported yet */
if (*(uint8_t *) frame->fr_data != encoding)
return -1;
/* Set encoding */
*(uint8_t *) frame->fr_data = encoding;
return 0;
}
/*
* Function id3_get_text (frame)
*
* Return string contents of frame.
*
*/
char *id3_get_text(id3_frame_t * frame)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T')
return NULL;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return NULL;
if (frame->fr_desc->fd_id == ID3_TXXX) {
/*
* This is a user defined text frame. Skip the description.
*/
switch (*(uint8_t *) frame->fr_data) {
case ID3_ENCODING_ISO_8859_1:
{
char *text = (char *) frame->fr_data + 1;
while (*text != 0)
text++;
return ++text;
}
case ID3_ENCODING_UTF16:
{
int16_t *text16 =
(int16_t *) ((int) frame->fr_data + 1);
while (*text16 != 0)
text16++;
return (char *) ++text16;
}
default:
return NULL;
}
}
return (char *) frame->fr_data + 1;
}
/*
* Function id3_get_text_desc (frame)
*
* Get description part of a text frame.
*
*/
char *id3_get_text_desc(id3_frame_t * frame)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T')
return NULL;
/* If predefined text frame, return description. */
if (frame->fr_desc->fd_id != ID3_TXXX)
return frame->fr_desc->fd_description;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return NULL;
return (char *) frame->fr_data + 1;
}
/*
* Function id3_get_text_number (frame)
*
* Return string contents of frame translated to a positive
* integer, or -1 if an error occured.
*
*/
int id3_get_text_number(id3_frame_t * frame)
{
int number = 0;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return -1;
/*
* Generate integer according to encoding.
*/
switch (*(uint8_t *) frame->fr_data) {
case ID3_ENCODING_ISO_8859_1:
{
char *text = ((char *) frame->fr_data) + 1;
while (*text >= '0' && *text <= '9') {
number *= 10;
number += *text - '0';
text++;
}
return number;
}
case ID3_ENCODING_UTF16:
{
int16_t *text = ((int16_t *) frame->fr_data) + 1;
while (*text >= '0' && *text <= '9') {
number *= 10;
number += *text - '0';
text++;
}
return number;
}
default:
return -1;
}
}
/*
* Function id3_set_text (frame, text)
*
* Set text for the indicated frame (only ISO-8859-1 is currently
* supported). Return 0 upon success, or -1 if an error occured.
*
*/
int id3_set_text(id3_frame_t * frame, char *text)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T')
return -1;
/*
* Release memory occupied by previous data.
*/
id3_frame_clear_data(frame);
/*
* Allocate memory for new data.
*/
frame->fr_raw_size = strlen(text) + 1;
frame->fr_raw_data = kmalloc(frame->fr_raw_size + 1, GFP_KERNEL);
/*
* Copy contents.
*/
*(uint8_t *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1;
memcpy((char *) frame->fr_raw_data + 1, text, frame->fr_raw_size);
frame->fr_altered = 1;
frame->fr_owner->id3_altered = 1;
frame->fr_data = frame->fr_raw_data;
frame->fr_size = frame->fr_raw_size;
return 0;
}
/*
* Function id3_set_text_number (frame, number)
*
* Set number for the indicated frame (only ISO-8859-1 is currently
* supported). Return 0 upon success, or -1 if an error occured.
*
*/
int id3_set_text_number(id3_frame_t * frame, int number)
{
char buf[64];
int pos;
char *text;
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'T')
return -1;
/*
* Release memory occupied by previous data.
*/
id3_frame_clear_data(frame);
/*
* Create a string with a reversed number.
*/
pos = 0;
while (number > 0 && pos < 64) {
buf[pos++] = (number % 10) + '0';
number /= 10;
}
if (pos == 64)
return -1;
if (pos == 0)
buf[pos++] = '0';
/*
* Allocate memory for new data.
*/
frame->fr_raw_size = pos + 1;
frame->fr_raw_data = kmalloc(frame->fr_raw_size + 1, GFP_KERNEL);
/*
* Insert contents.
*/
*(uint8_t *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1;
text = (char *) frame->fr_raw_data + 1;
while (--pos >= 0)
*text++ = buf[pos];
*text = '\0';
frame->fr_altered = 1;
frame->fr_owner->id3_altered = 1;
frame->fr_data = frame->fr_raw_data;
frame->fr_size = frame->fr_raw_size;
return 0;
}
--- NEW FILE: id3_frame_url.c ---
/*********************************************************************
*
* Copyright (C) 1999, 2001,
* Department of Computer Science, University of Tromsø
*
* Filename: id3_frame_url.c
* Description: Code for handling ID3 URL frames.
* Author: Espen Skoglund <es...@st...>
* Created at: Tue Feb 9 21:10:45 1999
*
* $Id: id3_frame_url.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include "id3.h"
#include "id3_header.h"
/*
* Function id3_get_url (frame)
*
* Return URL of frame.
*
*/
char *id3_get_url(id3_frame_t * frame)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'W')
return NULL;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return NULL;
if (frame->fr_desc->fd_id == ID3_WXXX) {
/*
* This is a user defined link frame. Skip the description.
*/
switch (*(uint8_t *) frame->fr_data) {
case ID3_ENCODING_ISO_8859_1:
{
char *text = (char *) frame->fr_data + 1;
while (*text != 0)
text++;
return ++text;
}
case ID3_ENCODING_UTF16:
{
int16_t *text16 =
(int16_t *) ((int) frame->fr_data + 1);
while (*text16 != 0)
text16++;
return (char *) ++text16;
}
default:
return NULL;
}
}
return (char *) frame->fr_data;
}
/*
* Function id3_get_url_desc (frame)
*
* Get description of a URL.
*
*/
char *id3_get_url_desc(id3_frame_t * frame)
{
/* Type check */
if (frame->fr_desc->fd_idstr[0] != 'W')
return NULL;
/* If predefined link frame, return description. */
if (frame->fr_desc->fd_id != ID3_WXXX)
return frame->fr_desc->fd_description;
/* Check if frame is compressed */
if (id3_decompress_frame(frame) == -1)
return NULL;
return (char *) frame->fr_data + 1;
}
--- NEW FILE: id3_header.h ---
/*********************************************************************
*
* Copyright (C) 1998, 1999, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3_header.h
* Description: Definitions for various ID3 headers.
* Author: Espen Skoglund <es...@st...>
* Created at: Thu Nov 5 15:55:10 1998
*
* $Id: id3_header.h,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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.
*
********************************************************************/
#ifndef ID3_HEADER_H
#define ID3_HEADER_H
#ifndef __GNUC__
#define __attribute__(A)
#endif
/*
* Layout for the ID3 tag header.
*/
typedef struct id3_taghdr_t id3_taghdr_t;
struct id3_taghdr_t {
uint8_t th_version;
uint8_t th_revision;
uint8_t th_flags;
uint32_t th_size;
} __attribute__ ((packed));
#define ID3_THFLAG_USYNC 0x80000000
#define ID3_THFLAG_EXT 0x40000000
#define ID3_THFLAG_EXP 0x20000000
#define ID3_SET_SIZE28(size) \
( ((size << 3) & 0x7f000000) | \
((size << 2) & 0x007f0000) | \
((size << 1) & 0x00007f00) | \
((size ) & 0x0000007f) )
#define ID3_GET_SIZE28(size) \
( ((size & 0x7f000000) >> 3) | \
((size & 0x007f0000) >> 2) | \
((size & 0x00007f00) >> 1) | \
((size & 0x0000007f) ) )
/*
* Layout for the extended header.
*/
typedef struct id3_exthdr_t id3_exthdr_t;
struct id3_exthdr_t {
uint32_t eh_size;
uint16_t eh_flags;
uint32_t eh_padsize;
} __attribute__ ((packed));
#define ID3_EHFLAG_CRC 0x80000000
/*
* Layout for the frame header.
*/
typedef struct id3_framehdr_t id3_framehdr_t;
struct id3_framehdr_t {
uint32_t fh_id;
uint32_t fh_size;
uint16_t fh_flags;
} __attribute__ ((packed));
#define ID3_FHFLAG_TAGALT 0x8000
#define ID3_FHFLAG_FILEALT 0x4000
#define ID3_FHFLAG_RO 0x2000
#define ID3_FHFLAG_COMPRESS 0x0080
#define ID3_FHFLAG_ENCRYPT 0x0040
#define ID3_FHFLAG_GROUP 0x0020
typedef enum {
ID3_UNI_LATIN = 0x007f,
ID3_UNI_LATIN_1 = 0x00ff,
ID3_UNI_SUPPORTED = 0x00ff,
ID3_UNI_UNSUPPORTED = 0xffff,
} id3_unicode_blocks;
#ifdef DEBUG_ID3
#define id3_error(id3, error) \
(void) ( id3->id3_error_msg = error, \
printf( "Error %s, line %d: %s\n", __FILE__, __LINE__, error ) )
#else
#define id3_error(id3, error) \
(void) ( id3->id3_error_msg = error )
#endif
#endif /* ID3_HEADER_H */
--- NEW FILE: id3_tag.c ---
#define err(x) printk(x "\n")
/*********************************************************************
*
* Copyright (C) 1999-2000, Espen Skoglund
* Department of Computer Science, University of Tromsø
*
* Filename: id3_tag.c
* Description: Code for handling ID3 tags.
* Author: Espen Skoglund <es...@st...>
* Created at: Tue Feb 9 21:13:19 1999
*
* $Id: id3_tag.c,v 1.1.2.1 2003/08/03 23:10:43 ben_osheroff Exp $
*
* 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 <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
#include "id3.h"
#include "id3_header.h"
/*
* Function id3_init_tag (id3)
*
* Initialize an empty ID3 tag.
*
*/
void id3_init_tag(id3_t * id3)
{
/*
* Initialize header.
*/
id3->id3_version = 3;
id3->id3_revision = 0;
id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP;
id3->id3_tagsize = 0;
id3->id3_altered = 1;
id3->id3_newtag = 1;
id3->id3_pos = 0;
INIT_LIST_HEAD(&id3->id3_frame);
}
/*
* Function id3_read_tag (id3)
*
* Read the ID3 tag from the input stream. The start of the tag
* must be positioned in the next tag in the stream. Return 0 upon
* success, or -1 if an error occured.
*
*/
int id3_read_tag(id3_t * id3)
{
id3_taghdr_t *taghdr;
id3_exthdr_t *exthdr;
char *id;
/*
* We know that the tag will be at least this big.
*/
id3->id3_tagsize = sizeof(*taghdr) + 3;
if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) {
/*
* Check if we have a valid ID3 tag.
*/
id = id3->id3_read(id3, NULL, 3);
if (id == NULL)
return -1;
if (id[0] != 'I' || id[1] != 'D' || id[2] != '3') {
/*
* ID3 tag was not detected.
*/
id3->id3_seek(id3, -3);
return -1;
}
}
err("reading the tag header");
/*
* Read ID3 tag-header.
*/
taghdr = id3->id3_read(id3, NULL, sizeof(*taghdr));
if (taghdr == NULL)
return -1;
id3->id3_version = taghdr->th_version;
id3->id3_revision = taghdr->th_revision;
id3->id3_flags = taghdr->th_flags;
id3->id3_tagsize = ID3_GET_SIZE28(be32_to_cpu(taghdr->th_size));
id3->id3_newtag = 0;
id3->id3_pos = 0;
/*
* Parse extended header.
*/
err("reading the extended header");
if (taghdr->th_flags & ID3_THFLAG_EXT) {
exthdr = id3->id3_read(id3, NULL, sizeof(*exthdr));
if (exthdr == NULL)
return -1;
}
/*
* Parse frames.
*/
err("reading the frames");
INIT_LIST_HEAD(&id3->id3_frame);
while (id3->id3_pos < id3->id3_tagsize) {
if (id3_read_frame(id3) == -1)
return -1;
}
return 0;
}
--- NEW FILE: mpg123.c ---
#include <linux/kernel.h>
#include <linux/string.h>
#include "mpg123.h"
const char *mpg123_id3_genres[GENRE_MAX] = {
"Blues", "Classic Rock", "Country", "Dance",
"Disco", "Funk", "Grunge", "Hip-Hop",
"Jazz", "Metal", "New Age", "Oldies",
"Other", "Pop", "R&B", "Rap", "Reggae",
"Rock", "Techno", "Industrial", "Alternative",
"Ska", "Death Metal", "Pranks", "Soundtrack",
"Euro-Techno", "Ambient", "Trip-Hop", "Vocal",
"Jazz+Funk", "Fusion", "Trance", "Classical",
"Instrumental", "Acid", "House", "Game",
"Sound Clip", "Gospel", "Noise", "Alt",
"Bass", "Soul", "Punk", "Space",
"Meditative", "Instrumental Pop",
"Instrumental Rock", "Ethnic", "Gothic",
"Darkwave", "Techno-Industrial", "Electronic",
"Pop-Folk", "Eurodance", "Dream",
"Southern Rock", "Comedy", "Cult",
"Gangsta Rap", "Top 40", "Christian Rap",
"Pop/Funk", "Jungle", "Native American",
"Cabaret", "New Wave", "Psychedelic", "Rave",
"Showtunes", "Trailer", "Lo-Fi", "Tribal",
"Acid Punk", "Acid Jazz", "Polka", "Retro",
"Musical", "Rock & Roll", "Hard Rock", "Folk",
"Folk/Rock", "National Folk", "Swing",
"Fast-Fusion", "Bebob", "Latin", "Revival",
"Celtic", "Bluegrass", "Avantgarde",
"Gothic Rock", "Progressive Rock",
"Psychedelic Rock", "Symphonic Rock", "Slow Rock",
"Big Band", "Chorus", "Easy Listening",
"Acoustic", "Humour", "Speech", "Chanson",
"Opera", "Chamber Music", "Sonata", "Symphony",
"Booty Bass", "Primus", "Porn Groove",
"Satire", "Slow Jam", "Club", "Tango",
"Samba", "Folklore", "Ballad", "Power Ballad",
"Rhythmic Soul", "Freestyle", "Duet",
"Punk Rock", "Drum Solo", "A Cappella",
"Euro-House", "Dance Hall", "Goa",
"Drum & Bass", "Club-House", "Hardcore",
"Terror", "Indie", "BritPop", "Negerpunk",
"Polsk Punk", "Beat", "Christian Gangsta Rap",
"Heavy Metal", "Black Metal", "Crossover",
"Contemporary Christian", "Christian Rock",
"Merengue", "Salsa", "Thrash Metal",
"Anime", "JPop", "Synthpop"
};
--- NEW FILE: mpg123.h ---
/*
* mpg123 defines
* used source: musicout.h from mpegaudio package
*/
#ifndef __MPG123_H__
#define __MPG123_H__
#include "id3.h"
#define real float
/* #define MAX_NAME_SIZE 81 */
#define SBLIMIT 32
#define SCALE_BLOCK 12
#define SSLIMIT 18
#define MPG_MD_STEREO 0
#define MPG_MD_JOINT_STEREO 1
#define MPG_MD_DUAL_CHANNEL 2
#define MPG_MD_MONO 3
struct id3v1tag_t {
char tag[3]; /* always "TAG": defines ID3v1 tag 128 bytes before EOF */
char title[30];
char artist[30];
char album[30];
char year[4];
union {
struct {
char comment[30];
} v1_0;
struct {
char comment[28];
char __zero;
unsigned char track_number;
} v1_1;
} u;
unsigned char genre;
};
struct id3tag_t {
char title[64];
char artist[64];
char album[64];
char comment[256];
char genre[256];
int year;
int track_number;
};
struct al_table {
short bits;
short d;
};
#define GENRE_MAX 0x94
extern const char *mpg123_id3_genres[GENRE_MAX];
extern int tabsel_123[2][3][16];
#endif
|