Merge branch 'greenleon' of git.sv.gnu.org:/srv/git/libcdio

Conflicts:
	lib/driver/image/bincue.c
This commit is contained in:
R. Bernstein
2012-03-10 16:13:58 -05:00
32 changed files with 1672 additions and 1210 deletions

View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2004, 2005, 2006, 2008, 2009, 2011, 2012
Rocky Bernstein <rocky@gnu.org>
Rocky Bernstein <rocky@gnu.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
@@ -18,6 +18,9 @@
/* Simple program to list CD-Text info of a Compact Disc using
libcdio. See also corresponding C++ programs of similar names. */
#define EXAMPLE_CUE_FILE "../test/data/cat.cue"
#ifdef HAVE_CONFIG_H
#include "config.h"
#define __CDIO_CONFIG_H__ 1
@@ -40,8 +43,9 @@ print_cdtext_track_info(cdtext_t *cdtext, track_t i_track, const char *psz_msg)
printf("%s\n", psz_msg);
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
if (cdtext_get_const(i, i_track, cdtext)) {
printf("\t%s: %s\n", cdtext_field2str(i), cdtext_get_const(i, i_track, cdtext));
if (cdtext_get_const(cdtext, i, i_track)) {
printf("\t%s: %s\n", cdtext_field2str(i),
cdtext_get_const(cdtext, i, i_track));
}
}
@@ -52,8 +56,9 @@ print_disc_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) {
track_t i_last_track = i_first_track+i_tracks;
discmode_t cd_discmode = cdio_get_discmode(p_cdio);
cdtext_t *cdtext = cdio_get_cdtext(p_cdio);
int i;
printf("%s\n", discmode2str[cd_discmode]);
printf("Discmode: %s\n", discmode2str[cd_discmode]);
if (NULL == cdtext)
{
@@ -61,13 +66,33 @@ print_disc_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) {
return;
}
printf("Encoding: %s; Language: %s\n", cdtext->encoding, cdtext->language);
print_cdtext_track_info(cdtext, 0, "\nCD-Text for Disc:");
for ( ; i_first_track < i_last_track; i_first_track++ ) {
char psz_msg[50];
snprintf(psz_msg, sizeof(psz_msg), "CD-Text for Track %d:",
i_first_track);
print_cdtext_track_info(cdtext, i_first_track, psz_msg);
/* print available languages */
{
cdtext_lang_t *languages;
printf("\nCD-Text available in: ");
languages = cdtext_languages_available(cdtext);
for(i=0; i<8; i++)
if ( CDTEXT_LANGUAGE_UNKNOWN != languages[i])
printf("%s ", cdtext_lang2str(languages[i]));
printf("\n");
}
/* select language */
if(cdtext_select_language(cdtext, "German")) {
printf("%s selected.\n", "German");
} else {
printf("'%s' is not available. Using '%s'\n", "German",
cdtext_lang2str (cdtext_get_language (cdtext)));
}
/* print cd-text */
print_cdtext_track_info(cdtext, 0, "CD-Text for Disc:");
for (i=i_first_track ; i < i_last_track; i++ ) {
char psz_msg[50];
snprintf(psz_msg, sizeof(psz_msg), "CD-Text for Track %d:", i);
print_cdtext_track_info(cdtext, i, psz_msg);
}
}
@@ -76,11 +101,13 @@ main(int argc, const char *argv[])
{
track_t i_first_track;
track_t i_tracks;
CdIo_t *p_cdio = cdio_open ("../test/cdda.cue", DRIVER_BINCUE);
CdIo_t *p_cdio;
/* read CD-Text from a bin/cue (CDRWIN) image */
p_cdio = cdio_open(EXAMPLE_CUE_FILE, DRIVER_BINCUE);
if (NULL == p_cdio) {
printf("Couldn't open ../test/cdda.cue with BIN/CUE driver.\n");
printf("Couldn't open %s with BIN/CUE driver.\n",
EXAMPLE_CUE_FILE);
} else {
i_first_track = cdio_get_first_track_num(p_cdio);
i_tracks = cdio_get_num_tracks(p_cdio);
@@ -88,14 +115,14 @@ main(int argc, const char *argv[])
cdio_destroy(p_cdio);
}
/* read CD-Text from default device */
p_cdio = cdio_open (NULL, DRIVER_DEVICE);
i_first_track = cdio_get_first_track_num(p_cdio);
i_tracks = cdio_get_num_tracks(p_cdio);
if (NULL == p_cdio) {
printf("Couldn't find CD\n");
return 77;
} else {
i_first_track = cdio_get_first_track_num(p_cdio);
i_tracks = cdio_get_num_tracks(p_cdio);
print_disc_info(p_cdio, i_tracks, i_first_track);
}

View File

@@ -101,10 +101,9 @@ void possible_throw_device_exception(driver_return_code_t drc);
class CdioCDText
{
public:
CdioCDText(cdtext_t *p)
CdioCDText()
{
p_cdtext = p;
cdtext_init(p); // make sure we're initialized on the C side
p_cdtext = cdtext_init(); // make sure we're initialized on the C side
}
~CdioCDText()

View File

@@ -28,6 +28,16 @@ const char *field2str (cdtext_field_t i)
return cdtext_field2str (i);
}
const char *genre2str (cdtext_genre_t i)
{
return cdtext_genre2str (i);
}
const char *lang2str (cdtext_lang_t i)
{
return cdtext_lang2str (i);
}
/*! returns an allocated string associated with the given field. NULL is
returned if key is CDTEXT_INVALID or the field is not set.
@@ -39,7 +49,7 @@ const char *field2str (cdtext_field_t i)
*/
char *get (cdtext_field_t key, track_t i_track)
{
return cdtext_get (key, i_track, p_cdtext);
return cdtext_get (p_cdtext, key, i_track);
}
/*! returns the C cdtext_t pointer associated with this object. */
@@ -60,24 +70,15 @@ cdtext_t *get ()
*/
const char *getConst (cdtext_field_t key, track_t i_track)
{
return cdtext_get_const (key, i_track, p_cdtext);
}
/*!
returns enum of keyword if key is a CD-Text keyword,
returns MAX_CDTEXT_FIELDS non-zero otherwise.
*/
cdtext_field_t isKeyword (const char *key)
{
return cdtext_is_keyword (key);
return cdtext_get_const (p_cdtext, key, i_track);
}
/*!
sets cdtext's keyword entry to field
*/
void set (cdtext_field_t key, track_t i_track, const char *value)
void set (cdtext_field_t key, track_t i_track, const uint8_t *value, const char *charset)
{
cdtext_set (key, i_track, value, p_cdtext);
cdtext_set (p_cdtext, key, value, i_track, charset);
}

View File

@@ -45,8 +45,6 @@ extern "C" {
/** This is an opaque structure for the CD object. */
typedef struct _CdIo CdIo_t;
typedef struct cdtext_s cdtext_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -56,6 +54,9 @@ extern "C" {
*/
#include <cdio/device.h>
/* CD-Text-related functions. */
#include <cdio/cdtext.h>
/* Disc-related functions. */
#include <cdio/disc.h>
@@ -64,9 +65,6 @@ extern "C" {
*/
#include <cdio/read.h>
/* CD-Text-related functions. */
#include <cdio/cdtext.h>
/* Track-related functions. */
#include <cdio/track.h>

View File

@@ -29,139 +29,278 @@
#ifndef __CDIO_CDTEXT_H__
#define __CDIO_CDTEXT_H__
#include <cdio/cdio.h>
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MAX_CDTEXT_FIELDS 13
#define MIN_CDTEXT_FIELD 0
#define MAX_CDTEXT_DATA_LENGTH 5000
#define MAX_CDTEXT_GENRE_CODE 28
#define MAX_CDTEXT_FIELDS 10
/*! Enumeration of CD-TEXT text fields. */
typedef enum {
CDTEXT_FIELD_TITLE = 0, /**< title of album name or track titles */
CDTEXT_FIELD_PERFORMER = 1, /**< name(s) of the performer(s) */
CDTEXT_FIELD_SONGWRITER = 2, /**< name(s) of the songwriter(s) */
CDTEXT_FIELD_COMPOSER = 3, /**< name(s) of the composer(s) */
CDTEXT_FIELD_MESSAGE = 4, /**< message(s) from content provider or artist, ISO-8859-1 encoded*/
CDTEXT_FIELD_ARRANGER = 5, /**< name(s) of the arranger(s) */
CDTEXT_FIELD_ISRC = 6, /**< ISRC code of each track */
CDTEXT_FIELD_UPC_EAN = 7, /**< upc/european article number of disc, ISO-8859-1 encoded */
CDTEXT_FIELD_GENRE = 8, /**< genre identification and genre information, ASCII encoded */
CDTEXT_FIELD_DISCID = 9, /**< disc identification, ASCII encoded (may be non-printable) */
CDTEXT_FIELD_INVALID = MAX_CDTEXT_FIELDS /**< INVALID FIELD*/
} cdtext_field_t;
/*! Enumeration of possible genre codes. */
typedef enum {
CDTEXT_GENRE_UNUSED = 0, /**< field is not used. default */
CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
CDTEXT_GENRE_ADULT_CONTEMP = 2, /**< Adult Contemporary */
CDTEXT_GENRE_ALT_ROCK = 3, /**< Alternative Rock */
CDTEXT_GENRE_CHILDRENS = 4, /**< Childrens Music */
CDTEXT_GENRE_CLASSIC = 5, /**< Classical */
CDTEXT_GENRE_CHRIST_CONTEMP = 6, /**< Contemporary Christian */
CDTEXT_GENRE_COUNTRY = 7, /**< Country */
CDTEXT_GENRE_DANCE = 8, /**< Dance */
CDTEXT_GENRE_EASY_LISTENING = 9, /**< Easy Listening */
CDTEXT_GENRE_EROTIC = 10, /**< Erotic */
CDTEXT_GENRE_FOLK = 11, /**< Folk */
CDTEXT_GENRE_GOSPEL = 12, /**< Gospel */
CDTEXT_GENRE_HIPHOP = 13, /**< Hip Hop */
CDTEXT_GENRE_JAZZ = 14, /**< Jazz */
CDTEXT_GENRE_LATIN = 15, /**< Latin */
CDTEXT_GENRE_MUSICAL = 16, /**< Musical */
CDTEXT_GENRE_NEWAGE = 17, /**< New Age */
CDTEXT_GENRE_OPERA = 18, /**< Opera */
CDTEXT_GENRE_OPERETTA = 19, /**< Operetta */
CDTEXT_GENRE_POP = 20, /**< Pop Music */
CDTEXT_GENRE_RAP = 21, /**< RAP */
CDTEXT_GENRE_REGGAE = 22, /**< Reggae */
CDTEXT_GENRE_ROCK = 23, /**< Rock Music */
CDTEXT_GENRE_RYTHMANDBLUES = 24, /**< Rhythm & Blues */
CDTEXT_GENRE_SOUNDEFFECTS = 25, /**< Sound Effects */
CDTEXT_GENRE_SOUNDTRACK = 26, /**< Soundtrack */
CDTEXT_GENRE_SPOKEN_WORD = 27, /**< Spoken Word */
CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_t;
/*! Enumeration of possible CD-TEXT languages.
*
* The language code is encoded as specified in ANNEX 1 to part 5 of EBU
* Tech 32 58 -E (1991).
*/
typedef enum {
CDTEXT_LANGUAGE_UNKNOWN = 0x00,
CDTEXT_LANGUAGE_ALBANIAN = 0x01,
CDTEXT_LANGUAGE_BRETON = 0x02,
CDTEXT_LANGUAGE_CATALAN = 0x03,
CDTEXT_LANGUAGE_CROATIAN = 0x04,
CDTEXT_LANGUAGE_WELSH = 0x05,
CDTEXT_LANGUAGE_CZECH = 0x06,
CDTEXT_LANGUAGE_DANISH = 0x07,
CDTEXT_LANGUAGE_GERMAN = 0x08,
CDTEXT_LANGUAGE_ENGLISH = 0x09,
CDTEXT_LANGUAGE_SPANISH = 0x0A,
CDTEXT_LANGUAGE_ESPERANTO = 0x0B,
CDTEXT_LANGUAGE_ESTONIAN = 0x0C,
CDTEXT_LANGUAGE_BASQUE = 0x0D,
CDTEXT_LANGUAGE_FAROESE = 0x0E,
CDTEXT_LANGUAGE_FRENCH = 0x0F,
CDTEXT_LANGUAGE_FRISIAN = 0x10,
CDTEXT_LANGUAGE_IRISH = 0x11,
CDTEXT_LANGUAGE_GAELIC = 0x12,
CDTEXT_LANGUAGE_GALICIAN = 0x13,
CDTEXT_LANGUAGE_ICELANDIC = 0x14,
CDTEXT_LANGUAGE_ITALIAN = 0x15,
CDTEXT_LANGUAGE_LAPPISH = 0x16,
CDTEXT_LANGUAGE_LATIN = 0x17,
CDTEXT_LANGUAGE_LATVIAN = 0x18,
CDTEXT_LANGUAGE_LUXEMBOURGIAN = 0x19,
CDTEXT_LANGUAGE_LITHUANIAN = 0x1A,
CDTEXT_LANGUAGE_HUNGARIAN = 0x1B,
CDTEXT_LANGUAGE_MALTESE = 0x1C,
CDTEXT_LANGUAGE_DUTCH = 0x1D,
CDTEXT_LANGUAGE_NORWEGIAN = 0x1E,
CDTEXT_LANGUAGE_OCCITAN = 0x1F,
CDTEXT_LANGUAGE_POLISH = 0x20,
CDTEXT_LANGUAGE_PORTUGUESE = 0x21,
CDTEXT_LANGUAGE_ROMANIAN = 0x22,
CDTEXT_LANGUAGE_ROMANSH = 0x23,
CDTEXT_LANGUAGE_SERBIAN = 0x24,
CDTEXT_LANGUAGE_SLOVAK = 0x25,
CDTEXT_LANGUAGE_SLOVENIAN = 0x26,
CDTEXT_LANGUAGE_FINNISH = 0x27,
CDTEXT_LANGUAGE_SWEDISH = 0x28,
CDTEXT_LANGUAGE_TURKISH = 0x29,
CDTEXT_LANGUAGE_FLEMISH = 0x2A,
CDTEXT_LANGUAGE_WALLON = 0x2B,
CDTEXT_LANGUAGE_ZULU = 0x45,
CDTEXT_LANGUAGE_VIETNAMESE = 0x46,
CDTEXT_LANGUAGE_UZBEK = 0x47,
CDTEXT_LANGUAGE_URDU = 0x48,
CDTEXT_LANGUAGE_UKRAINIAN = 0x49,
CDTEXT_LANGUAGE_THAI = 0x4A,
CDTEXT_LANGUAGE_TELUGU = 0x4B,
CDTEXT_LANGUAGE_TATAR = 0x4C,
CDTEXT_LANGUAGE_TAMIL = 0x4D,
CDTEXT_LANGUAGE_TADZHIK = 0x4E,
CDTEXT_LANGUAGE_SWAHILI = 0x4F,
CDTEXT_LANGUAGE_SRANANTONGO = 0x50,
CDTEXT_LANGUAGE_SOMALI = 0x51,
CDTEXT_LANGUAGE_SINHALESE = 0x52,
CDTEXT_LANGUAGE_SHONA = 0x53,
CDTEXT_LANGUAGE_SERBO_CROAT = 0x54,
CDTEXT_LANGUAGE_RUTHENIAN = 0x55,
CDTEXT_LANGUAGE_RUSSIAN = 0x56,
CDTEXT_LANGUAGE_QUECHUA = 0x57,
CDTEXT_LANGUAGE_PUSHTU = 0x58,
CDTEXT_LANGUAGE_PUNJABI = 0x59,
CDTEXT_LANGUAGE_PERSIAN = 0x5A,
CDTEXT_LANGUAGE_PAPAMIENTO = 0x5B,
CDTEXT_LANGUAGE_ORIYA = 0x5C,
CDTEXT_LANGUAGE_NEPALI = 0x5D,
CDTEXT_LANGUAGE_NDEBELE = 0x5E,
CDTEXT_LANGUAGE_MARATHI = 0x5F,
CDTEXT_LANGUAGE_MOLDAVIAN = 0x60,
CDTEXT_LANGUAGE_MALAYSIAN = 0x61,
CDTEXT_LANGUAGE_MALAGASAY = 0x62,
CDTEXT_LANGUAGE_MACEDONIAN = 0x63,
CDTEXT_LANGUAGE_LAOTIAN = 0x64,
CDTEXT_LANGUAGE_KOREAN = 0x65,
CDTEXT_LANGUAGE_KHMER = 0x66,
CDTEXT_LANGUAGE_KAZAKH = 0x67,
CDTEXT_LANGUAGE_KANNADA = 0x68,
CDTEXT_LANGUAGE_JAPANESE = 0x69,
CDTEXT_LANGUAGE_INDONESIAN = 0x6A,
CDTEXT_LANGUAGE_HINDI = 0x6B,
CDTEXT_LANGUAGE_HEBREW = 0x6C,
CDTEXT_LANGUAGE_HAUSA = 0x6D,
CDTEXT_LANGUAGE_GURANI = 0x6E,
CDTEXT_LANGUAGE_GUJURATI = 0x6F,
CDTEXT_LANGUAGE_GREEK = 0x70,
CDTEXT_LANGUAGE_GEORGIAN = 0x71,
CDTEXT_LANGUAGE_FULANI = 0x72,
CDTEXT_LANGUAGE_DARI = 0x73,
CDTEXT_LANGUAGE_CHURASH = 0x74,
CDTEXT_LANGUAGE_CHINESE = 0x75,
CDTEXT_LANGUAGE_BURMESE = 0x76,
CDTEXT_LANGUAGE_BULGARIAN = 0x77,
CDTEXT_LANGUAGE_BENGALI = 0x78,
CDTEXT_LANGUAGE_BIELORUSSIAN = 0x79,
CDTEXT_LANGUAGE_BAMBORA = 0x7A,
CDTEXT_LANGUAGE_AZERBAIJANI = 0x7B,
CDTEXT_LANGUAGE_ASSAMESE = 0x7C,
CDTEXT_LANGUAGE_ARMENIAN = 0x7D,
CDTEXT_LANGUAGE_ARABIC = 0x7E,
CDTEXT_LANGUAGE_AMHARIC = 0x7F
} cdtext_lang_t;
/*!
Opaque type for CD-Text.
*/
typedef struct cdtext_s cdtext_t;
/*!
Return string representation of the given genre code.
*/
const char *cdtext_genre2str (cdtext_genre_t i);
/*!
Return string representation of the given language code.
*/
const char *cdtext_lang2str (cdtext_lang_t i);
/*!
Return string representation of given field type.
*/
const char *cdtext_field2str (cdtext_field_t i);
/*!
Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
cdtext_t *cdtext_init (void);
/*!
Read a binary CD-TEXT and fill a cdtext struct.
@param p_cdtext the CD-TEXT object
@param wdata the data
@param i_data size of wdata
@returns 0 on success, non-zero on failure
*/
int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t length);
/*!
Free memory associated with the given cdtext_t object.
@param p_cdtext the CD-TEXT object
*/
void cdtext_destroy (cdtext_t *p_cdtext);
/*!
Returns a copy of the return value of cdtext_get_const or NULL.
Should be freed when done.
@see cdtext_get_const
*/
char *cdtext_get (const cdtext_t *p_cdtext, cdtext_field_t key, track_t track);
/*!
Returns value of the given field.
NULL is returned if key is CDTEXT_INVALID or the field is not set.
Strings are encoded in UTF-8.
@param p_cdtext the CD-TEXT object
@param field type of the field to return
@param track specifies the track, 0 stands for disc
*/
const char *cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t key, track_t track);
/*!
Returns the currently active language.
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t cdtext_get_language (const cdtext_t *p_cdtext);
/*!
Try to select the given language.
@param p_cdtext the CD-TEXT object
@param language string representation of the language
@return true on success, false if language is not available
*/
bool cdtext_select_language(cdtext_t *p_cdtext, const char *lang);
/*
Returns a list of available languages or NULL.
Internally the list is stored in a static array.
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t *cdtext_languages_available (const cdtext_t *p_cdtext);
/*!
Sets the given field at the given track to the given value.
/*! \brief structure for holding CD-Text information
@see cdtext_init, cdtext_destroy, cdtext_get, and cdtext_set.
*/
struct cdtext {
char *field[MAX_CDTEXT_FIELDS];
};
typedef struct cdtext cdtext_track_t;
struct cdtext_s {
cdtext_track_t track[100]; /* cdtext for track 1..99. 0 represents cd-text of disc */
uint16_t genre_code; /* genre code */
uint8_t block;
char encoding[16]; /* encoding of character strings */
char language[3]; /* ISO 639-1 (2 letter) language code */
};
Recodes to UTF-8 if charset is not NULL.
/*! \brief A list of all of the CD-Text fields. Because
the interval has no gaps, we can use ++ to iterate over fields.
*/
typedef enum {
CDTEXT_ARRANGER = 0, /**< name(s) of the arranger(s) */
CDTEXT_COMPOSER = 1, /**< name(s) of the composer(s) */
CDTEXT_DISCID = 2, /**< disc identification information */
CDTEXT_GENRE = 3, /**< genre identification and genre information */
CDTEXT_MESSAGE = 4, /**< ISRC code of each track */
CDTEXT_ISRC = 5, /**< message(s) from the content provider or artist */
CDTEXT_PERFORMER = 6, /**< name(s) of the performer(s) */
CDTEXT_SIZE_INFO = 7, /**< size information of the block */
CDTEXT_SONGWRITER = 8, /**< name(s) of the songwriter(s) */
CDTEXT_TITLE = 9, /**< title of album name or track titles */
CDTEXT_TOC_INFO = 10, /**< table of contents information */
CDTEXT_TOC_INFO2 = 11, /**< second table of contents information */
CDTEXT_UPC_EAN = 12,
CDTEXT_INVALID = MAX_CDTEXT_FIELDS
} cdtext_field_t;
@param p_cdtext the CD-TEXT object
@param key field to set
@param value value to set
@param track track to work on
@param charset charset to convert from
*/
void cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset);
/*! Return string representation of the enum values above */
const char *cdtext_field2str (cdtext_field_t i);
/*! CD-Text genre codes */
typedef enum {
CDIO_CDTEXT_GENRE_UNUSED = 0, /**< not used */
CDIO_CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
CDIO_CDTEXT_GENRE_ADULT_CONTEMP = 2, /**< Adult Contemporary */
CDIO_CDTEXT_GENRE_ALT_ROCK = 3, /**< Alternative Rock */
CDIO_CDTEXT_GENRE_CHILDRENS = 4, /**< Childrens Music */
CDIO_CDTEXT_GENRE_CLASSIC = 5, /**< Classical */
CDIO_CDTEXT_GENRE_CHRIST_CONTEMP = 6, /**< Contemporary Christian */
CDIO_CDTEXT_GENRE_COUNTRY = 7, /**< Country */
CDIO_CDTEXT_GENRE_DANCE = 8, /**< Dance */
CDIO_CDTEXT_GENRE_EASY_LISTENING = 9, /**< Easy Listening */
CDIO_CDTEXT_GENRE_EROTIC = 10, /**< Erotic */
CDIO_CDTEXT_GENRE_FOLK = 11, /**< Folk */
CDIO_CDTEXT_GENRE_GOSPEL = 12, /**< Gospel */
CDIO_CDTEXT_GENRE_HIPHOP = 13, /**< Hip Hop */
CDIO_CDTEXT_GENRE_JAZZ = 14, /**< Jazz */
CDIO_CDTEXT_GENRE_LATIN = 15, /**< Latin */
CDIO_CDTEXT_GENRE_MUSICAL = 16, /**< Musical */
CDIO_CDTEXT_GENRE_NEWAGE = 17, /**< New Age */
CDIO_CDTEXT_GENRE_OPERA = 18, /**< Opera */
CDIO_CDTEXT_GENRE_OPERETTA = 19, /**< Operetta */
CDIO_CDTEXT_GENRE_POP = 20, /**< Pop Music */
CDIO_CDTEXT_GENRE_RAP = 21, /**< RAP */
CDIO_CDTEXT_GENRE_REGGAE = 22, /**< Reggae */
CDIO_CDTEXT_GENRE_ROCK = 23, /**< Rock Music */
CDIO_CDTEXT_GENRE_RYTHMANDBLUES = 24, /**< Rhythm & Blues */
CDIO_CDTEXT_GENRE_SOUNDEFFECTS = 25, /**< Sound Effects */
CDIO_CDTEXT_GENRE_SOUNDTRACK = 26, /**< Soundtrack */
CDIO_CDTEXT_GENRE_SPOKEN_WORD = 27, /**< Spoken Word */
CDIO_CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_t;
/*! Return string representation of the given genre code */
const char *cdtext_genre2str (cdtext_genre_t i);
/*! Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
void cdtext_init (cdtext_t *cdtext);
/*! Parse raw CD-Text data into cdtext structure */
bool cdtext_data_init(cdtext_t *cdtext, uint8_t *wdata, size_t length);
/*! Free memory assocated with cdtext*/
void cdtext_destroy (cdtext_t *cdtext);
/*! returns an allocated string associated with the given field. NULL is
returned if key is CDTEXT_INVALID or the field is not set.
The user needs to free the string when done with it.
@see cdio_get_const to retrieve a constant string that doesn't
have to be freed.
*/
char *cdtext_get (cdtext_field_t key, track_t track, const cdtext_t *cdtext);
/*! returns a const string associated with the given field. NULL is
returned if key is CDTEXT_INVALID or the field is not set.
Don't use the string when the cdtext object (i.e. the CdIo_t object
you got it from) is no longer valid.
@see cdio_get to retrieve an allocated string that persists past
the cdtext object.
*/
const char *cdtext_get_const (cdtext_field_t key, track_t track, const cdtext_t *cdtext);
/*!
returns enum of keyword if key is a CD-Text keyword,
returns MAX_CDTEXT_FIELDS non-zero otherwise.
*/
cdtext_field_t cdtext_is_keyword (const char *key);
/*!
sets cdtext's keyword entry to field
*/
void cdtext_set (cdtext_field_t key, track_t track, const char *value, cdtext_t *cdtext);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -56,6 +56,7 @@ extern "C" {
} discmode_t;
extern const char *discmode2str[];
/**
Get binary CD-Text information for a CdIo_t object.

View File

@@ -1,6 +1,4 @@
/*
$Id: track.h,v 1.14 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify

View File

@@ -87,7 +87,7 @@ bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst,
*/
bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst,
bool cdio_charset_to_utf8(const char *src, size_t src_len, cdio_utf8_t **dst,
const char * src_charset);
#ifdef _WIN32

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) 2004, 2005, 2008, 2009, 2010 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2008, 2009, 2010, 2012
Rocky Bernstein <rocky@gnu.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

View File

@@ -50,7 +50,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "aspi32.h"
#include "cdtext_private.h"
/* Amount of time we are willing to wait for an operation to complete.
10 seconds?

View File

@@ -189,14 +189,6 @@ track_format_t get_track_format_aspi(const _img_private_t *env,
*/
bool init_aspi (_img_private_t *env);
/*
Read cdtext information for a CdIo object .
return true on success, false on error or CD-TEXT information does
not exist.
*/
bool init_cdtext_aspi (_img_private_t *env);
const char *is_cdrom_aspi(const char drive_letter);
/*!

View File

@@ -25,7 +25,6 @@ typedef struct {
lsn_t start_lsn;
UCHAR Control : 4;
UCHAR Format;
cdtext_t cdtext; /* CD-TEXT */
} track_info_t;
typedef enum {
@@ -197,14 +196,6 @@ bool read_toc_win32ioctl (_img_private_t *p_env);
*/
char *get_mcn_win32ioctl (const _img_private_t *p_env);
/*
Read cdtext information for a CdIo object .
return true on success, false on error or CD-TEXT information does
not exist.
*/
bool init_cdtext_win32ioctl (_img_private_t *p_env);
/*!
Return the the kind of drive capabilities of device.
@@ -234,8 +225,3 @@ void get_drive_cap_win32ioctl (const _img_private_t *p_env,
*/
track_format_t get_track_format_win32ioctl(const _img_private_t *p_env,
track_t i_track);
void set_cdtext_field_win32(void *user_data, track_t i_track,
track_t i_first_track,
cdtext_field_t e_field, const char *psz_value);

View File

@@ -58,7 +58,6 @@
#include <cdio/util.h>
#include "cdio_assert.h"
#include <cdio/mmc.h>
#include "cdtext_private.h"
#include "cdio/logging.h"
#if defined (_XBOX)

View File

@@ -286,8 +286,7 @@ get_cdtext_generic (void *p_user_data)
if (NULL == p_env->cdtext) {
p_cdtext_data = read_cdtext_generic (p_env);
if (NULL != p_cdtext_data) {
p_env->cdtext = malloc (sizeof(cdtext_t));
cdtext_init(p_env->cdtext);
p_env->cdtext = cdtext_init();
len = CDIO_MMC_GET_LEN16(p_cdtext_data);
if(!cdtext_data_init (p_env->cdtext, &p_cdtext_data[4], len-2)) {

View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 2004, 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2008, 2011, 2012 Rocky Bernstein <rocky@gnu.org>
toc reading routine adapted from cuetools
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
@@ -25,6 +25,7 @@
#include <cdio/cdtext.h>
#include <cdio/logging.h>
#include "cdtext_private.h"
#include <cdio/utf8.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -33,32 +34,30 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#define _CDTEXT_DBCC
#define MAX_CDTEXT_GENRE_CODE 28
#define MAX_CDTEXT_LANGUAGE_CODE 127
/*! Note: the order and number items (except CDTEXT_INVALID) should
match the cdtext_field_t enumeration. */
static const char cdtext_keywords[][16] =
#ifndef CDIO_CD_MAX_TRACKS
# define CDIO_CD_MAX_TRACKS 99 /* Largest CD track number */
#endif
const char *cdtext_field[MAX_CDTEXT_FIELDS] =
{
"ARRANGER",
"COMPOSER",
"DISC_ID",
"GENRE",
"MESSAGE",
"ISRC",
"PERFORMER",
"SIZE_INFO",
"SONGWRITER",
"TITLE",
"TOC_INFO",
"TOC_INFO2",
"PERFORMER",
"SONGWRITER",
"COMPOSER",
"MESSAGE",
"ARRANGER",
"ISRC",
"UPC_EAN",
"GENRE",
"DISC_ID",
};
static const char cdtext_genre[][30] =
const char *cdtext_genre[MAX_CDTEXT_GENRE_CODE] =
{
"Not Used",
"Not Defined",
@@ -90,349 +89,651 @@ static const char cdtext_genre[][30] =
"World Music"
};
/*! Return string representation of the enum values above */
const char *cdtext_language[MAX_CDTEXT_LANGUAGE_CODE] =
{
"Unknown",
"Albanian",
"Breton",
"Catalan",
"Croatian",
"Welsh",
"Czech",
"Danish",
"German",
"English",
"Spanish",
"Esperanto",
"Estonian",
"Basque",
"Faroese",
"French",
"Frisian",
"Irish",
"Gaelic",
"Galician",
"Icelandic",
"Italian",
"Lappish",
"Latin",
"Latvian",
"Luxembourgian",
"Lithuanian",
"Hungarian",
"Maltese",
"Dutch",
"Norwegian",
"Occitan",
"Polish",
"Portuguese",
"Romanian",
"Romansh",
"Serbian",
"Slovak",
"Slovenian",
"Finnish",
"Swedish",
"Turkish",
"Flemish",
"Wallon",
"Zulu",
"Vietnamese",
"Uzbek",
"Urdu",
"Ukrainian",
"Thai",
"Telugu",
"Tatar",
"Tamil",
"Tadzhik",
"Swahili",
"SrananTongo",
"Somali",
"Sinhalese",
"Shona",
"Serbo-croat",
"Ruthenian",
"Russian",
"Russian",
"Quechua",
"Pushtu",
"Punjabi",
"Persian",
"Papamiento",
"Oriya",
"Nepali",
"Ndebele",
"Marathi",
"Moldavian",
"Malaysian",
"Malagasay",
"Macedonian",
"Laotian",
"Korean",
"Khmer",
"Kazakh",
"Kannada",
"Japanese",
"Indonesian",
"Hindi",
"Hebrew",
"Hausa",
"Gurani",
"Gujurati",
"Greek",
"Georgian",
"Fulani",
"Dari",
"Churash",
"Chinese",
"Burmese",
"Bulgarian",
"Bengali",
"Bielorussian",
"Bambora",
"Azerbaijani",
"Assamese",
"Armenian",
"Arabic",
"Amharic"
};
/*!
Return string representation of given field type.
*/
const char *
cdtext_field2str (cdtext_field_t i)
cdtext_field2str(cdtext_field_t i)
{
if (i >= MAX_CDTEXT_FIELDS)
return "Invalid CDTEXT field index";
return "INVALID";
else
return cdtext_keywords[i];
return cdtext_field[i];
}
/*! Return string representation of the given genre oode */
/*!
Return string representation of the given genre code.
*/
const char *
cdtext_genre2str (cdtext_genre_t i)
cdtext_genre2str(cdtext_genre_t i)
{
if (i >= MAX_CDTEXT_GENRE_CODE)
return "Invalid genre code";
return "INVALID";
else
return cdtext_genre[i];
}
/*! Free memory assocated with cdtext*/
void
cdtext_destroy (cdtext_t *p_cdtext)
/*!
Return string representation of the given language code.
*/
const char *
cdtext_lang2str(cdtext_lang_t i)
{
cdtext_field_t i;
track_t i2;
if (i >= MAX_CDTEXT_LANGUAGE_CODE)
return "INVALID";
else
return cdtext_language[i];
}
/*!
Free memory associated with the given cdtext_t object.
@param p_cdtext the CD-TEXT object
*/
void
cdtext_destroy(cdtext_t *p_cdtext)
{
cdtext_field_t k;
track_t j;
int i;
if (!p_cdtext) return;
for (i2=0; i2<=99; i2++) {
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
if (p_cdtext->track[i2].field[i]) {
free(p_cdtext->track[i2].field[i]);
p_cdtext->track[i2].field[i] = NULL;
for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
for (j=0; j<CDTEXT_NUM_TRACKS_MAX; j++) {
for (k=0; k < MAX_CDTEXT_FIELDS; k++) {
if (p_cdtext->block[i].track[j].field[k]) {
free(p_cdtext->block[i].track[j].field[k]);
p_cdtext->block[i].track[j].field[k] = NULL;
}
}
}
}
}
/*!
returns the CDTEXT value associated with key. NULL is returned
if key is CDTEXT_INVALID or the field is not set.
*/
/*!
Returns a copy of the return value of cdtext_get_const or NULL.
Should be freed when done.
@see cdtext_get_const
*/
char *
cdtext_get (cdtext_field_t key, track_t track, const cdtext_t *p_cdtext)
cdtext_get(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
{
const char *ret = cdtext_get_const(key, track, p_cdtext);
const char *ret = cdtext_get_const(p_cdtext, field, track);
if (NULL == ret)
return NULL;
else
return strdup(ret);
}
/*!
Returns value of the given field.
NULL is returned if key is CDTEXT_INVALID or the field is not set.
Strings are encoded in UTF-8.
@param p_cdtext the CD-TEXT object
@param field type of the field to return
@param track specifies the track, 0 stands for disc
*/
const char *
cdtext_get_const (cdtext_field_t key, track_t track, const cdtext_t *p_cdtext)
cdtext_get_const(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
{
if (CDTEXT_INVALID == key
if (CDTEXT_FIELD_INVALID == field
|| NULL == p_cdtext
|| 0 > track
|| 99 < track)
|| CDIO_CD_MAX_TRACKS < track)
return NULL;
return p_cdtext->track[track].field[key];
return p_cdtext->block[p_cdtext->block_i].track[track].field[field];
}
/*! Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
void
cdtext_init (cdtext_t *p_cdtext)
{
cdtext_field_t i;
track_t i2;
/*!
Returns the currently active language.
for (i2=0; i2<=99; i2++) {
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
p_cdtext->track[i2].field[i] = NULL;
}
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t
cdtext_get_language(const cdtext_t *p_cdtext)
{
if (NULL == p_cdtext)
return CDTEXT_LANGUAGE_UNKNOWN;
return p_cdtext->block[p_cdtext->block_i].language_code;
}
/*
Returns a list of available languages or NULL.
Internally the list is stored in a static array.
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t
*cdtext_languages_available(const cdtext_t *p_cdtext)
{
static cdtext_lang_t avail[CDTEXT_NUM_BLOCKS_MAX];
int i, j=0;
if (NULL == p_cdtext)
return NULL;
for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++)
{
avail[i] = CDTEXT_LANGUAGE_UNKNOWN;
if (CDTEXT_LANGUAGE_UNKNOWN != p_cdtext->block[i].language_code)
avail[j++] = p_cdtext->block[i].language_code;
}
p_cdtext->genre_code = CDIO_CDTEXT_GENRE_UNUSED;
p_cdtext->language[0] = '\0';
p_cdtext->encoding[0] = '\0';
p_cdtext->block = 0;
return avail;
}
/*!
returns associated cdtext_field_t if field is a CD-TEXT keyword, returns non-zero otherwise
Try to select the given language.
Select default language if specified is not available or invalid and
return false.
@param p_cdtext the CD-TEXT object
@param language string representation of the language
@return true on success, false if language is not available
*/
bool
cdtext_select_language(cdtext_t *p_cdtext, const char *language)
{
cdtext_lang_t lang_id;
lang_id = cdtext_is_language(language);
if(NULL == p_cdtext)
return false;
if (CDTEXT_LANGUAGE_UNKNOWN != lang_id)
{
int i;
for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
if (lang_id == p_cdtext->block[i].language_code) {
p_cdtext->block_i = i;
return true;
}
}
} else {
p_cdtext->block_i = 0;
}
return false;
}
/*!
Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
cdtext_t
*cdtext_init(void)
{
cdtext_field_t k;
track_t j;
int i;
cdtext_t *p_cdtext;
p_cdtext = (cdtext_t *) malloc(sizeof(struct cdtext_s));
for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
for (j=0; j<CDTEXT_NUM_TRACKS_MAX; j++) {
for (k=0; k < MAX_CDTEXT_FIELDS; k++) {
p_cdtext->block[i].track[j].field[k] = NULL;
}
}
p_cdtext->block[i].genre_code = CDTEXT_GENRE_UNUSED;
p_cdtext->block[i].language_code = CDTEXT_LANGUAGE_UNKNOWN;
}
p_cdtext->block_i = 0;
return p_cdtext;
}
/*!
Returns associated cdtext_field_t if field is a CD-TEXT keyword.
Internal function.
@param key key to test
@return CDTEXT_INVALID if the given keyword is invalid
*/
cdtext_field_t
cdtext_is_keyword (const char *key)
cdtext_is_field (const char *key)
{
unsigned int i;
for (i = 0; i < 13 ; i++)
if (0 == strcmp (cdtext_keywords[i], key)) {
for (i = 0; i < MAX_CDTEXT_FIELDS ; i++)
if (0 == strcmp(cdtext_field[i], key)) {
return i;
}
return CDTEXT_INVALID;
return CDTEXT_FIELD_INVALID;
}
/*! sets cdtext's keyword entry to field.
/*!
Returns associated cdtext_lang_t if argument is a supported language.
Internal function.
@param lang language to test
@return CDTEXT_LANGUAGE_UNKNOWN if language is not supported
*/
cdtext_lang_t
cdtext_is_language(const char *lang)
{
unsigned int i;
for (i = 0; i < MAX_CDTEXT_LANGUAGE_CODE; i++)
if (0 == strcmp(cdtext_language[i], lang)) {
return i;
}
return CDTEXT_LANGUAGE_UNKNOWN;
}
/*!
Sets the given field at the given track to the given value.
Recodes to UTF-8 if charset is not NULL.
@param p_cdtext the CD-TEXT object
@param key field to set
@param value value to set
@param track track to work on
@param charset charset to convert from
*/
void
cdtext_set (cdtext_field_t key, track_t track, const char *p_value, cdtext_t *p_cdtext)
cdtext_set(cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value,
track_t track, const char *charset)
{
if (NULL == p_value || key == CDTEXT_INVALID || 0 > track || 99 < track) return;
if (NULL == value || key == CDTEXT_FIELD_INVALID || 0 > track
|| CDIO_CD_MAX_TRACKS < track)
return;
if (p_cdtext->track[track].field[key])
free (p_cdtext->track[track].field[key]);
p_cdtext->track[track].field[key] = strdup (p_value);
/* free old memory */
if (p_cdtext->block[p_cdtext->block_i].track[track].field[key])
free(p_cdtext->block[p_cdtext->block_i].track[track].field[key]);
/* recode to UTF-8 */
if (NULL != charset) {
cdio_utf8_t *utf8_str = NULL;
cdio_charset_to_utf8((const char*) value, strlen((const char*)value),
&utf8_str, charset);
p_cdtext->block[p_cdtext->block_i].track[track].field[key] = (char *)utf8_str;
} else
p_cdtext->block[p_cdtext->block_i].track[track].field[key] = strdup((const char *)value);
}
#define SET_CDTEXT_FIELD(FIELD) \
cdtext_set(FIELD, i_track, buffer, p_cdtext);
/*!
Read a binary CD-TEXT and fill a cdtext struct.
/*
parse all CD-TEXT data retrieved.
@param p_cdtext the CD-TEXT object
@param wdata the data
@param i_data size of wdata
@returns 0 on success, non-zero on failure
*/
bool
int
cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data)
{
CDText_data_t *p_data;
int i;
uint8_t *p_data;
int j;
char buffer[256];
int idx;
int i_track;
bool b_ret = false;
int block = 0;
CDText_blocksize_t p_blocksize;
memset( buffer, 0x00, sizeof(buffer) );
idx = 0;
memset( &p_blocksize, 0x00, sizeof(CDText_blocksize_t) );
uint8_t buffer[256];
int i_buf = 0;
int i_block;
int i_seq = 0;
int i;
cdtext_blocksize_t blocksize;
char *charset = NULL;
p_data = (CDText_data_t *) wdata;
if (0 != i_data % sizeof(CDText_data_t)) {
memset( buffer, 0, sizeof(buffer) );
p_data = wdata;
if (i_data < CDTEXT_LEN_PACK || 0 != i_data % CDTEXT_LEN_PACK) {
cdio_warn("CD-Text size is not multiple of pack size");
return false;
return -1;
}
for( i = -1; i_data > 0; i_data -= sizeof(CDText_data_t), p_data++ ) {
#ifndef _CDTEXT_DBCC
if ( p_data->bDBC ) {
cdio_warn("Double-byte characters not supported");
return false;
}
#if 0
for(i=0; i < i_data; i++)
printf("%0x%c", wdata[i], ((i+1) % 18 == 0 ? '\n' : ' '));
#endif
if ( p_data->seq != ++i || p_data->block != block ) break;
/* only handle character packs */
if ( ((p_data->type >= 0x80) && (p_data->type <= 0x87)) ||
(p_data->type == 0x8E))
{
i_track = p_data->i_track;
/* Iterate over blocks */
i_block = -1;
while(i_data > 0) {
cdtext_pack_t pack;
cdtext_read_pack(&pack, p_data);
j = 0;
if (CDIO_CDTEXT_GENRE == p_data->type) {
j = 2;
if (CDIO_CDTEXT_GENRE_UNUSED == p_cdtext->genre_code) {
p_cdtext->genre_code = CDTEXT_GET_LEN16(p_data->text);
}
if (i_block != pack.block || i_seq != pack.seq) {
cdtext_pack_t tpack;
i_block = pack.block;
if (i_block >= CDTEXT_NUM_BLOCKS_MAX) {
cdio_warn("CD-TEXT: Invalid blocknumber %d.\n", i_block);
return -1;
}
p_cdtext->block_i = i_block;
i_seq = 0;
memset( &blocksize, 0, CDTEXT_LEN_BLOCKSIZE);
#ifdef _CDTEXT_DBCC
for( ; j < CDIO_CDTEXT_MAX_TEXT_DATA; (p_data->bDBC ? j+=2 : j++) ) {
if( p_data->text[j] == 0x00 && (!p_data->bDBC || p_data->text[j+1] == 0x00)) {
if((buffer[0] != 0x00) && (!p_data->bDBC || buffer[1] != 0x00)) {
#else
for( ; j < CDIO_CDTEXT_MAX_TEXT_DATA; j++) {
if( p_data->text[j] == 0x00) {
if(buffer[0] != 0x00) {
#endif
/* omit empty strings */
switch( p_data->type) {
case CDIO_CDTEXT_TITLE:
SET_CDTEXT_FIELD(CDTEXT_TITLE);
/* first read block size information for sanity checks and encoding */
for(i=0; i <= i_data-CDTEXT_LEN_PACK; i+=CDTEXT_LEN_PACK) {
if (p_data[i+0] == CDTEXT_PACK_BLOCKSIZE) {
cdtext_read_pack(&tpack, p_data+i);
switch (tpack.i_track) {
case 0:
blocksize.charcode = tpack.text[0];
blocksize.i_first_track = tpack.text[1];
blocksize.i_last_track = tpack.text[2];
blocksize.copyright = tpack.text[3];
blocksize.i_packs[0] = tpack.text[4];
blocksize.i_packs[1] = tpack.text[5];
blocksize.i_packs[2] = tpack.text[6];
blocksize.i_packs[3] = tpack.text[7];
blocksize.i_packs[4] = tpack.text[8];
blocksize.i_packs[5] = tpack.text[9];
blocksize.i_packs[6] = tpack.text[10];
blocksize.i_packs[7] = tpack.text[11];
break;
case CDIO_CDTEXT_PERFORMER:
SET_CDTEXT_FIELD(CDTEXT_PERFORMER);
case 1:
blocksize.i_packs[8] = tpack.text[0];
blocksize.i_packs[9] = tpack.text[1];
blocksize.i_packs[10] = tpack.text[2];
blocksize.i_packs[11] = tpack.text[3];
blocksize.i_packs[12] = tpack.text[4];
blocksize.i_packs[13] = tpack.text[5];
blocksize.i_packs[14] = tpack.text[6];
blocksize.i_packs[15] = tpack.text[7];
blocksize.lastseq[0] = tpack.text[8];
blocksize.lastseq[1] = tpack.text[9];
blocksize.lastseq[2] = tpack.text[10];
blocksize.lastseq[3] = tpack.text[11];
break;
case CDIO_CDTEXT_SONGWRITER:
SET_CDTEXT_FIELD(CDTEXT_SONGWRITER);
case 2:
blocksize.lastseq[4] = tpack.text[0];
blocksize.lastseq[5] = tpack.text[1];
blocksize.lastseq[6] = tpack.text[2];
blocksize.lastseq[7] = tpack.text[3];
blocksize.langcode[0] = tpack.text[4];
blocksize.langcode[1] = tpack.text[5];
blocksize.langcode[2] = tpack.text[6];
blocksize.langcode[3] = tpack.text[7];
blocksize.langcode[4] = tpack.text[8];
blocksize.langcode[5] = tpack.text[9];
blocksize.langcode[6] = tpack.text[10];
blocksize.langcode[7] = tpack.text[11];
break;
case CDIO_CDTEXT_COMPOSER:
SET_CDTEXT_FIELD(CDTEXT_COMPOSER);
break;
case CDIO_CDTEXT_ARRANGER:
SET_CDTEXT_FIELD(CDTEXT_ARRANGER);
break;
case CDIO_CDTEXT_MESSAGE:
SET_CDTEXT_FIELD(CDTEXT_MESSAGE);
break;
case CDIO_CDTEXT_DISCID:
if(i_track == 0) {
SET_CDTEXT_FIELD(CDTEXT_DISCID);
}
break;
case CDIO_CDTEXT_UPC:
if(i_track == 0) {
SET_CDTEXT_FIELD(CDTEXT_UPC_EAN);
}
else {
SET_CDTEXT_FIELD(CDTEXT_ISRC);
}
break;
case CDIO_CDTEXT_GENRE:
SET_CDTEXT_FIELD(CDTEXT_GENRE);
break;
}
b_ret = true;
i_track++;
idx = 0;
}
} else {
buffer[idx++] = p_data->text[j];
#ifdef _CDTEXT_DBCC
if(p_data->bDBC)
buffer[idx++] = p_data->text[j+1];
#endif
}
buffer[idx] = 0x00;
#ifdef _CDTEXT_DBCC
if(p_data->bDBC)
buffer[idx+1] = 0x00;
#endif
}
} else {
/* not a character pack */
if(p_data->type == CDIO_CDTEXT_TOC) {
/* no idea what this is */
}
if (p_data->type == CDIO_CDTEXT_TOC2) {
/* no idea what this is */
}
/* i got this info from cdrtools' cdda2wav; all the tests i ran so far were successful */
if (p_data->type == CDIO_CDTEXT_BLOCKSIZE) {
/* i_track is the pack element number in this case */
switch(p_data->i_track){
case 0:
memcpy((char*)&p_blocksize,p_data->text,0x0c);
break;
case 1:
memcpy(((char*)&p_blocksize)+0x0c,p_data->text,0x0c);
break;
case 2:
memcpy(((char*)&p_blocksize)+0x18,p_data->text,0x0c);
break;
}
}
if(blocksize.i_packs[15] == 3) {
/* if there were 3 BLOCKSIZE packs */
/* set copyright */
p_cdtext->block[i_block].copyright = (0x03 == (blocksize.copyright & 0x03));
/* set Language */
if(blocksize.langcode[i_block] <= 0x7f)
p_cdtext->block[i_block].language_code = blocksize.langcode[i_block];
/* determine encoding */
switch (blocksize.charcode){
case CDTEXT_CHARCODE_ISO_8859_1:
/* default */
charset = (char *) "ISO-8859-1";
break;
case CDTEXT_CHARCODE_ASCII:
charset = (char *) "ASCII";
break;
case CDTEXT_CHARCODE_SHIFT_JIS:
charset = (char *) "SHIFT_JIS";
break;
}
} else {
cdio_warn("CD-TEXT: No blocksize information available for block %d.\n", i_block);
return -1;
}
}
}
if (p_blocksize.i_packs[15] >= 3) {
/* if there were more than 3 BLOCKSIZE packs */
switch (p_blocksize.charcode){
case CDIO_CDTEXT_CHARCODE_ISO_8859_1:
strcpy(p_cdtext->encoding, "ISO-8859-1");
break;
case CDIO_CDTEXT_CHARCODE_ASCII:
strcpy(p_cdtext->encoding, "ASCII");
break;
case CDIO_CDTEXT_CHARCODE_KANJI:
strcpy(p_cdtext->encoding, "Shift-JIS");
cdtext_read_pack(&pack, p_data);
#ifndef _CDTEXT_DBCC
if ( pack.db_chars ) {
cdio_warn("CD-TEXT: Double-byte characters not supported");
return -1;
}
#endif
/* read text packs first */
j = 0;
switch (pack.type) {
case CDTEXT_PACK_GENRE:
/* If pack.text starts with an unprintable character, it is likely to be the genre_code.
* While the specification requires the first GENRE pack to start with the 2 byte genre code,
* it is not specific about the following ones. */
if (pack.text[0] <= 31) {
j = 2;
if (CDTEXT_GENRE_UNUSED == p_cdtext->block[i_block].genre_code)
p_cdtext->block[i_block].genre_code = CDTEXT_GET_LEN16(pack.text);
}
case CDTEXT_PACK_TITLE:
case CDTEXT_PACK_PERFORMER:
case CDTEXT_PACK_SONGWRITER:
case CDTEXT_PACK_COMPOSER:
case CDTEXT_PACK_ARRANGER:
case CDTEXT_PACK_MESSAGE:
case CDTEXT_PACK_DISCID:
case CDTEXT_PACK_UPC:
while (j < CDTEXT_LEN_TEXTDATA) {
/* not terminated */
if (pack.text[j] != 0 || (pack.db_chars && pack.text[j+1] != 0)) {
buffer[i_buf++] = pack.text[j];
if(pack.db_chars)
buffer[i_buf++] = pack.text[j+1];
} else if(i_buf > 1) {
buffer[i_buf++] = 0;
if(pack.db_chars)
buffer[i_buf++] = 0;
switch (pack.type) {
case CDTEXT_PACK_TITLE:
cdtext_set(p_cdtext, CDTEXT_FIELD_TITLE, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_PERFORMER:
cdtext_set(p_cdtext, CDTEXT_FIELD_PERFORMER, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_SONGWRITER:
cdtext_set(p_cdtext, CDTEXT_FIELD_SONGWRITER, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_COMPOSER:
cdtext_set(p_cdtext, CDTEXT_FIELD_COMPOSER, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_ARRANGER:
cdtext_set(p_cdtext, CDTEXT_FIELD_ARRANGER, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_MESSAGE:
cdtext_set(p_cdtext, CDTEXT_FIELD_MESSAGE, buffer, pack.i_track, charset);
break;
case CDTEXT_PACK_DISCID:
if (pack.i_track == 0)
cdtext_set(p_cdtext, CDTEXT_FIELD_DISCID, buffer, pack.i_track, NULL);
break;
case CDTEXT_PACK_GENRE:
cdtext_set(p_cdtext, CDTEXT_FIELD_GENRE, buffer, pack.i_track, "ASCII");
break;
case CDTEXT_PACK_UPC:
if (pack.i_track == 0)
cdtext_set(p_cdtext, CDTEXT_FIELD_UPC_EAN, buffer, pack.i_track, "ASCII");
else
cdtext_set(p_cdtext, CDTEXT_FIELD_ISRC, buffer, pack.i_track, "ISO-8859-1");
break;
}
i_buf = 0;
}
if (pack.db_chars)
j+=2;
else
j+=1;
}
break;
}
/* set ISO 639-1 code */
switch (p_blocksize.langcode[block]) {
case CDIO_CDTEXT_LANG_CZECH :
strcpy(p_cdtext->language, "cs");
break;
case CDIO_CDTEXT_LANG_DANISH :
strcpy(p_cdtext->language, "da");
break;
case CDIO_CDTEXT_LANG_GERMAN :
strcpy(p_cdtext->language, "de");
break;
case CDIO_CDTEXT_LANG_ENGLISH :
strcpy(p_cdtext->language, "en");
break;
case CDIO_CDTEXT_LANG_SPANISH :
strcpy(p_cdtext->language, "es");
break;
case CDIO_CDTEXT_LANG_FRENCH :
strcpy(p_cdtext->language, "fr");
break;
case CDIO_CDTEXT_LANG_ITALIAN :
strcpy(p_cdtext->language, "it");
break;
case CDIO_CDTEXT_LANG_HUNGARIAN :
strcpy(p_cdtext->language, "hu");
break;
case CDIO_CDTEXT_LANG_DUTCH :
strcpy(p_cdtext->language, "nl");
break;
case CDIO_CDTEXT_LANG_NORWEGIAN :
strcpy(p_cdtext->language, "no");
break;
case CDIO_CDTEXT_LANG_POLISH :
strcpy(p_cdtext->language, "pl");
break;
case CDIO_CDTEXT_LANG_PORTUGUESE :
strcpy(p_cdtext->language, "pt");
break;
case CDIO_CDTEXT_LANG_SLOVENE :
strcpy(p_cdtext->language, "sl");
break;
case CDIO_CDTEXT_LANG_FINNISH :
strcpy(p_cdtext->language, "fi");
break;
case CDIO_CDTEXT_LANG_SWEDISH :
strcpy(p_cdtext->language, "sv");
break;
case CDIO_CDTEXT_LANG_RUSSIAN :
strcpy(p_cdtext->language, "ru");
break;
case CDIO_CDTEXT_LANG_KOREAN :
strcpy(p_cdtext->language, "ko");
break;
case CDIO_CDTEXT_LANG_JAPANESE :
strcpy(p_cdtext->language, "ja");
break;
case CDIO_CDTEXT_LANG_GREEK :
strcpy(p_cdtext->language, "el");
break;
case CDIO_CDTEXT_LANG_CHINESE :
strcpy(p_cdtext->language, "zh");
break;
}
}
return b_ret;
/* This would be the right place to parse TOC and TOC2 fields. */
i_seq++;
i_data-=CDTEXT_LEN_PACK;
p_data+=CDTEXT_LEN_PACK;
} /* end of while loop */
p_cdtext->block_i = 0;
return 0;
}
/*!
Fills cdtext_pack_t with information read from p_data
@param p_pack out
@param p_data in
*/
int
cdtext_read_pack(cdtext_pack_t *p_pack, const uint8_t *p_data) {
p_pack->type = p_data[0];
p_pack->i_track = p_data[1];
p_pack->seq = p_data[2];
p_pack->char_pos = p_data[3] & 0x0F;
p_pack->block = (p_data[3] >> 4) & 0x07;
p_pack->db_chars = (p_data[3] >> 7) & 0x01;
p_pack->text[0] = p_data[4];
p_pack->text[1] = p_data[5];
p_pack->text[2] = p_data[6];
p_pack->text[3] = p_data[7];
p_pack->text[4] = p_data[8];
p_pack->text[5] = p_data[9];
p_pack->text[6] = p_data[10];
p_pack->text[7] = p_data[11];
p_pack->text[8] = p_data[12];
p_pack->text[9] = p_data[13];
p_pack->text[10] = p_data[14];
p_pack->text[11] = p_data[15];
p_pack->crc[0] = p_data[16];
p_pack->crc[1] = p_data[17];
return 0;
}

View File

@@ -18,170 +18,122 @@
#ifndef __CDIO_CDTEXT_PRIVATE_H__
#define __CDIO_CDTEXT_PRIVATE_H__
#include <cdio/cdio.h>
#include <cdio/cdtext.h>
#include <cdio/types.h>
#define CDTEXT_GET_LEN16(p) (p[0]<<8) + p[1]
/*! An enumeration for some of the CDIO_CDTEXT_* #defines below. This isn't
really an enumeration one would really use in a program it is here
to be helpful in debuggers where wants just to refer to the
ISO_*_ names and get something.
*/
extern const enum cdtext_enum1_s {
CDIO_CDTEXT_MAX_PACK_DATA = 255,
CDIO_CDTEXT_MAX_TEXT_DATA = 12,
CDIO_CDTEXT_TITLE = 0x80,
CDIO_CDTEXT_PERFORMER = 0x81,
CDIO_CDTEXT_SONGWRITER = 0x82,
CDIO_CDTEXT_COMPOSER = 0x83,
CDIO_CDTEXT_ARRANGER = 0x84,
CDIO_CDTEXT_MESSAGE = 0x85,
CDIO_CDTEXT_DISCID = 0x86,
CDIO_CDTEXT_GENRE = 0x87,
CDIO_CDTEXT_TOC = 0x88,
CDIO_CDTEXT_TOC2 = 0x89,
CDIO_CDTEXT_UPC = 0x8E,
CDIO_CDTEXT_BLOCKSIZE = 0x8F
} cdtext_enums1;
enum {
CDTEXT_LEN_BINARY_MAX = 9216,
CDTEXT_LEN_TEXTDATA = 12,
CDTEXT_LEN_PACK = 18,
CDTEXT_LEN_BLOCKSIZE = 36,
CDTEXT_NUM_BLOCKS_MAX = 8,
CDTEXT_NUM_TRACKS_MAX = 100,
CDTEXT_NUM_BLOCKPACKS_MAX = 255
} cdtext_format_enum;
/*!
* CD-Text character codes
/**
* From table J.2 - Pack Type Indicator Definitions from
* Working Draft NCITS XXX T10/1364-D Revision 10G. November 12, 2001.
*/
extern const enum cdtext_charcode_enum_s {
CDIO_CDTEXT_CHARCODE_ISO_8859_1 = 0x00, /**< ISO-8859-1 */
CDIO_CDTEXT_CHARCODE_ASCII = 0x01, /**< ASCII - 7 bit */
CDIO_CDTEXT_CHARCODE_KANJI = 0x80, /**< Music Shift-JIS Kanji -
double byte */
CDIO_CDTEXT_CHARCODE_KOREAN = 0x81, /**< Korean */
CDIO_CDTEXT_CHARCODE_CHINESE = 0x82, /**< Mandarin Chinese */
CDIO_CDTEXT_CHARCODE_UNDEFINED = 0xFF, /**< everything else */
enum {
CDTEXT_PACK_TITLE = 0x80,
CDTEXT_PACK_PERFORMER = 0x81,
CDTEXT_PACK_SONGWRITER = 0x82,
CDTEXT_PACK_COMPOSER = 0x83,
CDTEXT_PACK_ARRANGER = 0x84,
CDTEXT_PACK_MESSAGE = 0x85,
CDTEXT_PACK_DISCID = 0x86,
CDTEXT_PACK_GENRE = 0x87,
CDTEXT_PACK_TOC = 0x88,
CDTEXT_PACK_TOC2 = 0x89,
CDTEXT_PACK_UPC = 0x8E,
CDTEXT_PACK_BLOCKSIZE = 0x8F
} cdtext_packtype_enum;
/** CD-Text character encodings */
enum cdtext_charcode_enum_s {
CDTEXT_CHARCODE_ISO_8859_1 = 0x00, /**< ISO-8859-1 (8 bit), Latin-1 */
CDTEXT_CHARCODE_ASCII = 0x01, /**< ASCII (7 bit) */
CDTEXT_CHARCODE_SHIFT_JIS = 0x80 /**< Shift_JIS (double byte), JIS X 0208 Appendix 1 */
///* The following were proposed but never implemented anywhere.
// * They are mentioned for completeness here
// * CDTEXT_CHARCODE_KOREAN = 0x81, /**< Korean */
// * CDTEXT_CHARCODE_CHINESE = 0x82, /**< Mandarin Chinese */
// * CDTEXT_CHARCODE_UNDEFINED = 0xFF, /**< everything else */
// */
} cdtext_charcode_enum;
/*!
* The language code is encoded as specified in ANNEX 1 to part 5 of EBU
* Tech 32 58 -E (1991).
*/
extern const enum cdtext_lang_enum_s
{
CDIO_CDTEXT_LANG_CZECH = 0x06,
CDIO_CDTEXT_LANG_DANISH = 0x07,
CDIO_CDTEXT_LANG_GERMAN = 0x08,
CDIO_CDTEXT_LANG_ENGLISH = 0x09,
CDIO_CDTEXT_LANG_SPANISH = 0x0A,
CDIO_CDTEXT_LANG_FRENCH = 0x0F,
CDIO_CDTEXT_LANG_ITALIAN = 0x15,
CDIO_CDTEXT_LANG_HUNGARIAN = 0x1b,
CDIO_CDTEXT_LANG_DUTCH = 0x1d,
CDIO_CDTEXT_LANG_NORWEGIAN = 0x1e,
CDIO_CDTEXT_LANG_POLISH = 0x20,
CDIO_CDTEXT_LANG_PORTUGUESE = 0x21,
CDIO_CDTEXT_LANG_SLOVENE = 0x26,
CDIO_CDTEXT_LANG_FINNISH = 0x27,
CDIO_CDTEXT_LANG_SWEDISH = 0x28,
CDIO_CDTEXT_LANG_RUSSIAN = 0x56,
CDIO_CDTEXT_LANG_KOREAN = 0x65,
CDIO_CDTEXT_LANG_JAPANESE = 0x69,
CDIO_CDTEXT_LANG_GREEK = 0x70,
CDIO_CDTEXT_LANG_CHINESE = 0x75,
} cdtext_lang_enum;
#define CDIO_CDTEXT_MAX_PACK_DATA 255
#define CDIO_CDTEXT_MAX_TEXT_DATA 12
/* From table J.2 - Pack Type Indicator Definitions from
Working Draft NCITS XXX T10/1364-D Revision 10G. November 12, 2001.
*/
/* Title of Album name (ID=0) or Track Titles (ID != 0) */
#define CDIO_CDTEXT_TITLE 0x80
/* Name(s) of the performer(s) in ASCII */
#define CDIO_CDTEXT_PERFORMER 0x81
/* Name(s) of the songwriter(s) in ASCII */
#define CDIO_CDTEXT_SONGWRITER 0x82
/* Name(s) of the Composers in ASCII */
#define CDIO_CDTEXT_COMPOSER 0x83
/* Name(s) of the Arrangers in ASCII */
#define CDIO_CDTEXT_ARRANGER 0x84
/* Message(s) from content provider and/or artist in ASCII */
#define CDIO_CDTEXT_MESSAGE 0x85
/* Disc Identificatin information */
#define CDIO_CDTEXT_DISCID 0x86
/* Genre Identification and Genre Information */
#define CDIO_CDTEXT_GENRE 0x87
/* Table of Content Information */
#define CDIO_CDTEXT_TOC 0x88
/* Second Table of Content Information */
#define CDIO_CDTEXT_TOC2 0x89
/* 0x8A, 0x8B, 0x8C are reserved
0x8D Reserved for content provider only.
*/
/* UPC/EAN code of the album and ISRC code of each track */
#define CDIO_CDTEXT_UPC 0x8E
/* Size information of the Block */
#define CDIO_CDTEXT_BLOCKSIZE 0x8F
PRAGMA_BEGIN_PACKED
struct CDText_data
/** Structure of CD-TEXT data Packs */
struct cdtext_pack_s
{
uint8_t type;
track_t i_track;
uint8_t i_track;
uint8_t seq;
#ifdef WORDS_BIGENDIAN
uint8_t bDBC: 1; /* double byte character */
uint8_t block: 3; /* block number 0..7 */
uint8_t characterPosition:4; /* character position */
#else
uint8_t characterPosition:4; /* character position */
uint8_t block :3; /* block number 0..7 */
uint8_t bDBC :1; /* double byte character */
#endif
char text[CDIO_CDTEXT_MAX_TEXT_DATA];
uint8_t char_pos; /* character position */
uint8_t block; /* block number 0..7 */
uint8_t db_chars; /* double byte character */
uint8_t text[CDTEXT_LEN_TEXTDATA];
uint8_t crc[2];
} GNUC_PACKED;
};
PRAGMA_END_PACKED
/*
* content of BLOCKSIZE packs
*/
PRAGMA_BEGIN_PACKED
struct CDText_blocksize
/** Structure of of block size information packs */
struct cdtext_blocksize_s
{
uint8_t charcode; /* character code */
uint8_t charcode; /* character code */
uint8_t i_first_track; /* first track number */
uint8_t i_last_track; /* last track number */
uint8_t copyright; /* cd-text information copyright byte */
uint8_t i_packs[16];/* number of packs of each type
* 0 TITLE; 1 PERFORMER; 2 SONGWRITER; 3 COMPOSER;
* 4 ARRANGER; 5 MESSAGE; 6 DISCID; 7 GENRE;
* 8 TOC; 9 TOC2; 10-12 RESERVED; 13 CLOSED;
* 14 UPC_ISRC; 15 BLOCKSIZE */
uint8_t lastseq[8]; /* last sequence for block 0..7 */
uint8_t langcode[8]; /* language code for block 0..7 */
} GNUC_PACKED;
uint8_t copyright; /* 3 CD-TEXT is copyrighted, 0 no copyright on CD-TEXT */
uint8_t i_packs[16]; /* number of packs of each type
* 0 TITLE; 1 PERFORMER; 2 SONGWRITER; 3 COMPOSER;
* 4 ARRANGER; 5 MESSAGE; 6 DISCID; 7 GENRE;
* 8 TOC; 9 TOC2; 10-12 RESERVED; 13 CLOSED;
* 14 UPC_ISRC; 15 BLOCKSIZE */
uint8_t lastseq[8]; /* last sequence for block 0..7 */
uint8_t langcode[8]; /* language code for block 0..7 */
};
PRAGMA_END_PACKED;
typedef struct cdtext_pack_s cdtext_pack_t;
typedef struct cdtext_blocksize_s cdtext_blocksize_t;
/*! Structure for CD-TEXT of a track. */
struct cdtext_track_s {
char *field[MAX_CDTEXT_FIELDS];
};
typedef struct CDText_blocksize CDText_blocksize_t;
typedef struct CDText_data CDText_data_t;
/*! Structure for CD-TEXT of a block. */
struct cdtext_block_s {
struct cdtext_track_s track[CDTEXT_NUM_TRACKS_MAX]; /**< 0: disc; 1..99: tracks */
cdtext_genre_t genre_code; /**< genre code of the disc */
cdtext_lang_t language_code; /**< language of this block */
bool copyright; /**< CD-TEXT copyright */
};
/*! Structure for CD-TEXT of a disc.
@see cdtext_init, cdtext_destroy, cdtext_get, and cdtext_set.
*/
struct cdtext_s {
struct cdtext_block_s block[CDTEXT_NUM_BLOCKS_MAX]; /**< CD-TEXT for block 0..7 */
uint8_t block_i; /**< index of active block */
};
int cdtext_read_pack (cdtext_pack_t *pack, const uint8_t *data);
/*!
returns enum of field if key is a CD-Text keyword,
returns CDTEXT_FIELD_INVALID otherwise.
*/
cdtext_field_t cdtext_is_field (const char *field);
/*!
returns enum of language if lang is a valid language,
returns CDTEXT_LANGUAGE_UNKNOWN otherwise.
*/
cdtext_lang_t cdtext_is_language (const char *lang);
#endif /* __CDIO_CDTEXT_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -76,6 +76,7 @@
#endif
#include "image_common.h"
#include "cdtext_private.h"
static lsn_t get_disc_last_lsn_cdrdao (void *p_user_data);
static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name);
@@ -918,48 +919,49 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
goto not_in_global_section;
}
/* CD_TEXT { ... } */
/* todo: opening { must be on same line as CD_TEXT */
/* CD_TEXT { ... } */
/* todo: opening { must be on same line as CD_TEXT */
} else if (0 == strcmp ("CD_TEXT", psz_keyword)) {
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
if ( 0 == strcmp( "{", psz_field ) ) {
i_cdtext_nest++;
} else {
cdio_log (log_level,
"%s line %d: expecting '{'", psz_cue_name, i_line);
goto err_exit;
}
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
if ( 0 == strcmp( "{", psz_field ) ) {
i_cdtext_nest++;
} else {
cdio_log (log_level,
"%s line %d: expecting '{'", psz_cue_name, i_line);
goto err_exit;
}
// TODO: implement language mapping
} else if (0 == strcmp ("LANGUAGE_MAP", psz_keyword)) {
/* LANGUAGE d { ... } */
/* LANGUAGE d { ... } */
} else if (0 == strcmp ("LANGUAGE", psz_keyword)) {
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
/* Language number */
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
if ( 0 == strcmp( "{", psz_field ) ) {
i_cdtext_nest++;
}
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
/* Language number */
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error;
}
if ( 0 == strcmp( "{", psz_field ) ) {
i_cdtext_nest++;
}
} else if (0 == strcmp ("{", psz_keyword)) {
i_cdtext_nest++;
i_cdtext_nest++;
} else if (0 == strcmp ("}", psz_keyword)) {
if (i_cdtext_nest > 0) i_cdtext_nest--;
} else if ( CDTEXT_INVALID !=
(cdtext_key = cdtext_is_keyword (psz_keyword)) ) {
if (i_cdtext_nest > 0) i_cdtext_nest--;
} else if ( CDTEXT_FIELD_INVALID !=
(cdtext_key = cdtext_is_field (psz_keyword)) ) {
if (NULL != cd) {
if (NULL == cd->gen.cdtext) {
cd->gen.cdtext = malloc(sizeof(cdtext_t));
cdtext_init (cd->gen.cdtext);
cd->gen.cdtext = cdtext_init ();
/* until language mapping is implemented ...*/
cd->gen.cdtext->block[cd->gen.cdtext->block_i].language_code = CDTEXT_LANGUAGE_ENGLISH;
}
cdtext_set (cdtext_key,
(-1 == i ? 0 : cd->gen.i_first_track + i + 1),
strtok (NULL, "\"\t\n\r"),
cd->gen.cdtext);
cdtext_set (cd->gen.cdtext, cdtext_key, (uint8_t*) strtok (NULL, "\"\t\n\r"),
(-1 == i ? 0 : cd->gen.i_first_track + i + 1),
"ISO-8859-1");
}
/* unrecognized line */

View File

@@ -750,10 +750,9 @@ parse_nrg (_img_private_t *p_env, const char *psz_nrg_name,
case CDTX_ID: { /* "CD TEXT" */
uint8_t *wdata = (uint8_t *) chunk->data;
int len = UINT32_FROM_BE (chunk->len);
cdio_assert (len % sizeof (CDText_data_t) == 0);
p_env->gen.cdtext = malloc(sizeof(cdtext_t));
cdtext_init (p_env->gen.cdtext);
if(!cdtext_data_init (p_env->gen.cdtext, wdata, len))
cdio_assert (len % CDTEXT_LEN_PACK == 0);
p_env->gen.cdtext = cdtext_init ();
if(0 !=cdtext_data_init (p_env->gen.cdtext, wdata, len))
{
cdtext_destroy(p_env->gen.cdtext);
free(p_env->gen.cdtext);

View File

@@ -183,11 +183,14 @@ cdio_warn
cdtext_destroy
cdtext_field2str
cdtext_genre2str
cdtext_lang2str
cdtext_get
cdtext_get_const
cdtext_get_language
cdtext_init
cdtext_is_keyword
cdtext_languages_available
cdtext_set
cdtext_select_language
debug_cdio_mmc_feature
debug_cdio_mmc_feature_interface
debug_cdio_mmc_feature_profile

View File

@@ -36,12 +36,10 @@
#include "cdio_assert.h"
#include "portable.h"
static const char _rcsid[] = "$Id: logging.c,v 1.2 2008/04/22 15:29:12 karl Exp $";
cdio_log_level_t cdio_loglevel_default = CDIO_LOG_WARN;
static void
default_cdio_log_handler (cdio_log_level_t level, const char message[])
default_cdio_log_handler(cdio_log_level_t level, const char message[])
{
switch (level)
{
@@ -85,7 +83,7 @@ default_cdio_log_handler (cdio_log_level_t level, const char message[])
static cdio_log_handler_t _handler = default_cdio_log_handler;
cdio_log_handler_t
cdio_log_set_handler (cdio_log_handler_t new_handler)
cdio_log_set_handler(cdio_log_handler_t new_handler)
{
cdio_log_handler_t old_handler = _handler;
@@ -95,7 +93,7 @@ cdio_log_set_handler (cdio_log_handler_t new_handler)
}
static void
cdio_logv (cdio_log_level_t level, const char format[], va_list args)
cdio_logv(cdio_log_level_t level, const char format[], va_list args)
{
char buf[1024] = { 0, };
static int in_recursion = 0;
@@ -113,7 +111,7 @@ cdio_logv (cdio_log_level_t level, const char format[], va_list args)
}
void
cdio_log (cdio_log_level_t level, const char format[], ...)
cdio_log(cdio_log_level_t level, const char format[], ...)
{
va_list args;
va_start (args, format);

View File

@@ -27,6 +27,7 @@
#include <cdio/mmc_cmds.h>
#include <cdio/util.h>
#include "cdio_private.h"
#include "cdtext_private.h"
#ifdef HAVE_STRING_H
#include <string.h>
@@ -350,7 +351,7 @@ mmc_read_cdtext_private ( void *p_user_data,
errno = 0;
wdata = calloc(MAX_CDTEXT_DATA_LENGTH, sizeof(unsigned char));
wdata = calloc(CDTEXT_LEN_BINARY_MAX, sizeof(unsigned char));
/* We may need to give CD-Text a little more time to complete. */
/* First off, just try and read the size */
@@ -368,8 +369,8 @@ mmc_read_cdtext_private ( void *p_user_data,
/* Now read the CD-Text data */
int i_cdtext = CDIO_MMC_GET_LEN16(wdata);
if (i_cdtext+2 > MAX_CDTEXT_DATA_LENGTH)
i_cdtext = MAX_CDTEXT_DATA_LENGTH-2;
if (i_cdtext+2 > CDTEXT_LEN_BINARY_MAX)
i_cdtext = CDTEXT_LEN_BINARY_MAX-2;
else
wdata = realloc(wdata,i_cdtext+2);
/* the 2 bytes holding the size are not included in i_cdtext */

View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 2006, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2006, 2008, 2011, 2012 Rocky Bernstein <rocky@gnu.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

View File

@@ -167,7 +167,7 @@ void cdio_charset_converter_destroy(cdio_charset_coverter_t*cnv)
#define BYTES_INCREMENT 16
static bool
do_convert(iconv_t cd, char * src, int src_len,
do_convert(iconv_t cd, const char * src, int src_len,
char ** dst, int *dst_len)
{
char * ret;
@@ -194,7 +194,7 @@ do_convert(iconv_t cd, char * src, int src_len,
ret = malloc(alloc_size);
inbuf = src;
inbuf = (char *)src;
outbuf = ret;
while(1)
@@ -269,7 +269,7 @@ bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst,
bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst,
bool cdio_charset_to_utf8(const char *src, size_t src_len, cdio_utf8_t **dst,
const char * src_charset)
{
iconv_t ic;

5
maintMakefile Normal file
View File

@@ -0,0 +1,5 @@
# Lots of warnings!
AM_CFLAGS += -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast
MAKE_MAINTAINER_MODE := -DMAKE_MAINTAINER_MODE
AM_CPPFLAGS += $(MAKE_MAINTAINER_MODE)

View File

@@ -423,8 +423,8 @@ print_cdtext_track_info(cdtext_t *p_cdtext, track_t i_track, const char *psz_msg
printf("%s\n", psz_msg);
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
if (cdtext_get_const(i, i_track, p_cdtext)) {
printf("\t%s: %s\n", cdtext_field2str(i), cdtext_get_const(i, i_track, p_cdtext));
if (cdtext_get_const(p_cdtext, i, i_track)) {
printf("\t%s: %s\n", cdtext_field2str(i), cdtext_get_const(p_cdtext, i, i_track));
}
}
}
@@ -434,18 +434,28 @@ static void
print_cdtext_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) {
track_t i_last_track = i_first_track+i_tracks;
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
cdtext_lang_t *languages;
int i, j;
if(NULL == p_cdtext) {
printf("No CD-TEXT on Disc.\n");
return;
}
print_cdtext_track_info(p_cdtext, 0, "\nCD-TEXT for Disc:");
for ( ; i_first_track < i_last_track; i_first_track++ ) {
char msg[50];
sprintf(msg, "CD-TEXT for Track %2d:", i_first_track);
print_cdtext_track_info(p_cdtext, i_first_track, msg);
}
languages = cdtext_languages_available(p_cdtext);
for(i=0; i<8; i++)
if ( CDTEXT_LANGUAGE_UNKNOWN != languages[i]
&& cdtext_select_language(p_cdtext, cdtext_lang2str(languages[i])))
{
printf("\nLanguage %d '%s':\n", i, cdtext_lang2str(languages[i]));
print_cdtext_track_info(p_cdtext, 0, "CD-TEXT for Disc:");
for ( j = i_first_track ; j < i_last_track; j++ ) {
char msg[50];
sprintf(msg, "CD-TEXT for Track %2d:", j);
print_cdtext_track_info(p_cdtext, j, msg);
}
}
}
#ifdef HAVE_CDDB

View File

@@ -544,9 +544,9 @@ get_cddb_disc_info(CdIo_t *p_cdio)
}
#define add_cdtext_disc_info(format_str, info_field, FIELD) \
if (cdtext_get_const(FIELD, 0, p_cdtext) && !strlen(info_field)) { \
if (cdtext_get_const(p_cdtext, FIELD, 0) && !strlen(info_field)) { \
snprintf(info_field, sizeof(info_field), format_str, \
cdtext_get_const(FIELD, 0, p_cdtext)); \
cdtext_get_const(p_cdtext, FIELD, 0)); \
b_cdtext_ ## info_field = true; \
}
@@ -556,9 +556,9 @@ get_cdtext_disc_info(CdIo_t *p_cdio)
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
if (p_cdtext) {
add_cdtext_disc_info("%s", title, CDTEXT_TITLE);
add_cdtext_disc_info("%s", artist, CDTEXT_PERFORMER);
add_cdtext_disc_info("%s", genre, CDTEXT_GENRE);
add_cdtext_disc_info("%s", title, CDTEXT_FIELD_TITLE);
add_cdtext_disc_info("%s", artist, CDTEXT_FIELD_PERFORMER);
add_cdtext_disc_info("%s", genre, CDTEXT_FIELD_GENRE);
}
}
@@ -840,10 +840,10 @@ get_cddb_track_info(track_t i_track)
}
#define add_cdtext_track_info(format_str, info_field, FIELD) \
if (cdtext_get_const(FIELD, i_track, p_cdtext)) { \
if (cdtext_get_const(p_cdtext, FIELD, i_track)) { \
snprintf(cd_info[i_track].info_field, \
sizeof(cd_info[i_track].info_field), \
format_str, cdtext_get_const(FIELD, i_track, p_cdtext)); \
format_str, cdtext_get_const(p_cdtext, FIELD, i_track)); \
cd_info[i_track].b_cdtext = true; \
}
@@ -855,8 +855,8 @@ get_cdtext_track_info(track_t i_track)
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
if (NULL != p_cdtext) {
add_cdtext_track_info("%s", title, CDTEXT_TITLE);
add_cdtext_track_info("%s", artist, CDTEXT_PERFORMER);
add_cdtext_track_info("%s", title, CDTEXT_FIELD_TITLE);
add_cdtext_track_info("%s", artist, CDTEXT_FIELD_PERFORMER);
}
}

View File

@@ -11,7 +11,8 @@ audio status: not implemented
__________________________________
CD Analysis Report
Language 0 'English':
CD-TEXT for Disc:
PERFORMER: Richard Stallman
TITLE: Join us now we have the software
PERFORMER: Richard Stallman
CD-TEXT for Track 1:

View File

@@ -13,37 +13,69 @@ audio status: not implemented
__________________________________
CD Analysis Report
Language 0 'English':
CD-TEXT for Disc:
ARRANGER: The Gnu Community
COMPOSER: Another Gnu
DISC_ID: 0815 42
GENRE: Animal Soundz
MESSAGE: Gnu lives!
PERFORMER: A Gnu
SONGWRITER: A Gnu, too
TITLE: The Voice of the Gnu
UPC_EAN: 0123456789876
TITLE: Joyful Nights
PERFORMER: United Cat Orchestra
SONGWRITER: Various Songwriters
COMPOSER: Various Composers
MESSAGE: For all our fans
ARRANGER: Tom Cat
UPC_EAN: 1234567890123
GENRE: Feline classic music
DISC_ID: 1234567890
CD-TEXT for Track 1:
ARRANGER: His Brother
COMPOSER: His Brother
MESSAGE: Free the Gnu!
ISRC: DE-GNU-11-00001
PERFORMER: Gnu2
SONGWRITER: Gnu2
TITLE: I Will Survive
TITLE: Song of Joy
PERFORMER: Felix and The Purrs
SONGWRITER: Friedrich Schiller
COMPOSER: unknown
MESSAGE: Fritz and Louie once were punks
ARRANGER: Tom Cat
ISRC: XYBLG1101234
CD-TEXT for Track 2:
ARRANGER: The Guy With the Microphone
COMPOSER: The Alpha Gnu
MESSAGE: Isn't it beatiful?
ISRC: DE-GNU-11-00002
PERFORMER: Those Particular Gnus
SONGWRITER: None in Particular
TITLE: A Forest Full of Gnus
TITLE: Humpty Dumpty
PERFORMER: Catwalk Beauties
SONGWRITER: Mother Goose
MESSAGE: Pluck the goose
ISRC: XYBLG1100005
CD-TEXT for Track 3:
ARRANGER: An Even Less Famous Gnu
COMPOSER: A Not So Famous Gnu
MESSAGE: Every Gnu Is Legal!
ISRC: DE-GNU-11-00003
PERFORMER: Whatwasitsname?
SONGWRITER: A Famous Gnu
TITLE: Gnu Opera
TITLE: Mee Owwww
PERFORMER: Mia Kitten
SONGWRITER: Mia Kitten
COMPOSER: Mia Kitten
ARRANGER: Mia Kitten
ISRC: XYBLG1100006
Language 1 'German':
CD-TEXT for Disc:
TITLE: Freudvolle Nächte
PERFORMER: Vereinigtes Katzenorchester
SONGWRITER: Verschiedene Liedschreiber
COMPOSER: Verschiedene Komponisten
MESSAGE: Für alle unsere Fans
ARRANGER: Tom Cat
UPC_EAN: 1234567890123
GENRE: Katzenhafte Klassik
DISC_ID: 1234567890
CD-TEXT for Track 1:
TITLE: Lied der Freude
PERFORMER: Felix und Die Schnurrer
SONGWRITER: Friedrich Schiller
COMPOSER: Ludwig van Beethoven
MESSAGE: Fritz und Louie waren einmal Punks
ARRANGER: Tom Cat
ISRC: XYBLG1101234
CD-TEXT for Track 2:
TITLE: Rubbeldiekatz
PERFORMER: Katzengang Schönheiten
SONGWRITER: Mutter Gans
COMPOSER: unbekannt
MESSAGE: Rupft die Gans
ISRC: XYBLG1100005
CD-TEXT for Track 3:
TITLE: Mie auu
PERFORMER: Mia Kätzchen
SONGWRITER: Mia Kätzchen
COMPOSER: Mia Kätzchen
ARRANGER: Mia Kätzchen
ISRC: XYBLG1100006

View File

@@ -72,7 +72,7 @@ if test -f ${abs_top_srcdir}/test/data/${fname}.bin ; then
fi
else
echo "Don't see CUE file ${abs_top_srcdir}/test/data/${fname}.bin. Test $testnum skipped."
echo "Don't see binary file ${abs_top_srcdir}/test/data/${fname}.bin. Test $testnum skipped."
fi
if test -n "@HAVE_ROCK@"; then

Binary file not shown.

View File

@@ -56,7 +56,7 @@ main(int argc, const char *argv[])
"Richard Stallman",
"Join us now we have the software"
};
const int cdtext_fields[NUM_FIELDS] = {CDTEXT_PERFORMER, CDTEXT_TITLE};
const int cdtext_fields[NUM_FIELDS] = {CDTEXT_FIELD_PERFORMER, CDTEXT_FIELD_TITLE};
cdio_loglevel_default = (argc > 1) ? CDIO_LOG_DEBUG : CDIO_LOG_INFO;
/* snprintf(psz_nrgfile, sizeof(psz_nrgfile)-1,
@@ -77,7 +77,7 @@ main(int argc, const char *argv[])
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
if (!p_cdtext) return(1);
for (i=0; i<NUM_FIELDS; i++) {
const char *psz_field = cdtext_get_const(cdtext_fields[i], 0, p_cdtext);
const char *psz_field = cdtext_get_const(p_cdtext, cdtext_fields[i], 0);
if (!psz_field)
return(2);
if (0 != strncmp(psz_field, cdtext_check[i], strlen(cdtext_check[i]))) {