mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
remove id3 support from the plugins
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include @ID3LIB_CFLAGS@
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LTLIBRARIES = libplugin_common.la
|
||||
|
||||
@@ -12,8 +12,6 @@ noinst_HEADERS = \
|
||||
charset.h \
|
||||
defs.h \
|
||||
dither.h \
|
||||
id3v1.h \
|
||||
id3v2.h \
|
||||
locale_hack.h \
|
||||
vorbiscomment.h
|
||||
|
||||
@@ -21,8 +19,6 @@ libplugin_common_la_SOURCES = \
|
||||
canonical_tag.c \
|
||||
charset.c \
|
||||
dither.c \
|
||||
id3v1.c \
|
||||
id3v2.c \
|
||||
vorbiscomment.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
||||
@@ -6,14 +6,12 @@ topdir = ../..
|
||||
|
||||
LIB_NAME = libplugin_common
|
||||
INCLUDES = -I$(topdir)/include -I$(HOME)/local/include
|
||||
DEFINES = -DFLAC__HAS_ID3LIB -DID3LIB_MAJOR=3 -DID3LIB_MINOR=8 -DID3LIB_PATCH=0
|
||||
DEFINES =
|
||||
|
||||
SRCS_C = \
|
||||
canonical_tag.c \
|
||||
charset.c \
|
||||
dither.c \
|
||||
id3v1.c \
|
||||
id3v2.c \
|
||||
vorbiscomment.c
|
||||
|
||||
include $(topdir)/build/lib.mk
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#include "canonical_tag.h"
|
||||
#include "charset.h"
|
||||
#include "dither.h"
|
||||
#include "id3v1.h"
|
||||
#include "id3v2.h"
|
||||
#include "locale_hack.h"
|
||||
#include "vorbiscomment.h"
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* for strlen() and memcpy() */
|
||||
|
||||
#include "canonical_tag.h"
|
||||
#include "id3v2.h"
|
||||
#include "vorbiscomment.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/metadata.h"
|
||||
@@ -151,38 +151,6 @@ weak_alias (__wcscasecmp, wcscasecmp)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
/* @@@ cheesy and does base 10 only */
|
||||
wchar_t *local__itow(int value, wchar_t *string)
|
||||
{
|
||||
if (value == 0) {
|
||||
string[0] = (wchar_t)'0';
|
||||
string[1] = (wchar_t)0;
|
||||
}
|
||||
else {
|
||||
/* convert backwards, then reverse string */
|
||||
wchar_t *start = string, *s;
|
||||
if (value < 0) {
|
||||
*start++ = (wchar_t)'-';
|
||||
value = -value; /* @@@ overflow at INT_MIN */
|
||||
}
|
||||
s = start;
|
||||
while (value > 0) {
|
||||
*s++ = (wchar_t)((value % 10) + '0');
|
||||
value /= 10;
|
||||
}
|
||||
*s-- = (wchar_t)0;
|
||||
while (s > start) {
|
||||
wchar_t tmp = *s;
|
||||
*s-- = *start;
|
||||
*start++ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* helpers
|
||||
*/
|
||||
@@ -611,133 +579,7 @@ void FLAC_plugin__canonical_tag_merge(FLAC_Plugin__CanonicalTag *dest, const FLA
|
||||
}
|
||||
}
|
||||
|
||||
static wchar_t *local__copy_field(const char *src, unsigned n)
|
||||
{
|
||||
const char *p = src + n;
|
||||
wchar_t *dest;
|
||||
FLAC__ASSERT(n > 0);
|
||||
|
||||
while (p>src && *(--p)==' ');
|
||||
|
||||
n = p - src + 1;
|
||||
if (!n) return NULL;
|
||||
|
||||
if ((dest = malloc((n+1)*sizeof(wchar_t))) != 0)
|
||||
{
|
||||
mbstowcs(dest, src, n);
|
||||
dest[n] = 0;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void local__add_id3_field(FLAC_Plugin__CanonicalTag *object, const char *value, size_t length, const wchar_t *new_name)
|
||||
{
|
||||
wchar_t *tmp;
|
||||
if (0 != value && length > 0) {
|
||||
tmp = local__copy_field(value, length);
|
||||
if (tmp)
|
||||
FLAC_plugin__canonical_add_tail(object, wcsdup(new_name), tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC_plugin__canonical_tag_convert_from_id3v1(FLAC_Plugin__CanonicalTag *object, const FLAC_Plugin__Id3v1_Tag *id3v1_tag)
|
||||
{
|
||||
wchar_t *tmp;
|
||||
FLAC_plugin__canonical_tag_clear(object);
|
||||
|
||||
local__add_id3_field(object, id3v1_tag->title, 30, L"TITLE");
|
||||
local__add_id3_field(object, id3v1_tag->artist, 30, L"ARTIST");
|
||||
local__add_id3_field(object, id3v1_tag->album, 30, L"ALBUM");
|
||||
local__add_id3_field(object, id3v1_tag->year, 4, L"YEAR");
|
||||
|
||||
/* check for v1.1 tags */
|
||||
if (id3v1_tag->zero == 0)
|
||||
{
|
||||
if (id3v1_tag->track && (tmp=(wchar_t*)malloc(sizeof(id3v1_tag->track)*4*sizeof(wchar_t)))!=0)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_itow(id3v1_tag->track, tmp, 10);
|
||||
#else
|
||||
local__itow(id3v1_tag->track, tmp);
|
||||
#endif
|
||||
FLAC_plugin__canonical_add_tail(object, wcsdup(L"TRACKNUMBER"), tmp);
|
||||
}
|
||||
local__add_id3_field(object, id3v1_tag->comment, 28, L"DESCRIPTION");
|
||||
}
|
||||
else
|
||||
{
|
||||
local__add_id3_field(object, id3v1_tag->comment, 30, L"DESCRIPTION");
|
||||
}
|
||||
|
||||
tmp = FLAC_plugin__convert_ansi_to_wide(FLAC_plugin__id3v1_tag_get_genre_as_string(id3v1_tag->genre));
|
||||
if (tmp) FLAC_plugin__canonical_add_tail(object, wcsdup(L"GENRE"), tmp);
|
||||
}
|
||||
|
||||
void FLAC_plugin__canonical_tag_convert_from_id3v2(FLAC_Plugin__CanonicalTag *object, const FLAC_Plugin__Id3v2_Tag *id3v2_tag)
|
||||
{
|
||||
FLAC_plugin__canonical_tag_clear(object);
|
||||
|
||||
local__add_id3_field(object, id3v2_tag->title , strlen(id3v2_tag->title) , L"TITLE");
|
||||
local__add_id3_field(object, id3v2_tag->composer , strlen(id3v2_tag->composer) , L"ARTIST");
|
||||
local__add_id3_field(object, id3v2_tag->performer , strlen(id3v2_tag->performer) , L"PERFORMER");
|
||||
local__add_id3_field(object, id3v2_tag->album , strlen(id3v2_tag->album) , L"ALBUM");
|
||||
local__add_id3_field(object, id3v2_tag->year_recorded , strlen(id3v2_tag->year_recorded) , L"YEAR_RECORDED");
|
||||
local__add_id3_field(object, id3v2_tag->year_performed , strlen(id3v2_tag->year_performed) , L"YEAR_PERFORMED");
|
||||
local__add_id3_field(object, id3v2_tag->track_number , strlen(id3v2_tag->track_number) , L"TRACKNUMBER");
|
||||
local__add_id3_field(object, id3v2_tag->tracks_in_album, strlen(id3v2_tag->tracks_in_album), L"TRACKS_IN_ALBUM");
|
||||
local__add_id3_field(object, id3v2_tag->genre , strlen(id3v2_tag->genre) , L"GENRE");
|
||||
local__add_id3_field(object, id3v2_tag->comment , strlen(id3v2_tag->comment) , L"DESCRIPTION");
|
||||
}
|
||||
|
||||
static FLAC__bool local__get_id3v1_tag_as_canonical(const char *filename, FLAC_Plugin__CanonicalTag *tag)
|
||||
{
|
||||
FLAC_Plugin__Id3v1_Tag id3v1_tag;
|
||||
|
||||
if (FLAC_plugin__id3v1_tag_get(filename, &id3v1_tag))
|
||||
{
|
||||
FLAC_plugin__canonical_tag_convert_from_id3v1(tag, &id3v1_tag);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static FLAC__bool local__get_id3v2_tag_as_canonical(const char *filename, FLAC_Plugin__CanonicalTag *tag)
|
||||
{
|
||||
FLAC_Plugin__Id3v2_Tag id3v2_tag;
|
||||
|
||||
if (FLAC_plugin__id3v2_tag_get(filename, &id3v2_tag))
|
||||
{
|
||||
FLAC_plugin__canonical_tag_convert_from_id3v2(tag, &id3v2_tag);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FLAC_plugin__canonical_tag_add_id3v1(const char *filename, FLAC_Plugin__CanonicalTag *tag)
|
||||
{
|
||||
FLAC_Plugin__CanonicalTag id3v1_tag;
|
||||
|
||||
FLAC_plugin__canonical_tag_init(&id3v1_tag);
|
||||
(void)local__get_id3v1_tag_as_canonical(filename, &id3v1_tag);
|
||||
FLAC_plugin__canonical_tag_merge(tag, &id3v1_tag);
|
||||
|
||||
FLAC_plugin__canonical_tag_clear(&id3v1_tag);
|
||||
}
|
||||
|
||||
void FLAC_plugin__canonical_tag_add_id3v2(const char *filename, FLAC_Plugin__CanonicalTag *tag)
|
||||
{
|
||||
FLAC_Plugin__CanonicalTag id3v2_tag;
|
||||
|
||||
FLAC_plugin__canonical_tag_init(&id3v2_tag);
|
||||
(void)local__get_id3v2_tag_as_canonical(filename, &id3v2_tag);
|
||||
FLAC_plugin__canonical_tag_merge(tag, &id3v2_tag);
|
||||
|
||||
FLAC_plugin__canonical_tag_clear(&id3v2_tag);
|
||||
}
|
||||
|
||||
void FLAC_plugin__canonical_tag_get_combined(const char *filename, FLAC_Plugin__CanonicalTag *tag, const char *sep)
|
||||
{
|
||||
FLAC_plugin__vorbiscomment_get(filename, tag, sep);
|
||||
FLAC_plugin__canonical_tag_add_id3v2(filename, tag);
|
||||
FLAC_plugin__canonical_tag_add_id3v1(filename, tag);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
#ifndef FLAC__PLUGIN_COMMON__CANONICAL_TAG_H
|
||||
#define FLAC__PLUGIN_COMMON__CANONICAL_TAG_H
|
||||
|
||||
#include "id3v1.h"
|
||||
#include "id3v2.h"
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/* TODO: splay tree? */
|
||||
typedef struct tagFLAC__tag_entry FLAC__tag_entry;
|
||||
@@ -80,20 +79,6 @@ wchar_t *FLAC_plugin__canonical_get_value(FLAC__tag_iterator it);
|
||||
char *FLAC_plugin__canonical_get_formatted(FLAC__tag_iterator it);
|
||||
|
||||
void FLAC_plugin__canonical_tag_merge(FLAC_Plugin__CanonicalTag *dest, const FLAC_Plugin__CanonicalTag *src);
|
||||
void FLAC_plugin__canonical_tag_convert_from_id3v1(FLAC_Plugin__CanonicalTag *, const FLAC_Plugin__Id3v1_Tag *);
|
||||
void FLAC_plugin__canonical_tag_convert_from_id3v2(FLAC_Plugin__CanonicalTag *, const FLAC_Plugin__Id3v2_Tag *);
|
||||
|
||||
void FLAC_plugin__canonical_tag_add_id3v1(const char *filename, FLAC_Plugin__CanonicalTag *tag);
|
||||
void FLAC_plugin__canonical_tag_add_id3v2(const char *filename, FLAC_Plugin__CanonicalTag *tag);
|
||||
|
||||
/* Returns a merged tag based on any Vorbis comments, id3v2 tag, and id3v1.
|
||||
* In case of overlaps the preceding precedence applies.
|
||||
*
|
||||
* sep - separator to use when merging fields with same name (in VorbisComment).
|
||||
* should be in UTF-8. if sep==NULL, no merging occurs, so multiple fields
|
||||
* with the same name can exist.
|
||||
*/
|
||||
void FLAC_plugin__canonical_tag_get_combined(const char *filename, FLAC_Plugin__CanonicalTag *tag, const char *sep);
|
||||
|
||||
/* helpers */
|
||||
wchar_t *FLAC_plugin__convert_ansi_to_wide(const char *src);
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
/* plugin_common - Routines common to several plugins
|
||||
* Copyright (C) 2002,2003,2004 Josh Coalson
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
#include "id3v1.h"
|
||||
#include "locale_hack.h"
|
||||
|
||||
|
||||
/*
|
||||
* Do not sort genres!!
|
||||
* Last Update: 2000/04/30
|
||||
*/
|
||||
static const char * const FLAC_plugin__id3v1_tag_genre_table[] =
|
||||
{
|
||||
"Blues", /* 0 */
|
||||
"Classic Rock",
|
||||
"Country",
|
||||
"Dance",
|
||||
"Disco",
|
||||
"Funk", /* 5 */
|
||||
"Grunge",
|
||||
"Hip-Hop",
|
||||
"Jazz",
|
||||
"Metal",
|
||||
"New Age", /* 10 */
|
||||
"Oldies",
|
||||
"Other",
|
||||
"Pop",
|
||||
"R&B",
|
||||
"Rap", /* 15 */
|
||||
"Reggae",
|
||||
"Rock",
|
||||
"Techno",
|
||||
"Industrial",
|
||||
"Alternative", /* 20 */
|
||||
"Ska",
|
||||
"Death Metal",
|
||||
"Pranks",
|
||||
"Soundtrack",
|
||||
"Euro-Techno", /* 25 */
|
||||
"Ambient",
|
||||
"Trip-Hop",
|
||||
"Vocal",
|
||||
"Jazz+Funk",
|
||||
"Fusion", /* 30 */
|
||||
"Trance",
|
||||
"Classical",
|
||||
"Instrumental",
|
||||
"Acid",
|
||||
"House", /* 35 */
|
||||
"Game",
|
||||
"Sound Clip",
|
||||
"Gospel",
|
||||
"Noise",
|
||||
"Altern Rock", /* 40 */
|
||||
"Bass",
|
||||
"Soul",
|
||||
"Punk",
|
||||
"Space",
|
||||
"Meditative", /* 45 */
|
||||
"Instrumental Pop",
|
||||
"Instrumental Rock",
|
||||
"Ethnic",
|
||||
"Gothic",
|
||||
"Darkwave", /* 50 */
|
||||
"Techno-Industrial",
|
||||
"Electronic",
|
||||
"Pop-Folk",
|
||||
"Eurodance",
|
||||
"Dream", /* 55 */
|
||||
"Southern Rock",
|
||||
"Comedy",
|
||||
"Cult",
|
||||
"Gangsta",
|
||||
"Top 40", /* 60 */
|
||||
"Christian Rap",
|
||||
"Pop/Funk",
|
||||
"Jungle",
|
||||
"Native American",
|
||||
"Cabaret", /* 65 */
|
||||
"New Wave",
|
||||
"Psychadelic",
|
||||
"Rave",
|
||||
"Showtunes",
|
||||
"Trailer", /* 70 */
|
||||
"Lo-Fi",
|
||||
"Tribal",
|
||||
"Acid Punk",
|
||||
"Acid Jazz",
|
||||
"Polka", /* 75 */
|
||||
"Retro",
|
||||
"Musical",
|
||||
"Rock & Roll",
|
||||
"Hard Rock",
|
||||
"Folk", /* 80 */
|
||||
"Folk/Rock",
|
||||
"National Folk",
|
||||
"Fast Fusion",
|
||||
"Swing",
|
||||
"Bebob", /* 85 */
|
||||
"Latin",
|
||||
"Revival",
|
||||
"Celtic",
|
||||
"Bluegrass",
|
||||
"Avantgarde", /* 90 */
|
||||
"Gothic Rock",
|
||||
"Progressive Rock",
|
||||
"Psychedelic Rock",
|
||||
"Symphonic Rock",
|
||||
"Slow Rock", /* 95 */
|
||||
"Big Band",
|
||||
"Chorus",
|
||||
"Easy Listening",
|
||||
"Acoustic",
|
||||
"Humour", /* 100 */
|
||||
"Speech",
|
||||
"Chanson",
|
||||
"Opera",
|
||||
"Chamber Music",
|
||||
"Sonata", /* 105 */
|
||||
"Symphony",
|
||||
"Booty Bass",
|
||||
"Primus",
|
||||
"Porn Groove",
|
||||
"Satire", /* 110 */
|
||||
"Slow Jam",
|
||||
"Club",
|
||||
"Tango",
|
||||
"Samba",
|
||||
"Folklore", /* 115 */
|
||||
"Ballad",
|
||||
"Power Ballad",
|
||||
"Rhythmic Soul",
|
||||
"Freestyle",
|
||||
"Duet", /* 120 */
|
||||
"Punk Rock",
|
||||
"Drum Solo",
|
||||
"A Capella",
|
||||
"Euro-House",
|
||||
"Dance Hall", /* 125 */
|
||||
"Goa",
|
||||
"Drum & Bass",
|
||||
"Club-House",
|
||||
"Hardcore",
|
||||
"Terror", /* 130 */
|
||||
"Indie",
|
||||
"BritPop",
|
||||
"Negerpunk",
|
||||
"Polsk Punk",
|
||||
"Beat", /* 135 */
|
||||
"Christian Gangsta Rap",
|
||||
"Heavy Metal",
|
||||
"Black Metal",
|
||||
"Crossover",
|
||||
"Contemporary Christian",/* 140 */
|
||||
"Christian Rock",
|
||||
"Merengue",
|
||||
"Salsa",
|
||||
"Thrash Metal",
|
||||
"Anime", /* 145 */
|
||||
"JPop",
|
||||
"Synthpop"
|
||||
};
|
||||
|
||||
|
||||
FLAC__bool FLAC_plugin__id3v1_tag_get(const char *filename, FLAC_Plugin__Id3v1_Tag *tag)
|
||||
{
|
||||
FILE *f;
|
||||
int res;
|
||||
|
||||
FLAC__ASSERT(0 != filename);
|
||||
FLAC__ASSERT(0 != tag);
|
||||
|
||||
memset(tag, 0, sizeof(FLAC_Plugin__Id3v1_Tag));
|
||||
|
||||
if(0 == (f = fopen(filename, "rb")))
|
||||
return false;
|
||||
if(-1 == fseek(f, -128, SEEK_END)) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
res = fread(tag, 128, 1, f);
|
||||
fclose(f);
|
||||
return res==1 && !strncmp(tag->tag, "TAG", 3);
|
||||
}
|
||||
|
||||
const char *FLAC_plugin__id3v1_tag_get_genre_as_string(unsigned char genre_code)
|
||||
{
|
||||
if (genre_code < (sizeof(FLAC_plugin__id3v1_tag_genre_table)/sizeof(FLAC_plugin__id3v1_tag_genre_table[0])))
|
||||
return gettext(FLAC_plugin__id3v1_tag_genre_table[genre_code]);
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
unsigned FLAC_plugin__id3v1_tag_genre_table_max()
|
||||
{
|
||||
return sizeof(FLAC_plugin__id3v1_tag_genre_table) / sizeof(FLAC_plugin__id3v1_tag_genre_table[0]) - 1;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* plugin_common - Routines common to several plugins
|
||||
* Copyright (C) 2002,2003,2004 Josh Coalson
|
||||
*
|
||||
* 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 FLAC__PLUGIN_COMMON__ID3V1_H
|
||||
#define FLAC__PLUGIN_COMMON__ID3V1_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct {
|
||||
char tag[3];
|
||||
char title[30];
|
||||
char artist[30];
|
||||
char album[30];
|
||||
char year[4];
|
||||
/* always use layout of id3 v1.1 */
|
||||
char comment[28];
|
||||
char zero;
|
||||
unsigned char track;
|
||||
unsigned char genre;
|
||||
} FLAC_Plugin__Id3v1_Tag;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
FLAC__bool FLAC_plugin__id3v1_tag_get(const char *filename, FLAC_Plugin__Id3v1_Tag *tag);
|
||||
|
||||
|
||||
#define FLAC_PLUGIN__ID3V1_TAG_INVALID_GENRE 255
|
||||
|
||||
const char *FLAC_plugin__id3v1_tag_get_genre_as_string(unsigned char genre_code);
|
||||
unsigned FLAC_plugin__id3v1_tag_genre_table_max();
|
||||
|
||||
#endif
|
||||
@@ -1,422 +0,0 @@
|
||||
/* plugin_common - Routines common to several plugins
|
||||
* Copyright (C) 2002,2003,2004 Daisuke Shimamura
|
||||
*
|
||||
* Almost from id3_tag.c - 2001/02/16
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 2001-2002 Jerome Couderc <j.couderc@ifrance.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#include <stdlib.h> /* for free() */
|
||||
#include <string.h> /* for memset() */
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
#include <id3.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "id3v1.h" /* for genre stuff */
|
||||
#include "locale_hack.h"
|
||||
|
||||
#define ID3V2_MAX_STRING_LEN 4096
|
||||
#define NUMBER_TRACK_FORMATED 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This should come after #include<id3.h> because id3.h doesn't #undef
|
||||
* true and false before redefining them, causing warnings.
|
||||
*/
|
||||
#include "id3v2.h"
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
/* local__strip() based on glib's g_strchomp() and g_strchug():
|
||||
* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* (LGPL 2 follows)
|
||||
*/
|
||||
static void local__strip(char *string)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if(0 == string)
|
||||
return;
|
||||
|
||||
for(s = string; *s && isspace(*s); s++)
|
||||
;
|
||||
|
||||
memmove(string, s, strlen((char*)s) + 1);
|
||||
|
||||
if(!*string)
|
||||
return;
|
||||
|
||||
for(s = string + strlen (string) - 1; s >= string && isspace(*s); s--)
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* As the ID3Tag_Link function of id3lib-3.8.0pre2 returns the ID3v1 tags
|
||||
* when a file has both ID3v1 and ID3v2 tags, we first try to explicitely
|
||||
* get the ID3v2 tags with ID3Tag_LinkWithFlags and, if we cannot get them,
|
||||
* fall back to the ID3v1 tags.
|
||||
* (Written by Holger Schemel).
|
||||
*/
|
||||
static size_t local__ID3Tag_Link_wrapper(ID3Tag *id3tag, const char *filename)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
# if ( (ID3LIB_MAJOR >= 3) && (ID3LIB_MINOR >= 8) )
|
||||
/* First, try to get the ID3v2 tags */
|
||||
offset = ID3Tag_LinkWithFlags(id3tag, filename, ID3TT_ID3V2);
|
||||
if (offset == 0) {
|
||||
/* No ID3v2 tags available => try to get the ID3v1 tags */
|
||||
offset = ID3Tag_LinkWithFlags(id3tag, filename, ID3TT_ID3V1);
|
||||
}
|
||||
# else
|
||||
/* Function 'ID3Tag_LinkWithFlags' is not defined up to id3lib-.3.7.13 */
|
||||
offset = ID3Tag_Link(id3tag, filename);
|
||||
# endif
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* As the ID3Field_GetASCII function differs with the version of id3lib, we must redefine it.
|
||||
*/
|
||||
/* [JEC] old id3lib versions may have used index_t for itemNum but size_t is what it wants now and seems safe enough. */
|
||||
static size_t local__ID3Field_GetASCII_wrapper(const ID3Field *field, char *buffer, size_t maxChars, size_t itemNum)
|
||||
{
|
||||
|
||||
/* Defined by id3lib: ID3LIB_MAJOR_VERSION, ID3LIB_MINOR_VERSION, ID3LIB_PATCH_VERSION
|
||||
* Defined by autoconf: ID3LIB_MAJOR, ID3LIB_MINOR, ID3LIB_PATCH
|
||||
*
|
||||
* <= 3.7.12 : first item num is 1 for ID3Field_GetASCII
|
||||
* = 3.7.13 : first item num is 0 for ID3Field_GetASCII
|
||||
* >= 3.8.0 : doesn't need item num for ID3Field_GetASCII
|
||||
*/
|
||||
# if (ID3LIB_MAJOR >= 3)
|
||||
/* (>= 3.x.x) */
|
||||
# if (ID3LIB_MINOR <= 7)
|
||||
/* (3.0.0 to 3.7.x) */
|
||||
# if (ID3LIB_PATCH >= 13)
|
||||
/* (>= 3.7.13) */
|
||||
return ID3Field_GetASCII(field, buffer, maxChars, itemNum);
|
||||
# else
|
||||
return ID3Field_GetASCII(field, buffer, maxChars, itemNum+1);
|
||||
# endif
|
||||
# else
|
||||
/* (>= to 3.8.0) */
|
||||
/*return ID3Field_GetASCII(field, buffer, maxChars); */
|
||||
return ID3Field_GetASCIIItem(field, buffer, maxChars, itemNum);
|
||||
# endif
|
||||
# else
|
||||
/* Not tested (< 3.x.x) */
|
||||
return ID3Field_GetASCII(field, buffer, maxChars, itemNum+1);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the name of a genre code if found
|
||||
* Three states for genre code :
|
||||
* - defined (0 to GENRE_MAX)
|
||||
* - undefined/unknown (GENRE_MAX+1 to ID3_INVALID_GENRE-1)
|
||||
* - invalid (>ID3_INVALID_GENRE)
|
||||
*/
|
||||
static const char *local__genre_to_string(unsigned genre_code)
|
||||
{
|
||||
if(genre_code >= FLAC_PLUGIN__ID3V1_TAG_INVALID_GENRE)
|
||||
return "";
|
||||
else {
|
||||
const char *s = FLAC_plugin__id3v1_tag_get_genre_as_string((unsigned)genre_code);
|
||||
if(s[0] == 0)
|
||||
return "Unknown";
|
||||
else
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read id3v1.x / id3v2 tag and load data into the File_Tag structure using id3lib functions.
|
||||
* Returns true on success, else false.
|
||||
* If a tag entry exists (ex: title), we allocate memory, else value stays to NULL
|
||||
*/
|
||||
static FLAC__bool local__get_tag(const char *filename, FLAC_Plugin__Id3v2_Tag *tag)
|
||||
{
|
||||
FILE *file;
|
||||
ID3Tag *id3_tag = 0; /* Tag defined by id3lib */
|
||||
char *string, *string1;
|
||||
|
||||
FLAC__ASSERT(0 != filename);
|
||||
FLAC__ASSERT(0 != tag);
|
||||
|
||||
if(0 == (file = fopen(filename, "r"))) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("ERROR while opening file: '%s' (%s).\n\a"), filename, strerror(errno));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
fclose(file); /* We close it cause id3lib opens/closes file itself */
|
||||
|
||||
|
||||
/* Get data from tag */
|
||||
if(0 != (id3_tag = ID3Tag_New())) {
|
||||
ID3Frame *id3_frame;
|
||||
ID3Field *id3_field;
|
||||
luint frm_size;
|
||||
luint num_chars;
|
||||
size_t field_num = 0; /* First field */
|
||||
|
||||
/* Link the file to the tag */
|
||||
frm_size = local__ID3Tag_Link_wrapper(id3_tag, filename);
|
||||
|
||||
string = malloc(ID3V2_MAX_STRING_LEN+1);
|
||||
|
||||
/*********
|
||||
* Title *
|
||||
*********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_TITLE))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
/* Note: if 'num_chars' is equal to 0, then the field is empty or corrupted! */
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
tag->title = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
* Composer *
|
||||
************/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_COMPOSER))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
tag->composer = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
* Artist *
|
||||
**********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_LEADARTIST))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
tag->performer = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
* Album *
|
||||
*********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_ALBUM))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
tag->album = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********
|
||||
* Year *
|
||||
********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_YEAR))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
char *tmp_str;
|
||||
|
||||
local__strip(string);
|
||||
|
||||
/* Fix for id3lib 3.7.x: if the id3v1.x tag was filled with spaces
|
||||
* instead of zeroes, then the year field contains garbages! */
|
||||
tmp_str = string;
|
||||
while (isdigit(*tmp_str)) tmp_str++;
|
||||
*tmp_str = 0;
|
||||
/* End of fix for id3lib 3.7.x */
|
||||
|
||||
local__strip(string);
|
||||
tag->year_recorded = strdup(string);
|
||||
tag->year_performed = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
* Track and Total Track *
|
||||
*************************/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_TRACKNUM))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
|
||||
string1 = strchr(string, '/');
|
||||
if (NUMBER_TRACK_FORMATED) {
|
||||
if (string1) {
|
||||
/* Just to have numbers like this : '01', '05', '12', ... */
|
||||
tag->tracks_in_album = malloc(64);
|
||||
sprintf(tag->tracks_in_album, "%.2d", atoi(string1+1));
|
||||
*string1 = '\0';
|
||||
}
|
||||
/* Just to have numbers like this : '01', '05', '12', ... */
|
||||
tag->track_number = malloc(64);
|
||||
sprintf(tag->track_number, "%.2d", atoi(string));
|
||||
}
|
||||
else {
|
||||
if (string1) {
|
||||
tag->tracks_in_album = strdup(string1+1);
|
||||
*string1 = '\0';
|
||||
}
|
||||
tag->track_number = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
* Genre *
|
||||
*********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_CONTENTTYPE))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
/*
|
||||
* We manipulate only the name of the genre
|
||||
*/
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
char *tmp;
|
||||
|
||||
local__strip(string);
|
||||
|
||||
if((string[0]=='(') && (tmp=strchr(string, ')')) && (strlen((tmp+1))>0)) {
|
||||
/* Convert a genre written as '(3)Dance' into 'Dance' */
|
||||
tag->genre = strdup(tmp+1);
|
||||
|
||||
}
|
||||
else if((string[0]=='(') && (tmp=strchr(string, ')'))) {
|
||||
/* Convert a genre written as '(3)' into 'Dance' */
|
||||
*tmp = 0;
|
||||
tag->genre = strdup(local__genre_to_string((unsigned)atoi(string+1)));
|
||||
|
||||
}
|
||||
else {
|
||||
/* Genre is already written as 'Dance' */
|
||||
tag->genre = strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********
|
||||
* Comment *
|
||||
***********/
|
||||
if(0 != (id3_frame = ID3Tag_FindFrameWithID(id3_tag, ID3FID_COMMENT))) {
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_TEXT))) {
|
||||
if((num_chars = local__ID3Field_GetASCII_wrapper(id3_field, string, ID3V2_MAX_STRING_LEN, field_num)) > 0 && string != NULL) {
|
||||
local__strip(string);
|
||||
tag->comment = strdup(string);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_DESCRIPTION))) {
|
||||
char *comment1 = calloc(MAX_STRING_LEN+1);
|
||||
num_chars = ID3Field_GetASCII(id3_field, comment1, MAX_STRING_LEN, Item_Num);
|
||||
free(comment1);
|
||||
}
|
||||
if(0 != (id3_field = ID3Frame_GetField(id3_frame, ID3FN_LANGUAGE))) {
|
||||
char *comment2 = calloc(MAX_STRING_LEN+1);
|
||||
num_chars = ID3Field_GetASCII(id3_field, comment2, MAX_STRING_LEN, Item_Num);
|
||||
free(comment2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
free(string);
|
||||
|
||||
/* Free allocated data */
|
||||
ID3Tag_Delete(id3_tag);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* ifdef FLAC__HAS_ID3LIB */
|
||||
|
||||
FLAC__bool FLAC_plugin__id3v2_tag_get(const char *filename, FLAC_Plugin__Id3v2_Tag *tag)
|
||||
{
|
||||
FLAC__ASSERT(0 != tag);
|
||||
if(
|
||||
0 != tag->title ||
|
||||
0 != tag->composer ||
|
||||
0 != tag->performer ||
|
||||
0 != tag->album ||
|
||||
0 != tag->year_recorded ||
|
||||
0 != tag->year_performed ||
|
||||
0 != tag->track_number ||
|
||||
0 != tag->tracks_in_album ||
|
||||
0 != tag->genre ||
|
||||
0 != tag->comment
|
||||
)
|
||||
return false;
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
return local__get_tag(filename, tag);
|
||||
#else
|
||||
(void)filename, (void)tag;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FLAC_plugin__id3v2_tag_clear(FLAC_Plugin__Id3v2_Tag *tag)
|
||||
{
|
||||
FLAC__ASSERT(0 != tag);
|
||||
if(0 != tag->title)
|
||||
free(tag->title);
|
||||
if(0 != tag->composer)
|
||||
free(tag->composer);
|
||||
if(0 != tag->performer)
|
||||
free(tag->performer);
|
||||
if(0 != tag->album)
|
||||
free(tag->album);
|
||||
if(0 != tag->year_recorded)
|
||||
free(tag->year_recorded);
|
||||
if(0 != tag->year_performed)
|
||||
free(tag->year_performed);
|
||||
if(0 != tag->track_number)
|
||||
free(tag->track_number);
|
||||
if(0 != tag->tracks_in_album)
|
||||
free(tag->tracks_in_album);
|
||||
if(0 != tag->genre)
|
||||
free(tag->genre);
|
||||
if(0 != tag->comment)
|
||||
free(tag->comment);
|
||||
memset(tag, 0, sizeof(*tag));
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* plugin_common - Routines common to several plugins
|
||||
* Copyright (C) 2002,2003,2004 Josh Coalson
|
||||
*
|
||||
* 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 FLAC__PLUGIN_COMMON__ID3V2_H
|
||||
#define FLAC__PLUGIN_COMMON__ID3V2_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/*
|
||||
* This is a simple structure that holds pointers to field values (in ASCII)
|
||||
* for fields we care about.
|
||||
*/
|
||||
typedef struct {
|
||||
char *title;
|
||||
char *composer;
|
||||
char *performer;
|
||||
char *album;
|
||||
char *year_recorded;
|
||||
char *year_performed;
|
||||
char *track_number;
|
||||
char *tracks_in_album;
|
||||
char *genre;
|
||||
char *comment;
|
||||
} FLAC_Plugin__Id3v2_Tag;
|
||||
|
||||
/* Fills up an existing FLAC_Plugin__Id3v2_Tag. All pointers must be NULL on
|
||||
* entry or the function will return false. For any field for which there is
|
||||
* no corresponding ID3 frame, it's pointer will be NULL.
|
||||
*
|
||||
* If loading fails, all pointers will be cleared and the function will return
|
||||
* false.
|
||||
*
|
||||
* If the function returns true, be sure to call FLAC_plugin__id3v2_tag_clear()
|
||||
* when you are done with 'tag'.
|
||||
*/
|
||||
FLAC__bool FLAC_plugin__id3v2_tag_get(const char *filename, FLAC_Plugin__Id3v2_Tag *tag);
|
||||
|
||||
/* free()s any non-NULL pointers in 'tag'. Does NOT free(tag).
|
||||
*/
|
||||
void FLAC_plugin__id3v2_tag_clear(FLAC_Plugin__Id3v2_Tag *tag);
|
||||
|
||||
#endif
|
||||
@@ -97,14 +97,6 @@ SOURCE=.\dither.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\id3v1.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\id3v2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vorbiscomment.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -129,10 +121,6 @@ SOURCE=.\dither.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\id3v1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\locale_hack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
Reference in New Issue
Block a user