Redo CD-TEXT handling. First minimally working version for CD bin/cue
and cdrdao images.
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -29,16 +29,27 @@
|
||||
int
|
||||
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) {
|
||||
printf("Couldn't find a driver.. leaving.\n");
|
||||
printf("Couldn't open ../test/cdda.cue with BIN/CUE driver \n");
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*- 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) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||
@@ -55,9 +55,12 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** This is an opaque structure. */
|
||||
/** This is an opaque structure for the CD object. */
|
||||
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
|
||||
* that is opened or is desired to be opened. Note that this is
|
||||
* different than what is available on a given host.
|
||||
@@ -82,9 +85,9 @@ extern "C" {
|
||||
DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed
|
||||
before BINCUE, to make the code prefer cdrdao
|
||||
over BINCUE when both exist. */
|
||||
DRIVER_BINCUE, /**< BIN/CUE format CD image. This is listed before NRG,
|
||||
to make the code prefer BINCUE over NRG when both
|
||||
exist. */
|
||||
DRIVER_BINCUE, /**< CDRWIN BIN/CUE format CD image. This is
|
||||
listed before NRG, to make the code prefer
|
||||
BINCUE over NRG when both exist. */
|
||||
DRIVER_NRG, /**< Nero NRG format CD image. */
|
||||
DRIVER_DEVICE /**< Is really a set of the above; should come last */
|
||||
} driver_id_t;
|
||||
@@ -151,6 +154,15 @@ extern "C" {
|
||||
*/
|
||||
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
|
||||
least the capabilities listed by cap. If search_devices is NULL,
|
||||
|
||||
@@ -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>
|
||||
adapted from cuetools
|
||||
@@ -34,32 +34,55 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct cdtext cdtext_t;
|
||||
#define MAX_CDTEXT_FIELDS 13
|
||||
|
||||
/*! Initialize and allocate a new cdtext structure and return a
|
||||
pointer to that. When the structure is no longer needed, release the
|
||||
struct cdtext {
|
||||
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.
|
||||
*/
|
||||
cdtext_t *cdtext_init (void);
|
||||
void cdtext_init (cdtext_t *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
|
||||
*/
|
||||
void cdtext_set (const char *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);
|
||||
|
||||
void cdtext_set (cdtext_field_t key, const char *value, cdtext_t *cdtext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
23
lib/cdio.c
23
lib/cdio.c
@@ -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) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <cdio/logging.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] =
|
||||
@@ -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.
|
||||
if CdIo is NULL (we haven't initialized a specific device driver),
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -56,6 +56,11 @@ extern "C" {
|
||||
*/
|
||||
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
|
||||
initialized a specific device driver), then find a suitable device
|
||||
|
||||
101
lib/cdtext.c
101
lib/cdtext.c
@@ -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>
|
||||
toc reading routine adapted from cuetools
|
||||
@@ -35,62 +35,50 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* Private type */
|
||||
struct cdtext {
|
||||
const char *key;
|
||||
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 ()
|
||||
/*! Free memory assocated with cdtext*/
|
||||
void
|
||||
cdtext_destroy (cdtext_t *cdtext)
|
||||
{
|
||||
cdtext_t *new_cdtext = NULL;
|
||||
cdtext_field_t i;
|
||||
|
||||
new_cdtext = (cdtext_t *) calloc (sizeof (cdtext) / sizeof (cdtext_t),
|
||||
sizeof (cdtext_t));
|
||||
if (NULL == new_cdtext)
|
||||
cdio_warn("problem allocating memory");
|
||||
else
|
||||
memcpy (new_cdtext, cdtext, sizeof(cdtext));
|
||||
|
||||
return (new_cdtext);
|
||||
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
|
||||
if (cdtext->field[i]) free(cdtext->field[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Free memory assocated with cdtext*/
|
||||
void cdtext_delete (cdtext_t *cdtext)
|
||||
/*!
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
if (key == CDTEXT_INVALID) return NULL;
|
||||
return cdtext->field[key];
|
||||
}
|
||||
|
||||
if (NULL != cdtext) {
|
||||
for (i = 0; NULL != cdtext[i].key; i++)
|
||||
free (cdtext[i].value);
|
||||
free (cdtext);
|
||||
/*! Initialize a new cdtext structure.
|
||||
When the structure is no longer needed, release the
|
||||
resources using cdtext_delete.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
int
|
||||
cdtext_field_t
|
||||
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[] =
|
||||
{
|
||||
"ARRANGER", /* name(s) of the arranger(s) */
|
||||
@@ -122,31 +110,20 @@ cdtext_is_keyword (const char *key)
|
||||
|
||||
for (i = 0; i < 13 ; i++)
|
||||
if (0 == strcmp (cdtext_keywords[i], key)) {
|
||||
return 0;
|
||||
return i;
|
||||
}
|
||||
return 1;
|
||||
return CDTEXT_INVALID;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! 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! */
|
||||
for (; NULL != cdtext->key; cdtext++)
|
||||
if (0 == strcmp (cdtext->key, key)) {
|
||||
free (cdtext->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);
|
||||
if (NULL == value || key == CDTEXT_INVALID) return;
|
||||
|
||||
if (cdtext->field[key]) free (cdtext->field[key]);
|
||||
cdtext->field[key] = strdup (value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef struct {
|
||||
CdioDataSource *data_source;
|
||||
track_format_t track_format;
|
||||
bool track_green;
|
||||
cdtext_t *cdtext; /**< CD-TEXT */
|
||||
cdtext_t cdtext; /**< CD-TEXT */
|
||||
|
||||
trackmode_t mode;
|
||||
uint16_t datasize; /**< How much is in the portion we return
|
||||
|
||||
@@ -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) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
@@ -26,7 +26,7 @@
|
||||
(*.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 "cdio_assert.h"
|
||||
@@ -83,13 +83,14 @@ typedef struct {
|
||||
add 1 for leadout. */
|
||||
track_t i_tracks; /* number of tracks in image */
|
||||
track_t i_first_track; /* track number of first track */
|
||||
cdtext_t *cdtext; /* CD-TEXT */
|
||||
cdtext_t cdtext; /* CD-TEXT */
|
||||
track_format_t mode;
|
||||
} _img_private_t;
|
||||
|
||||
static uint32_t _stat_size_bincue (void *user_data);
|
||||
static bool parse_cuefile (_img_private_t *cd, const char *toc_name);
|
||||
|
||||
#define NEED_MEDIA_EJECT_IMAGE
|
||||
#include "image_common.h"
|
||||
|
||||
/*!
|
||||
@@ -114,7 +115,8 @@ _bincue_init (_img_private_t *env)
|
||||
env->gen.init = true;
|
||||
env->i_first_track = 1;
|
||||
env->psz_mcn = NULL;
|
||||
env->cdtext = NULL;
|
||||
|
||||
cdtext_init (&(env->cdtext));
|
||||
|
||||
lead_lsn = _stat_size_bincue( (_img_private_t *) env);
|
||||
|
||||
@@ -267,14 +269,19 @@ _stat_size_bincue (void *user_data)
|
||||
static bool
|
||||
parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
|
||||
{
|
||||
/* The below declarations may be common in other image-parse routines. */
|
||||
FILE *fp;
|
||||
char psz_line[MAXLINE];
|
||||
unsigned int i_line=0;
|
||||
int start_index;
|
||||
char psz_line[MAXLINE]; /* text of current line read in file fp. */
|
||||
unsigned int i_line=0; /* line number in file of psz_line. */
|
||||
int i = -1; /* Position in tocent. Same as
|
||||
cd->i_tracks - 1 */
|
||||
char *psz_keyword, *psz_field;
|
||||
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;
|
||||
int i = -1; /* Position in tocent. Same as cd->i_tracks - 1 */
|
||||
|
||||
if (NULL == psz_cue_name)
|
||||
return false;
|
||||
@@ -357,8 +364,7 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
|
||||
/* TRACK N <mode> */
|
||||
} else if (0 == strcmp ("TRACK", psz_keyword)) {
|
||||
int i_track;
|
||||
i++;
|
||||
if (cd) cd->tocent[i].cdtext = NULL;
|
||||
|
||||
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
||||
if (1!=sscanf(psz_field, "%d", &i_track)) {
|
||||
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->num_indices = 0;
|
||||
b_first_index_for_track = false;
|
||||
cdtext_init (&(cd->tocent[cd->i_tracks].cdtext));
|
||||
cd->i_tracks++;
|
||||
}
|
||||
i++;
|
||||
@@ -606,19 +613,16 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
|
||||
/* 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 (NULL == cd->cdtext)
|
||||
if (cd) {
|
||||
cd->cdtext = cdtext_init ();
|
||||
cdtext_set (psz_keyword, strtok (NULL, "\"\t\n\r"), cd->cdtext);
|
||||
cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"), &(cd->cdtext));
|
||||
}
|
||||
} else {
|
||||
if (NULL == cd->tocent[i].cdtext)
|
||||
if (cd) {
|
||||
cd->tocent[i].cdtext = cdtext_init ();
|
||||
cdtext_set (psz_keyword, strtok (NULL, "\"\t\n\r"),
|
||||
cd->tocent[i].cdtext);
|
||||
cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"),
|
||||
&(cd->tocent[i].cdtext));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1020,6 +1024,7 @@ cdio_open_cue (const char *psz_cue_name)
|
||||
.eject_media = _eject_media_image,
|
||||
.free = _free_image,
|
||||
.get_arg = _get_arg_image,
|
||||
.get_cdtext = _get_cdtext_image,
|
||||
.get_devices = cdio_get_devices_bincue,
|
||||
.get_default_device = cdio_get_default_device_bincue,
|
||||
.get_drive_cap = _get_drive_cap_bincue,
|
||||
|
||||
@@ -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>
|
||||
toc reading routine adapted from cuetools
|
||||
@@ -25,7 +25,7 @@
|
||||
(*.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 "cdio_assert.h"
|
||||
@@ -83,13 +83,14 @@ typedef struct {
|
||||
add 1 for leadout. */
|
||||
track_t i_tracks; /* number of tracks in image */
|
||||
track_t i_first_track; /* track number of first track */
|
||||
cdtext_t *cdtext; /* CD-TEXT */
|
||||
cdtext_t cdtext; /* CD-TEXT */
|
||||
track_format_t mode;
|
||||
} _img_private_t;
|
||||
|
||||
static uint32_t _stat_size_cdrdao (void *user_data);
|
||||
static bool parse_tocfile (_img_private_t *cd, const char *toc_name);
|
||||
|
||||
#define NEED_MEDIA_EJECT_IMAGE
|
||||
#include "image_common.h"
|
||||
|
||||
/*!
|
||||
@@ -109,7 +110,8 @@ _init_cdrdao (_img_private_t *env)
|
||||
env->gen.init = true;
|
||||
env->i_first_track = 1;
|
||||
env->psz_mcn = NULL;
|
||||
env->cdtext = NULL;
|
||||
|
||||
cdtext_init (&(env->cdtext));
|
||||
|
||||
/* Read in TOC sheet. */
|
||||
if ( !parse_tocfile(env, env->psz_cue_name) ) return false;
|
||||
@@ -259,19 +261,24 @@ _stat_size_cdrdao (void *user_data)
|
||||
#define MAXLINE 512
|
||||
#define UNIMPLIMENTED_MSG \
|
||||
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
|
||||
parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
{
|
||||
char psz_line[MAXLINE];
|
||||
unsigned int i_cdtext_nest = 0;
|
||||
/* The below declarations may be common in other image-parse routines. */
|
||||
FILE *fp;
|
||||
unsigned int i_line=0;
|
||||
char *keyword, *psz_field;
|
||||
int i = -1;
|
||||
char psz_line[MAXLINE]; /* text of current line read in file fp. */
|
||||
unsigned int i_line=0; /* line number in file of psz_line. */
|
||||
int i = -1; /* Position in tocent. Same as
|
||||
cd->i_tracks - 1 */
|
||||
char *psz_keyword, *psz_field;
|
||||
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)
|
||||
return false;
|
||||
@@ -293,9 +300,9 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
if (NULL != (psz_field = strstr (psz_line, "//")))
|
||||
*psz_field = '\0';
|
||||
|
||||
if (NULL != (keyword = strtok (psz_line, " \t\n\r"))) {
|
||||
if (NULL != (psz_keyword = strtok (psz_line, " \t\n\r"))) {
|
||||
/* CATALOG "ddddddddddddd" */
|
||||
if (0 == strcmp ("CATALOG", keyword)) {
|
||||
if (0 == strcmp ("CATALOG", psz_keyword)) {
|
||||
if (-1 == i) {
|
||||
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
||||
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 */
|
||||
} else if (0 == strcmp ("CD_DA", keyword)) {
|
||||
} else if (0 == strcmp ("CD_DA", psz_keyword)) {
|
||||
if (-1 == i) {
|
||||
if (NULL != cd)
|
||||
cd->mode = TRACK_FORMAT_AUDIO;
|
||||
} else {
|
||||
goto not_in_global_section;
|
||||
}
|
||||
} else if (0 == strcmp ("CD_ROM", keyword)) {
|
||||
} else if (0 == strcmp ("CD_ROM", psz_keyword)) {
|
||||
if (-1 == i) {
|
||||
if (NULL != cd)
|
||||
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;
|
||||
}
|
||||
|
||||
} else if (0 == strcmp ("CD_ROM_XA", keyword)) {
|
||||
} else if (0 == strcmp ("CD_ROM_XA", psz_keyword)) {
|
||||
if (-1 == i) {
|
||||
if (NULL != cd)
|
||||
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>] */
|
||||
} else if (0 == strcmp ("TRACK", keyword)) {
|
||||
} else if (0 == strcmp ("TRACK", psz_keyword)) {
|
||||
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 (0 == strcmp ("AUDIO", psz_field)) {
|
||||
if (NULL != cd) {
|
||||
@@ -457,7 +464,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
|
||||
/* track flags */
|
||||
/* [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 (0 == strcmp ("COPY", psz_field)) {
|
||||
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"))) {
|
||||
goto format_error;
|
||||
}
|
||||
} else if (0 == strcmp ("COPY", keyword)) {
|
||||
} else if (0 == strcmp ("COPY", psz_keyword)) {
|
||||
if (NULL != cd)
|
||||
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)
|
||||
cd->tocent[i].flags |= CDIO_TRACK_FLAG_PRE_EMPHASIS;
|
||||
/* TWO_CHANNEL_AUDIO */
|
||||
} else if (0 == strcmp ("TWO_CHANNEL_AUDIO", keyword)) {
|
||||
} else if (0 == strcmp ("TWO_CHANNEL_AUDIO", psz_keyword)) {
|
||||
if (NULL != cd)
|
||||
cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_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)
|
||||
cd->tocent[i].flags |= CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO;
|
||||
|
||||
/* 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 != cd)
|
||||
cd->tocent[i].isrc = strdup(psz_field);
|
||||
@@ -499,16 +506,16 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
|
||||
/* SILENCE <length> */
|
||||
} else if (0 == strcmp ("SILENCE", keyword)) {
|
||||
} else if (0 == strcmp ("SILENCE", psz_keyword)) {
|
||||
UNIMPLIMENTED_MSG;
|
||||
|
||||
/* ZERO <length> */
|
||||
} else if (0 == strcmp ("ZERO", keyword)) {
|
||||
} else if (0 == strcmp ("ZERO", psz_keyword)) {
|
||||
UNIMPLIMENTED_MSG;
|
||||
|
||||
/* [FILE|AUDIOFILE] "<filename>" <start> [<length>] */
|
||||
} else if (0 == strcmp ("FILE", keyword)
|
||||
|| 0 == strcmp ("AUDIOFILE", keyword)) {
|
||||
} else if (0 == strcmp ("FILE", psz_keyword)
|
||||
|| 0 == strcmp ("AUDIOFILE", psz_keyword)) {
|
||||
if (0 <= i) {
|
||||
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
||||
if (NULL != cd) {
|
||||
@@ -547,15 +554,15 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
|
||||
/* DATAFILE "<filename>" <start> [<length>] */
|
||||
} else if (0 == strcmp ("DATAFILE", keyword)) {
|
||||
} else if (0 == strcmp ("DATAFILE", psz_keyword)) {
|
||||
goto unimplimented_error;
|
||||
|
||||
/* FIFO "<fifo path>" [<length>] */
|
||||
} else if (0 == strcmp ("FIFO", keyword)) {
|
||||
} else if (0 == strcmp ("FIFO", psz_keyword)) {
|
||||
goto unimplimented_error;
|
||||
|
||||
/* START MM:SS:FF */
|
||||
} else if (0 == strcmp ("START", keyword)) {
|
||||
} else if (0 == strcmp ("START", psz_keyword)) {
|
||||
if (0 <= i) {
|
||||
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
||||
/* todo: line is too long! */
|
||||
@@ -574,7 +581,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
|
||||
/* PREGAP MM:SS:FF */
|
||||
} else if (0 == strcmp ("PREGAP", keyword)) {
|
||||
} else if (0 == strcmp ("PREGAP", psz_keyword)) {
|
||||
if (0 <= i) {
|
||||
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
||||
if (NULL != cd)
|
||||
@@ -590,7 +597,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
|
||||
/* INDEX MM:SS:FF */
|
||||
} else if (0 == strcmp ("INDEX", keyword)) {
|
||||
} else if (0 == strcmp ("INDEX", psz_keyword)) {
|
||||
if (0 <= i) {
|
||||
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
||||
if (NULL != cd) {
|
||||
@@ -618,7 +625,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
|
||||
/* 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"))) {
|
||||
goto format_error;
|
||||
}
|
||||
@@ -630,8 +637,9 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
} else if (0 == strcmp ("LANGUAGE_MAP", keyword)) {
|
||||
} else if (0 == strcmp ("LANGUAGE", keyword)) {
|
||||
} else if (0 == strcmp ("LANGUAGE_MAP", psz_keyword)) {
|
||||
/* LANGUAGE d { ... } */
|
||||
} else if (0 == strcmp ("LANGUAGE", psz_keyword)) {
|
||||
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
|
||||
goto format_error;
|
||||
}
|
||||
@@ -641,33 +649,28 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
}
|
||||
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;
|
||||
}
|
||||
} 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--;
|
||||
} else if (0 == cdtext_is_keyword (keyword)) {
|
||||
} else if ( CDTEXT_INVALID !=
|
||||
(cdtext_key = cdtext_is_keyword (psz_keyword)) ) {
|
||||
if (-1 == i) {
|
||||
if (NULL != cd) {
|
||||
if (NULL == cd->cdtext)
|
||||
cd->cdtext = cdtext_init ();
|
||||
cdtext_set (keyword, strtok (NULL, "\"\t\n\r"), cd->cdtext);
|
||||
cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"), &(cd->cdtext));
|
||||
}
|
||||
} else {
|
||||
if (NULL != cd) {
|
||||
if (NULL == cd->tocent[i].cdtext)
|
||||
cd->tocent[i].cdtext = cdtext_init ();
|
||||
cdtext_set (keyword, strtok (NULL, "\"\t\n\r"),
|
||||
cd->tocent[i].cdtext);
|
||||
cdtext_set (cdtext_key, strtok (NULL, "\"\t\n\r"),
|
||||
&(cd->tocent[i].cdtext));
|
||||
}
|
||||
}
|
||||
|
||||
/* unrecognized line */
|
||||
} else {
|
||||
cdio_log(log_level, "%s line %d: warning: unrecognized keyword: %s",
|
||||
psz_cue_name, i_line, keyword);
|
||||
cdio_log(log_level, "%s line %d: warning: unrecognized word: %s",
|
||||
psz_cue_name, i_line, psz_keyword);
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
@@ -682,13 +685,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
||||
goto err_exit;
|
||||
|
||||
format_error:
|
||||
cdio_log(log_level, "%s line %d after keyword %s",
|
||||
psz_cue_name, i_line, keyword);
|
||||
cdio_log(log_level, "%s line %d after word %s",
|
||||
psz_cue_name, i_line, psz_keyword);
|
||||
goto err_exit;
|
||||
|
||||
not_in_global_section:
|
||||
cdio_log(log_level, "%s line %d: keyword %s only allowed in global section",
|
||||
psz_cue_name, i_line, keyword);
|
||||
cdio_log(log_level, "%s line %d: word %s only allowed in global section",
|
||||
psz_cue_name, i_line, psz_keyword);
|
||||
|
||||
err_exit:
|
||||
fclose (fp);
|
||||
@@ -1002,6 +1005,7 @@ cdio_open_cdrdao (const char *psz_cue_name)
|
||||
.eject_media = _eject_media_image,
|
||||
.free = _free_image,
|
||||
.get_arg = _get_arg_image,
|
||||
.get_cdtext = _get_cdtext_image,
|
||||
.get_devices = cdio_get_devices_cdrdao,
|
||||
.get_default_device = cdio_get_default_device_cdrdao,
|
||||
.get_drive_cap = _get_drive_cap_cdrdao,
|
||||
|
||||
@@ -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) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "_cdio_stdio.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 */
|
||||
@@ -79,7 +79,7 @@ typedef struct {
|
||||
add 1 for leadout. */
|
||||
track_t i_tracks; /* number of tracks in image */
|
||||
track_t i_first_track; /* track number of first track */
|
||||
cdtext_t *cdtext; /* CD-TEXT */
|
||||
cdtext_t cdtext; /* CD-TEXT */
|
||||
track_format_t mode;
|
||||
|
||||
/* 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->cdtext = NULL;
|
||||
|
||||
cdtext_init (&(env->cdtext));
|
||||
|
||||
if ( !parse_nrg (env, env->gen.source_name) ) {
|
||||
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,
|
||||
.free = _free_nrg,
|
||||
.get_arg = _get_arg_image,
|
||||
.get_cdtext = _get_cdtext_image,
|
||||
.get_devices = cdio_get_devices_nrg,
|
||||
.get_default_device = cdio_get_default_device_nrg,
|
||||
.get_drive_cap = _get_drive_cap_nrg,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -40,24 +40,25 @@
|
||||
static void
|
||||
_free_image (void *user_data)
|
||||
{
|
||||
_img_private_t *cd = user_data;
|
||||
_img_private_t *env = user_data;
|
||||
track_t i_track;
|
||||
|
||||
if (NULL == cd) return;
|
||||
if (NULL == env) return;
|
||||
|
||||
for (i_track=0; i_track < cd->i_tracks; i_track++) {
|
||||
free_if_notnull(cd->tocent[i_track].filename);
|
||||
free_if_notnull(cd->tocent[i_track].isrc);
|
||||
cdtext_delete(cd->tocent[i_track].cdtext);
|
||||
for (i_track=0; i_track < env->i_tracks; i_track++) {
|
||||
free_if_notnull(env->tocent[i_track].filename);
|
||||
free_if_notnull(env->tocent[i_track].isrc);
|
||||
cdtext_destroy(&(env->tocent[i_track].cdtext));
|
||||
}
|
||||
|
||||
free_if_notnull(cd->psz_mcn);
|
||||
free_if_notnull(cd->psz_cue_name);
|
||||
cdtext_delete(cd->cdtext);
|
||||
cdio_generic_stdio_free(cd);
|
||||
free(cd);
|
||||
free_if_notnull(env->psz_mcn);
|
||||
free_if_notnull(env->psz_cue_name);
|
||||
cdtext_destroy(&(env->cdtext));
|
||||
cdio_generic_stdio_free(env);
|
||||
free(env);
|
||||
}
|
||||
|
||||
#ifdef NEED_MEDIA_EJECT_IMAGE
|
||||
/*!
|
||||
Eject media -- there's nothing to do here except free resources.
|
||||
We always return 2.
|
||||
@@ -68,6 +69,7 @@ _eject_media_image(void *user_data)
|
||||
_free_image (user_data);
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Return the value associated with the key "arg".
|
||||
@@ -87,6 +89,18 @@ _get_arg_image (void *user_data, const char key[])
|
||||
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
|
||||
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;
|
||||
|
||||
if (NULL == env->psz_mcn) return NULL;
|
||||
if (NULL == env || NULL == env->psz_mcn) return NULL;
|
||||
return strdup(env->psz_mcn);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
TITLE "Join us now we have the software"
|
||||
PERFORMER "Richard Stallman"
|
||||
FILE "BOING.BIN" BINARY
|
||||
TRACK 01 AUDIO
|
||||
INDEX 01 00:00:00
|
||||
|
||||
Reference in New Issue
Block a user