Redo CD-TEXT handling. First minimally working version for CD bin/cue

and cdrdao images.
This commit is contained in:
rocky
2004-07-11 14:25:07 +00:00
parent 13614f9820
commit 0d3c10c775
12 changed files with 266 additions and 192 deletions

View File

@@ -1,5 +1,5 @@
/* /*
$Id: sample8.c,v 1.1 2004/07/09 01:05:31 rocky Exp $ $Id: sample8.c,v 1.2 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
@@ -29,16 +29,27 @@
int int
main(int argc, const char *argv[]) main(int argc, const char *argv[])
{ {
CdIo *cdio = cdio_open (NULL, DRIVER_UNKNOWN); CdIo *cdio = cdio_open ("../test/cdda.cue", DRIVER_BINCUE);
if (NULL == cdio) { if (NULL == cdio) {
printf("Couldn't find a driver.. leaving.\n"); printf("Couldn't open ../test/cdda.cue with BIN/CUE driver \n");
return 1; return 1;
} else {
const cdtext_t *cdtext = cdio_get_cdtext(cdio);
if (NULL != cdtext) {
printf("CD-TEXT Title: %s\n",
cdtext->field[CDTEXT_TITLE] ?
cdtext->field[CDTEXT_TITLE] : "not set");
printf("CD-TEXT Performer: %s\n",
cdtext->field[CDTEXT_PERFORMER] ?
cdtext->field[CDTEXT_PERFORMER] : "not set"
);
} else {
printf("Didn't get CD-TEXT info.\n");
}
} }
#if 0
cdio_cdtext_query(cdio);
#endif
cdio_destroy(cdio); cdio_destroy(cdio);
return 0; return 0;

View File

@@ -1,5 +1,5 @@
/* -*- c -*- /* -*- c -*-
$Id: cdio.h,v 1.55 2004/07/09 10:05:36 rocky Exp $ $Id: cdio.h,v 1.56 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -55,9 +55,12 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/** This is an opaque structure. */ /** This is an opaque structure for the CD object. */
typedef struct _CdIo CdIo; typedef struct _CdIo CdIo;
/** This is an opaque structure for the CDTEXT object. */
typedef struct cdtext cdtext_t;
/** The driver_id_t enumerations may be used to tag a specific driver /** The driver_id_t enumerations may be used to tag a specific driver
* that is opened or is desired to be opened. Note that this is * that is opened or is desired to be opened. Note that this is
* different than what is available on a given host. * different than what is available on a given host.
@@ -82,9 +85,9 @@ extern "C" {
DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed
before BINCUE, to make the code prefer cdrdao before BINCUE, to make the code prefer cdrdao
over BINCUE when both exist. */ over BINCUE when both exist. */
DRIVER_BINCUE, /**< BIN/CUE format CD image. This is listed before NRG, DRIVER_BINCUE, /**< CDRWIN BIN/CUE format CD image. This is
to make the code prefer BINCUE over NRG when both listed before NRG, to make the code prefer
exist. */ BINCUE over NRG when both exist. */
DRIVER_NRG, /**< Nero NRG format CD image. */ DRIVER_NRG, /**< Nero NRG format CD image. */
DRIVER_DEVICE /**< Is really a set of the above; should come last */ DRIVER_DEVICE /**< Is really a set of the above; should come last */
} driver_id_t; } driver_id_t;
@@ -151,6 +154,15 @@ extern "C" {
*/ */
const char * cdio_get_arg (const CdIo *obj, const char key[]); const char * cdio_get_arg (const CdIo *obj, const char key[]);
/*!
Get cdtext information for a CdIo object.
@param obj the CD object that may contain CD-TEXT information.
@return the CD-TEXT object or NULL if obj is NULL
or CD-TEXT information does not exist.
*/
const cdtext_t *cdio_get_cdtext (const CdIo *obj);
/*! /*!
Get an array of device names in search_devices that have at Get an array of device names in search_devices that have at
least the capabilities listed by cap. If search_devices is NULL, least the capabilities listed by cap. If search_devices is NULL,

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdtext.h,v 1.3 2004/07/09 01:34:16 rocky Exp $ $Id: cdtext.h,v 1.4 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
adapted from cuetools adapted from cuetools
@@ -34,32 +34,55 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef struct cdtext cdtext_t; #define MAX_CDTEXT_FIELDS 13
/*! Initialize and allocate a new cdtext structure and return a struct cdtext {
pointer to that. When the structure is no longer needed, release the char *field[MAX_CDTEXT_FIELDS];
};
typedef enum {
CDTEXT_ARRANGER = 0,
CDTEXT_COMPOSER = 1,
CDTEXT_DISCID = 2,
CDTEXT_GENRE = 3,
CDTEXT_MESSAGE = 4,
CDTEXT_ISRC = 5,
CDTEXT_PERFORMER = 6,
CDTEXT_SIZE_INFO = 7,
CDTEXT_SONGWRITER = 8,
CDTEXT_TITLE = 9,
CDTEXT_TOC_INFO = 10,
CDTEXT_TOC_INFO2 = 10,
CDTEXT_UPC_EAN = 12,
CDTEXT_INVALID = MAX_CDTEXT_FIELDS
} cdtext_field_t;
/*! Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete. resources using cdtext_delete.
*/ */
cdtext_t *cdtext_init (void); void cdtext_init (cdtext_t *cdtext);
/*! Free memory assocated with cdtext*/ /*! Free memory assocated with cdtext*/
void cdtext_delete (cdtext_t *cdtext); void cdtext_destroy (cdtext_t *cdtext);
/*! /*!
returns 0 if field is a CD-TEXT keyword, returns non-zero otherwise. returns the CDTEXT value associated with key. NULL is returned
if key is CDTEXT_INVALID or the field is not set.
*/
const char *cdtext_get (cdtext_field_t key, const cdtext_t *cdtext);
/*!
returns enum of keyword if key is a CD-TEXT keyword,
returns MAX_CDTEXT_FIELDS non-zero otherwise.
*/ */
int cdtext_is_keyword (const char *key); cdtext_field_t cdtext_is_keyword (const char *key);
/*! /*!
sets cdtext's keyword entry to field sets cdtext's keyword entry to field
*/ */
void cdtext_set (const char *key, const char *value, cdtext_t *cdtext); void cdtext_set (cdtext_field_t key, const char *value, cdtext_t *cdtext);
/*!
returns the CDTEXT value associated with key
*/
const char *cdtext_get (const char *key, const cdtext_t *cdtext);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdio.c,v 1.58 2004/07/09 01:05:32 rocky Exp $ $Id: cdio.c,v 1.59 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -39,7 +39,7 @@
#include <cdio/logging.h> #include <cdio/logging.h>
#include "cdio_private.h" #include "cdio_private.h"
static const char _rcsid[] = "$Id: cdio.c,v 1.58 2004/07/09 01:05:32 rocky Exp $"; static const char _rcsid[] = "$Id: cdio.c,v 1.59 2004/07/11 14:25:07 rocky Exp $";
const char *track_format2str[6] = const char *track_format2str[6] =
@@ -271,6 +271,25 @@ cdio_get_arg (const CdIo *obj, const char key[])
} }
} }
/*!
Get cdtext information for a CdIo object .
@param obj the CD object that may contain CD-TEXT information.
@return the CD-TEXT object or NULL if obj is NULL
or CD-TEXT information does not exist.
*/
const cdtext_t *
cdio_get_cdtext (const CdIo *obj)
{
if (obj == NULL) return NULL;
if (obj->op.get_cdtext) {
return obj->op.get_cdtext (obj->env);
} else {
return NULL;
}
}
/*! /*!
Return a string containing the default CD device if none is specified. Return a string containing the default CD device if none is specified.
if CdIo is NULL (we haven't initialized a specific device driver), if CdIo is NULL (we haven't initialized a specific device driver),

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdio_private.h,v 1.26 2004/07/09 01:05:32 rocky Exp $ $Id: cdio_private.h,v 1.27 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -56,6 +56,11 @@ extern "C" {
*/ */
const char * (*get_arg) (void *env, const char key[]); const char * (*get_arg) (void *env, const char key[]);
/*!
Return cdtext information.
*/
const cdtext_t * (*get_cdtext) (const void *env);
/*! /*!
Return an array of device names. if CdIo is NULL (we haven't Return an array of device names. if CdIo is NULL (we haven't
initialized a specific device driver), then find a suitable device initialized a specific device driver), then find a suitable device

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdtext.c,v 1.3 2004/07/11 02:26:15 rocky Exp $ $Id: cdtext.c,v 1.4 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
toc reading routine adapted from cuetools toc reading routine adapted from cuetools
@@ -35,62 +35,50 @@
#include <string.h> #include <string.h>
#endif #endif
/* Private type */ /*! Free memory assocated with cdtext*/
struct cdtext { void
const char *key; cdtext_destroy (cdtext_t *cdtext)
char *value;
};
const cdtext_t cdtext[] = {
{"TITLE", NULL},
{"PERFORMER", NULL},
{"SONGWRITER", NULL},
{"COMPOSER", NULL},
{"ARRANGER", NULL},
{"MESSAGE", NULL},
{"DISC_ID", NULL},
{"GENRE", NULL},
{"TOC_INFO", NULL},
{"TOC_INFO2", NULL},
{"UPC_EAN", NULL},
{"ISRC", NULL},
{"SIZE_INFO", NULL},
{NULL, NULL}
};
cdtext_t *cdtext_init ()
{ {
cdtext_t *new_cdtext = NULL; cdtext_field_t i;
new_cdtext = (cdtext_t *) calloc (sizeof (cdtext) / sizeof (cdtext_t), for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
sizeof (cdtext_t)); if (cdtext->field[i]) free(cdtext->field[i]);
if (NULL == new_cdtext) }
cdio_warn("problem allocating memory");
else
memcpy (new_cdtext, cdtext, sizeof(cdtext));
return (new_cdtext);
} }
/*!
/*! Free memory assocated with cdtext*/ returns the CDTEXT value associated with key. NULL is returned
void cdtext_delete (cdtext_t *cdtext) if key is CDTEXT_INVALID or the field is not set.
*/
const char *
cdtext_get (cdtext_field_t key, const cdtext_t *cdtext)
{ {
int i; if (key == CDTEXT_INVALID) return NULL;
return cdtext->field[key];
}
if (NULL != cdtext) { /*! Initialize a new cdtext structure.
for (i = 0; NULL != cdtext[i].key; i++) When the structure is no longer needed, release the
free (cdtext[i].value); resources using cdtext_delete.
free (cdtext); */
void
cdtext_init (cdtext_t *cdtext)
{
cdtext_field_t i;
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
cdtext->field[i] = NULL;
} }
} }
/*! /*!
returns 0 if field is a CD-TEXT keyword, returns non-zero otherwise returns 0 if field is a CD-TEXT keyword, returns non-zero otherwise
*/ */
int cdtext_field_t
cdtext_is_keyword (const char *key) cdtext_is_keyword (const char *key)
{ {
/* Note: the order and number items (except CDTEXT_INVALID) should
match the cdtext_field_t enumeration. */
const char *cdtext_keywords[] = const char *cdtext_keywords[] =
{ {
"ARRANGER", /* name(s) of the arranger(s) */ "ARRANGER", /* name(s) of the arranger(s) */
@@ -122,31 +110,20 @@ cdtext_is_keyword (const char *key)
for (i = 0; i < 13 ; i++) for (i = 0; i < 13 ; i++)
if (0 == strcmp (cdtext_keywords[i], key)) { if (0 == strcmp (cdtext_keywords[i], key)) {
return 0; return i;
} }
return 1; return CDTEXT_INVALID;
#endif #endif
} }
/*! sets cdtext's keyword entry to field. /*! sets cdtext's keyword entry to field.
*/ */
void cdtext_set (const char *key, const char *value, cdtext_t *cdtext) void cdtext_set (cdtext_field_t key, const char *value, cdtext_t *cdtext)
{ {
if (NULL != value) /* don't pass NULL to strdup! */ if (NULL == value || key == CDTEXT_INVALID) return;
for (; NULL != cdtext->key; cdtext++)
if (0 == strcmp (cdtext->key, key)) { if (cdtext->field[key]) free (cdtext->field[key]);
free (cdtext->value); cdtext->field[key] = strdup (value);
cdtext->value = strdup (value);
}
}
/* returns value for key, NULL if key is not found */
const char *cdtext_get (const char *key, const cdtext_t *cdtext)
{
for (; NULL != cdtext->key; cdtext++)
if (0 == strcmp (cdtext->key, key))
return (cdtext->value);
return (NULL);
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: image.h,v 1.2 2004/07/10 11:06:00 rocky Exp $ $Id: image.h,v 1.3 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -59,7 +59,7 @@ typedef struct {
CdioDataSource *data_source; CdioDataSource *data_source;
track_format_t track_format; track_format_t track_format;
bool track_green; bool track_green;
cdtext_t *cdtext; /**< CD-TEXT */ cdtext_t cdtext; /**< CD-TEXT */
trackmode_t mode; trackmode_t mode;
uint16_t datasize; /**< How much is in the portion we return uint16_t datasize; /**< How much is in the portion we return

View File

@@ -1,5 +1,5 @@
/* /*
$Id: bincue.c,v 1.32 2004/07/11 02:28:06 rocky Exp $ $Id: bincue.c,v 1.33 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -26,7 +26,7 @@
(*.cue). (*.cue).
*/ */
static const char _rcsid[] = "$Id: bincue.c,v 1.32 2004/07/11 02:28:06 rocky Exp $"; static const char _rcsid[] = "$Id: bincue.c,v 1.33 2004/07/11 14:25:07 rocky Exp $";
#include "image.h" #include "image.h"
#include "cdio_assert.h" #include "cdio_assert.h"
@@ -81,15 +81,16 @@ typedef struct {
exactly 13 bytes */ exactly 13 bytes */
track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track
add 1 for leadout. */ add 1 for leadout. */
track_t i_tracks; /* number of tracks in image */ track_t i_tracks; /* number of tracks in image */
track_t i_first_track; /* track number of first track */ track_t i_first_track; /* track number of first track */
cdtext_t *cdtext; /* CD-TEXT */ cdtext_t cdtext; /* CD-TEXT */
track_format_t mode; track_format_t mode;
} _img_private_t; } _img_private_t;
static uint32_t _stat_size_bincue (void *user_data); static uint32_t _stat_size_bincue (void *user_data);
static bool parse_cuefile (_img_private_t *cd, const char *toc_name); static bool parse_cuefile (_img_private_t *cd, const char *toc_name);
#define NEED_MEDIA_EJECT_IMAGE
#include "image_common.h" #include "image_common.h"
/*! /*!
@@ -114,7 +115,8 @@ _bincue_init (_img_private_t *env)
env->gen.init = true; env->gen.init = true;
env->i_first_track = 1; env->i_first_track = 1;
env->psz_mcn = NULL; env->psz_mcn = NULL;
env->cdtext = NULL;
cdtext_init (&(env->cdtext));
lead_lsn = _stat_size_bincue( (_img_private_t *) env); lead_lsn = _stat_size_bincue( (_img_private_t *) env);
@@ -267,14 +269,19 @@ _stat_size_bincue (void *user_data)
static bool static bool
parse_cuefile (_img_private_t *cd, const char *psz_cue_name) parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
{ {
/* The below declarations may be common in other image-parse routines. */
FILE *fp; FILE *fp;
char psz_line[MAXLINE]; char psz_line[MAXLINE]; /* text of current line read in file fp. */
unsigned int i_line=0; unsigned int i_line=0; /* line number in file of psz_line. */
int start_index; int i = -1; /* Position in tocent. Same as
cd->i_tracks - 1 */
char *psz_keyword, *psz_field; char *psz_keyword, *psz_field;
cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN; cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN;
cdtext_field_t cdtext_key;
/* The below declarations may be unique to this image-parse routine. */
int start_index;
bool b_first_index_for_track=false; bool b_first_index_for_track=false;
int i = -1; /* Position in tocent. Same as cd->i_tracks - 1 */
if (NULL == psz_cue_name) if (NULL == psz_cue_name)
return false; return false;
@@ -357,8 +364,7 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
/* TRACK N <mode> */ /* TRACK N <mode> */
} else if (0 == strcmp ("TRACK", psz_keyword)) { } else if (0 == strcmp ("TRACK", psz_keyword)) {
int i_track; int i_track;
i++;
if (cd) cd->tocent[i].cdtext = NULL;
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
if (1!=sscanf(psz_field, "%d", &i_track)) { if (1!=sscanf(psz_field, "%d", &i_track)) {
cdio_log(log_level, cdio_log(log_level,
@@ -377,6 +383,7 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
this_track->track_num = cd->i_tracks; this_track->track_num = cd->i_tracks;
this_track->num_indices = 0; this_track->num_indices = 0;
b_first_index_for_track = false; b_first_index_for_track = false;
cdtext_init (&(cd->tocent[cd->i_tracks].cdtext));
cd->i_tracks++; cd->i_tracks++;
} }
i++; i++;
@@ -606,20 +613,17 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
} }
/* CD-TEXT */ /* CD-TEXT */
} else if (0 == cdtext_is_keyword (psz_keyword)) { } else if ( CDTEXT_INVALID !=
(cdtext_key = cdtext_is_keyword (psz_keyword)) ) {
if (-1 == i) { if (-1 == i) {
if (NULL == cd->cdtext) if (cd) {
if (cd) { cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"), &(cd->cdtext));
cd->cdtext = cdtext_init (); }
cdtext_set (psz_keyword, strtok (NULL, "\"\t\n\r"), cd->cdtext);
}
} else { } else {
if (NULL == cd->tocent[i].cdtext) if (cd) {
if (cd) { cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"),
cd->tocent[i].cdtext = cdtext_init (); &(cd->tocent[i].cdtext));
cdtext_set (psz_keyword, strtok (NULL, "\"\t\n\r"), }
cd->tocent[i].cdtext);
}
} }
/* unrecognized line */ /* unrecognized line */
@@ -1020,6 +1024,7 @@ cdio_open_cue (const char *psz_cue_name)
.eject_media = _eject_media_image, .eject_media = _eject_media_image,
.free = _free_image, .free = _free_image,
.get_arg = _get_arg_image, .get_arg = _get_arg_image,
.get_cdtext = _get_cdtext_image,
.get_devices = cdio_get_devices_bincue, .get_devices = cdio_get_devices_bincue,
.get_default_device = cdio_get_default_device_bincue, .get_default_device = cdio_get_default_device_bincue,
.get_drive_cap = _get_drive_cap_bincue, .get_drive_cap = _get_drive_cap_bincue,

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdrdao.c,v 1.18 2004/07/11 02:28:07 rocky Exp $ $Id: cdrdao.c,v 1.19 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
toc reading routine adapted from cuetools toc reading routine adapted from cuetools
@@ -25,7 +25,7 @@
(*.cue). (*.cue).
*/ */
static const char _rcsid[] = "$Id: cdrdao.c,v 1.18 2004/07/11 02:28:07 rocky Exp $"; static const char _rcsid[] = "$Id: cdrdao.c,v 1.19 2004/07/11 14:25:07 rocky Exp $";
#include "image.h" #include "image.h"
#include "cdio_assert.h" #include "cdio_assert.h"
@@ -81,15 +81,16 @@ typedef struct {
exactly 13 bytes */ exactly 13 bytes */
track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track
add 1 for leadout. */ add 1 for leadout. */
track_t i_tracks; /* number of tracks in image */ track_t i_tracks; /* number of tracks in image */
track_t i_first_track; /* track number of first track */ track_t i_first_track; /* track number of first track */
cdtext_t *cdtext; /* CD-TEXT */ cdtext_t cdtext; /* CD-TEXT */
track_format_t mode; track_format_t mode;
} _img_private_t; } _img_private_t;
static uint32_t _stat_size_cdrdao (void *user_data); static uint32_t _stat_size_cdrdao (void *user_data);
static bool parse_tocfile (_img_private_t *cd, const char *toc_name); static bool parse_tocfile (_img_private_t *cd, const char *toc_name);
#define NEED_MEDIA_EJECT_IMAGE
#include "image_common.h" #include "image_common.h"
/*! /*!
@@ -109,7 +110,8 @@ _init_cdrdao (_img_private_t *env)
env->gen.init = true; env->gen.init = true;
env->i_first_track = 1; env->i_first_track = 1;
env->psz_mcn = NULL; env->psz_mcn = NULL;
env->cdtext = NULL;
cdtext_init (&(env->cdtext));
/* Read in TOC sheet. */ /* Read in TOC sheet. */
if ( !parse_tocfile(env, env->psz_cue_name) ) return false; if ( !parse_tocfile(env, env->psz_cue_name) ) return false;
@@ -259,19 +261,24 @@ _stat_size_cdrdao (void *user_data)
#define MAXLINE 512 #define MAXLINE 512
#define UNIMPLIMENTED_MSG \ #define UNIMPLIMENTED_MSG \
cdio_log(log_level, "%s line %d: unimplimented keyword: %s", \ cdio_log(log_level, "%s line %d: unimplimented keyword: %s", \
psz_cue_name, i_line, keyword) psz_cue_name, i_line, psz_keyword)
static bool static bool
parse_tocfile (_img_private_t *cd, const char *psz_cue_name) parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
{ {
char psz_line[MAXLINE]; /* The below declarations may be common in other image-parse routines. */
unsigned int i_cdtext_nest = 0; FILE *fp;
FILE *fp; char psz_line[MAXLINE]; /* text of current line read in file fp. */
unsigned int i_line=0; unsigned int i_line=0; /* line number in file of psz_line. */
char *keyword, *psz_field; int i = -1; /* Position in tocent. Same as
int i = -1; cd->i_tracks - 1 */
char *psz_keyword, *psz_field;
cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN; cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN;
cdtext_field_t cdtext_key;
/* The below declaration(s) may be unique to this image-parse routine. */
unsigned int i_cdtext_nest = 0;
if (NULL == psz_cue_name) if (NULL == psz_cue_name)
return false; return false;
@@ -293,9 +300,9 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
if (NULL != (psz_field = strstr (psz_line, "//"))) if (NULL != (psz_field = strstr (psz_line, "//")))
*psz_field = '\0'; *psz_field = '\0';
if (NULL != (keyword = strtok (psz_line, " \t\n\r"))) { if (NULL != (psz_keyword = strtok (psz_line, " \t\n\r"))) {
/* CATALOG "ddddddddddddd" */ /* CATALOG "ddddddddddddd" */
if (0 == strcmp ("CATALOG", keyword)) { if (0 == strcmp ("CATALOG", psz_keyword)) {
if (-1 == i) { if (-1 == i) {
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) { if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
if (13 != strlen(psz_field)) { if (13 != strlen(psz_field)) {
@@ -336,14 +343,14 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* CD_DA | CD_ROM | CD_ROM_XA */ /* CD_DA | CD_ROM | CD_ROM_XA */
} else if (0 == strcmp ("CD_DA", keyword)) { } else if (0 == strcmp ("CD_DA", psz_keyword)) {
if (-1 == i) { if (-1 == i) {
if (NULL != cd) if (NULL != cd)
cd->mode = TRACK_FORMAT_AUDIO; cd->mode = TRACK_FORMAT_AUDIO;
} else { } else {
goto not_in_global_section; goto not_in_global_section;
} }
} else if (0 == strcmp ("CD_ROM", keyword)) { } else if (0 == strcmp ("CD_ROM", psz_keyword)) {
if (-1 == i) { if (-1 == i) {
if (NULL != cd) if (NULL != cd)
cd->mode = TRACK_FORMAT_DATA; cd->mode = TRACK_FORMAT_DATA;
@@ -351,7 +358,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
goto not_in_global_section; goto not_in_global_section;
} }
} else if (0 == strcmp ("CD_ROM_XA", keyword)) { } else if (0 == strcmp ("CD_ROM_XA", psz_keyword)) {
if (-1 == i) { if (-1 == i) {
if (NULL != cd) if (NULL != cd)
cd->mode = TRACK_FORMAT_XA; cd->mode = TRACK_FORMAT_XA;
@@ -360,9 +367,9 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* TRACK <track-mode> [<sub-channel-mode>] */ /* TRACK <track-mode> [<sub-channel-mode>] */
} else if (0 == strcmp ("TRACK", keyword)) { } else if (0 == strcmp ("TRACK", psz_keyword)) {
i++; i++;
if (NULL != cd) cd->tocent[i].cdtext = NULL; if (NULL != cd) cdtext_init (&(cd->tocent[i].cdtext));
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
if (0 == strcmp ("AUDIO", psz_field)) { if (0 == strcmp ("AUDIO", psz_field)) {
if (NULL != cd) { if (NULL != cd) {
@@ -457,7 +464,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
/* track flags */ /* track flags */
/* [NO] COPY | [NO] PRE_EMPHASIS */ /* [NO] COPY | [NO] PRE_EMPHASIS */
} else if (0 == strcmp ("NO", keyword)) { } else if (0 == strcmp ("NO", psz_keyword)) {
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
if (0 == strcmp ("COPY", psz_field)) { if (0 == strcmp ("COPY", psz_field)) {
if (NULL != cd) if (NULL != cd)
@@ -474,23 +481,23 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error; goto format_error;
} }
} else if (0 == strcmp ("COPY", keyword)) { } else if (0 == strcmp ("COPY", psz_keyword)) {
if (NULL != cd) if (NULL != cd)
cd->tocent[i].flags |= CDIO_TRACK_FLAG_COPY_PERMITTED; cd->tocent[i].flags |= CDIO_TRACK_FLAG_COPY_PERMITTED;
} else if (0 == strcmp ("PRE_EMPHASIS", keyword)) { } else if (0 == strcmp ("PRE_EMPHASIS", psz_keyword)) {
if (NULL != cd) if (NULL != cd)
cd->tocent[i].flags |= CDIO_TRACK_FLAG_PRE_EMPHASIS; cd->tocent[i].flags |= CDIO_TRACK_FLAG_PRE_EMPHASIS;
/* TWO_CHANNEL_AUDIO */ /* TWO_CHANNEL_AUDIO */
} else if (0 == strcmp ("TWO_CHANNEL_AUDIO", keyword)) { } else if (0 == strcmp ("TWO_CHANNEL_AUDIO", psz_keyword)) {
if (NULL != cd) if (NULL != cd)
cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO; cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO;
/* FOUR_CHANNEL_AUDIO */ /* FOUR_CHANNEL_AUDIO */
} else if (0 == strcmp ("FOUR_CHANNEL_AUDIO", keyword)) { } else if (0 == strcmp ("FOUR_CHANNEL_AUDIO", psz_keyword)) {
if (NULL != cd) if (NULL != cd)
cd->tocent[i].flags |= CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO; cd->tocent[i].flags |= CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO;
/* ISRC "CCOOOYYSSSSS" */ /* ISRC "CCOOOYYSSSSS" */
} else if (0 == strcmp ("ISRC", keyword)) { } else if (0 == strcmp ("ISRC", psz_keyword)) {
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) { if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
if (NULL != cd) if (NULL != cd)
cd->tocent[i].isrc = strdup(psz_field); cd->tocent[i].isrc = strdup(psz_field);
@@ -499,16 +506,16 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* SILENCE <length> */ /* SILENCE <length> */
} else if (0 == strcmp ("SILENCE", keyword)) { } else if (0 == strcmp ("SILENCE", psz_keyword)) {
UNIMPLIMENTED_MSG; UNIMPLIMENTED_MSG;
/* ZERO <length> */ /* ZERO <length> */
} else if (0 == strcmp ("ZERO", keyword)) { } else if (0 == strcmp ("ZERO", psz_keyword)) {
UNIMPLIMENTED_MSG; UNIMPLIMENTED_MSG;
/* [FILE|AUDIOFILE] "<filename>" <start> [<length>] */ /* [FILE|AUDIOFILE] "<filename>" <start> [<length>] */
} else if (0 == strcmp ("FILE", keyword) } else if (0 == strcmp ("FILE", psz_keyword)
|| 0 == strcmp ("AUDIOFILE", keyword)) { || 0 == strcmp ("AUDIOFILE", psz_keyword)) {
if (0 <= i) { if (0 <= i) {
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) { if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
if (NULL != cd) { if (NULL != cd) {
@@ -547,15 +554,15 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* DATAFILE "<filename>" <start> [<length>] */ /* DATAFILE "<filename>" <start> [<length>] */
} else if (0 == strcmp ("DATAFILE", keyword)) { } else if (0 == strcmp ("DATAFILE", psz_keyword)) {
goto unimplimented_error; goto unimplimented_error;
/* FIFO "<fifo path>" [<length>] */ /* FIFO "<fifo path>" [<length>] */
} else if (0 == strcmp ("FIFO", keyword)) { } else if (0 == strcmp ("FIFO", psz_keyword)) {
goto unimplimented_error; goto unimplimented_error;
/* START MM:SS:FF */ /* START MM:SS:FF */
} else if (0 == strcmp ("START", keyword)) { } else if (0 == strcmp ("START", psz_keyword)) {
if (0 <= i) { if (0 <= i) {
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
/* todo: line is too long! */ /* todo: line is too long! */
@@ -574,7 +581,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* PREGAP MM:SS:FF */ /* PREGAP MM:SS:FF */
} else if (0 == strcmp ("PREGAP", keyword)) { } else if (0 == strcmp ("PREGAP", psz_keyword)) {
if (0 <= i) { if (0 <= i) {
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
if (NULL != cd) if (NULL != cd)
@@ -590,7 +597,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
/* INDEX MM:SS:FF */ /* INDEX MM:SS:FF */
} else if (0 == strcmp ("INDEX", keyword)) { } else if (0 == strcmp ("INDEX", psz_keyword)) {
if (0 <= i) { if (0 <= i) {
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
if (NULL != cd) { if (NULL != cd) {
@@ -618,7 +625,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
/* CD_TEXT { ... } */ /* CD_TEXT { ... } */
/* todo: opening { must be on same line as CD_TEXT */ /* todo: opening { must be on same line as CD_TEXT */
} else if (0 == strcmp ("CD_TEXT", keyword)) { } else if (0 == strcmp ("CD_TEXT", psz_keyword)) {
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error; goto format_error;
} }
@@ -630,8 +637,9 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
goto err_exit; goto err_exit;
} }
} else if (0 == strcmp ("LANGUAGE_MAP", keyword)) { } else if (0 == strcmp ("LANGUAGE_MAP", psz_keyword)) {
} else if (0 == strcmp ("LANGUAGE", keyword)) { /* LANGUAGE d { ... } */
} else if (0 == strcmp ("LANGUAGE", psz_keyword)) {
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) { if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
goto format_error; goto format_error;
} }
@@ -641,33 +649,28 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
} }
if ( 0 == strcmp( "{", psz_field ) ) { if ( 0 == strcmp( "{", psz_field ) ) {
i_cdtext_nest++; i_cdtext_nest++;
} else {
cdio_log (log_level,
"%s line %d: expecting '{'", psz_cue_name, i_line);
goto err_exit;
} }
} else if (0 == strcmp ("}", keyword)) { } else if (0 == strcmp ("{", psz_keyword)) {
i_cdtext_nest++;
} else if (0 == strcmp ("}", psz_keyword)) {
if (i_cdtext_nest > 0) i_cdtext_nest--; if (i_cdtext_nest > 0) i_cdtext_nest--;
} else if (0 == cdtext_is_keyword (keyword)) { } else if ( CDTEXT_INVALID !=
(cdtext_key = cdtext_is_keyword (psz_keyword)) ) {
if (-1 == i) { if (-1 == i) {
if (NULL != cd) { if (NULL != cd) {
if (NULL == cd->cdtext) cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"), &(cd->cdtext));
cd->cdtext = cdtext_init ();
cdtext_set (keyword, strtok (NULL, "\"\t\n\r"), cd->cdtext);
} }
} else { } else {
if (NULL != cd) { if (NULL != cd) {
if (NULL == cd->tocent[i].cdtext) cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"),
cd->tocent[i].cdtext = cdtext_init (); &(cd->tocent[i].cdtext));
cdtext_set (keyword, strtok (NULL, "\"\t\n\r"),
cd->tocent[i].cdtext);
} }
} }
/* unrecognized line */ /* unrecognized line */
} else { } else {
cdio_log(log_level, "%s line %d: warning: unrecognized keyword: %s", cdio_log(log_level, "%s line %d: warning: unrecognized word: %s",
psz_cue_name, i_line, keyword); psz_cue_name, i_line, psz_keyword);
goto err_exit; goto err_exit;
} }
} }
@@ -682,13 +685,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
goto err_exit; goto err_exit;
format_error: format_error:
cdio_log(log_level, "%s line %d after keyword %s", cdio_log(log_level, "%s line %d after word %s",
psz_cue_name, i_line, keyword); psz_cue_name, i_line, psz_keyword);
goto err_exit; goto err_exit;
not_in_global_section: not_in_global_section:
cdio_log(log_level, "%s line %d: keyword %s only allowed in global section", cdio_log(log_level, "%s line %d: word %s only allowed in global section",
psz_cue_name, i_line, keyword); psz_cue_name, i_line, psz_keyword);
err_exit: err_exit:
fclose (fp); fclose (fp);
@@ -1002,6 +1005,7 @@ cdio_open_cdrdao (const char *psz_cue_name)
.eject_media = _eject_media_image, .eject_media = _eject_media_image,
.free = _free_image, .free = _free_image,
.get_arg = _get_arg_image, .get_arg = _get_arg_image,
.get_cdtext = _get_cdtext_image,
.get_devices = cdio_get_devices_cdrdao, .get_devices = cdio_get_devices_cdrdao,
.get_default_device = cdio_get_default_device_cdrdao, .get_default_device = cdio_get_default_device_cdrdao,
.get_drive_cap = _get_drive_cap_cdrdao, .get_drive_cap = _get_drive_cap_cdrdao,

View File

@@ -1,5 +1,5 @@
/* /*
$Id: nrg.c,v 1.30 2004/07/11 02:28:07 rocky Exp $ $Id: nrg.c,v 1.31 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -45,7 +45,7 @@
#include "_cdio_stdio.h" #include "_cdio_stdio.h"
#include "nrg.h" #include "nrg.h"
static const char _rcsid[] = "$Id: nrg.c,v 1.30 2004/07/11 02:28:07 rocky Exp $"; static const char _rcsid[] = "$Id: nrg.c,v 1.31 2004/07/11 14:25:07 rocky Exp $";
/* reader */ /* reader */
@@ -79,7 +79,7 @@ typedef struct {
add 1 for leadout. */ add 1 for leadout. */
track_t i_tracks; /* number of tracks in image */ track_t i_tracks; /* number of tracks in image */
track_t i_first_track; /* track number of first track */ track_t i_first_track; /* track number of first track */
cdtext_t *cdtext; /* CD-TEXT */ cdtext_t cdtext; /* CD-TEXT */
track_format_t mode; track_format_t mode;
/* Nero Specific stuff. Note: for the image_free to work, this *must* /* Nero Specific stuff. Note: for the image_free to work, this *must*
@@ -756,7 +756,8 @@ _init_nrg (_img_private_t *env)
} }
env->psz_mcn = NULL; env->psz_mcn = NULL;
env->cdtext = NULL;
cdtext_init (&(env->cdtext));
if ( !parse_nrg (env, env->gen.source_name) ) { if ( !parse_nrg (env, env->gen.source_name) ) {
cdio_warn ("image file %s is not a Nero image", cdio_warn ("image file %s is not a Nero image",
@@ -1202,6 +1203,7 @@ cdio_open_nrg (const char *psz_source)
.eject_media = _eject_media_nrg, .eject_media = _eject_media_nrg,
.free = _free_nrg, .free = _free_nrg,
.get_arg = _get_arg_image, .get_arg = _get_arg_image,
.get_cdtext = _get_cdtext_image,
.get_devices = cdio_get_devices_nrg, .get_devices = cdio_get_devices_nrg,
.get_default_device = cdio_get_default_device_nrg, .get_default_device = cdio_get_default_device_nrg,
.get_drive_cap = _get_drive_cap_nrg, .get_drive_cap = _get_drive_cap_nrg,

View File

@@ -1,5 +1,5 @@
/* /*
$Id: image_common.h,v 1.8 2004/07/10 11:06:00 rocky Exp $ $Id: image_common.h,v 1.9 2004/07/11 14:25:07 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -40,24 +40,25 @@
static void static void
_free_image (void *user_data) _free_image (void *user_data)
{ {
_img_private_t *cd = user_data; _img_private_t *env = user_data;
track_t i_track; track_t i_track;
if (NULL == cd) return; if (NULL == env) return;
for (i_track=0; i_track < cd->i_tracks; i_track++) { for (i_track=0; i_track < env->i_tracks; i_track++) {
free_if_notnull(cd->tocent[i_track].filename); free_if_notnull(env->tocent[i_track].filename);
free_if_notnull(cd->tocent[i_track].isrc); free_if_notnull(env->tocent[i_track].isrc);
cdtext_delete(cd->tocent[i_track].cdtext); cdtext_destroy(&(env->tocent[i_track].cdtext));
} }
free_if_notnull(cd->psz_mcn); free_if_notnull(env->psz_mcn);
free_if_notnull(cd->psz_cue_name); free_if_notnull(env->psz_cue_name);
cdtext_delete(cd->cdtext); cdtext_destroy(&(env->cdtext));
cdio_generic_stdio_free(cd); cdio_generic_stdio_free(env);
free(cd); free(env);
} }
#ifdef NEED_MEDIA_EJECT_IMAGE
/*! /*!
Eject media -- there's nothing to do here except free resources. Eject media -- there's nothing to do here except free resources.
We always return 2. We always return 2.
@@ -68,6 +69,7 @@ _eject_media_image(void *user_data)
_free_image (user_data); _free_image (user_data);
return 2; return 2;
} }
#endif
/*! /*!
Return the value associated with the key "arg". Return the value associated with the key "arg".
@@ -87,6 +89,18 @@ _get_arg_image (void *user_data, const char key[])
return NULL; return NULL;
} }
/*!
Return the value associated with the key "arg".
*/
static const cdtext_t *
_get_cdtext_image (const void *user_data)
{
const _img_private_t *env = user_data;
if (NULL == env) return NULL;
return &(env->cdtext);
}
/*! /*!
Return the media catalog number (MCN) from the CD or NULL if there Return the media catalog number (MCN) from the CD or NULL if there
is none or we don't have the ability to get it. is none or we don't have the ability to get it.
@@ -99,7 +113,7 @@ _get_mcn_image(const void *user_data)
{ {
const _img_private_t *env = user_data; const _img_private_t *env = user_data;
if (NULL == env->psz_mcn) return NULL; if (NULL == env || NULL == env->psz_mcn) return NULL;
return strdup(env->psz_mcn); return strdup(env->psz_mcn);
} }

View File

@@ -1,3 +1,5 @@
TITLE "Join us now we have the software"
PERFORMER "Richard Stallman"
FILE "BOING.BIN" BINARY FILE "BOING.BIN" BINARY
TRACK 01 AUDIO TRACK 01 AUDIO
INDEX 01 00:00:00 INDEX 01 00:00:00