|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
Copyright (C) 2004-2008, 2011-2012, 2014, 2017
|
|
Packit |
dd8086 |
Rocky Bernstein <rocky@gnu.org>
|
|
Packit |
dd8086 |
toc reading routine adapted from cuetools
|
|
Packit |
dd8086 |
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
dd8086 |
it under the terms of the GNU General Public License as published by
|
|
Packit |
dd8086 |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
dd8086 |
(at your option) any later version.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
dd8086 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
dd8086 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
dd8086 |
GNU General Public License for more details.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
You should have received a copy of the GNU General Public License
|
|
Packit |
dd8086 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* This code implements low-level access functions for a CD images
|
|
Packit |
dd8086 |
residing inside a disk file (*.bin) and its associated cue sheet.
|
|
Packit |
dd8086 |
(*.cue).
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
#include "portable.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_LIMITS_H
|
|
Packit |
dd8086 |
#include <limits.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STDIO_H
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STDLIB_H
|
|
Packit |
dd8086 |
#include <stdlib.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STRING_H
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STRINGS_H
|
|
Packit |
dd8086 |
#include <strings.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_GLOB_H
|
|
Packit |
dd8086 |
#include <glob.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_ERRNO_H
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_INTTYPES_H
|
|
Packit |
dd8086 |
#include <inttypes.h>
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
#define PRId64 "lld"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <ctype.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <cdio/logging.h>
|
|
Packit |
dd8086 |
#include <cdio/sector.h>
|
|
Packit |
dd8086 |
#include <cdio/util.h>
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#include <cdio/utf8.h>
|
|
Packit |
dd8086 |
#include <cdio/version.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include "image.h"
|
|
Packit |
dd8086 |
#include "cdio_assert.h"
|
|
Packit |
dd8086 |
#include "_cdio_stdio.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* reader */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define DEFAULT_CDIO_DEVICE "videocd.bin"
|
|
Packit |
dd8086 |
#define DEFAULT_CDIO_CDRDAO "videocd.toc"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef _WIN32
|
|
Packit |
dd8086 |
#define CDIO_FOPEN fopen_utf8
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
#define CDIO_FOPEN fopen
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include "image_common.h"
|
|
Packit |
dd8086 |
#include "cdtext_private.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static lsn_t get_disc_last_lsn_cdrdao (void *p_user_data);
|
|
Packit |
dd8086 |
static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
check_track_is_blocksize_multiple(const char *psz_fname,
|
|
Packit |
dd8086 |
track_t i_track, off_t i_size,
|
|
Packit |
dd8086 |
uint16_t i_blocksize)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (i_size % i_blocksize) {
|
|
Packit |
dd8086 |
cdio_info ("image %s track %d size (%" PRId64 ") not a multiple"
|
|
Packit |
dd8086 |
" of the blocksize (%ld)",
|
|
Packit |
dd8086 |
psz_fname ? psz_fname : "unknown??", i_track, (int64_t)i_size,
|
|
Packit |
dd8086 |
(long int) i_blocksize);
|
|
Packit |
dd8086 |
if (i_size % M2RAW_SECTOR_SIZE == 0)
|
|
Packit |
dd8086 |
cdio_info ("this may be a 2336-type disc image");
|
|
Packit |
dd8086 |
else if (i_size % CDIO_CD_FRAMESIZE_RAW == 0)
|
|
Packit |
dd8086 |
cdio_info ("this may be a 2352-type disc image");
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Initialize image structures.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
_init_cdrdao (_img_private_t *env)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
lsn_t lead_lsn;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (env->gen.init)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Have to set init before calling get_disc_last_lsn_cdrdao() or we will
|
|
Packit |
dd8086 |
get into infinite recursion calling passing right here.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
env->gen.init = true;
|
|
Packit |
dd8086 |
env->gen.i_first_track = 1;
|
|
Packit |
dd8086 |
env->psz_mcn = NULL;
|
|
Packit |
dd8086 |
env->disc_mode = CDIO_DISC_MODE_NO_INFO;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Read in TOC sheet. */
|
|
Packit |
dd8086 |
if ( !parse_tocfile(env, env->psz_cue_name) ) return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
lead_lsn = get_disc_last_lsn_cdrdao( (_img_private_t *) env);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (-1 == lead_lsn)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Fake out leadout track and sector count for last track*/
|
|
Packit |
dd8086 |
cdio_lsn_to_msf (lead_lsn, &env->tocent[env->gen.i_tracks].start_msf);
|
|
Packit |
dd8086 |
env->tocent[env->gen.i_tracks].start_lba = cdio_lsn_to_lba(lead_lsn);
|
|
Packit |
dd8086 |
env->tocent[env->gen.i_tracks-env->gen.i_first_track].sec_count =
|
|
Packit |
dd8086 |
cdio_lsn_to_lba(lead_lsn - env->tocent[env->gen.i_tracks-1].start_lba);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads into buf the next size bytes.
|
|
Packit |
dd8086 |
Returns -1 on error.
|
|
Packit |
dd8086 |
Would be libc's seek() but we have to adjust for the extra track header
|
|
Packit |
dd8086 |
information in each sector.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static off_t
|
|
Packit |
dd8086 |
_lseek_cdrdao (void *user_data, off_t offset, int whence)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* real_offset is the real byte offset inside the disk image
|
|
Packit |
dd8086 |
The number below was determined empirically. I'm guessing
|
|
Packit |
dd8086 |
the 1st 24 bytes of a bin file are used for something.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
off_t real_offset=0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
env->pos.lba = 0;
|
|
Packit |
dd8086 |
for (i=0; i<env->gen.i_tracks; i++) {
|
|
Packit |
dd8086 |
track_info_t *this_track=&(env->tocent[i]);
|
|
Packit |
dd8086 |
env->pos.index = i;
|
|
Packit |
dd8086 |
if ( (this_track->sec_count*this_track->datasize) >= offset) {
|
|
Packit |
dd8086 |
int blocks = (int) (offset / this_track->datasize);
|
|
Packit |
dd8086 |
int rem = (int) (offset % this_track->datasize);
|
|
Packit |
dd8086 |
off_t block_offset = blocks * this_track->blocksize;
|
|
Packit |
dd8086 |
real_offset += block_offset + rem;
|
|
Packit |
dd8086 |
env->pos.buff_offset = rem;
|
|
Packit |
dd8086 |
env->pos.lba += (lba_t)blocks;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
real_offset += this_track->sec_count*this_track->blocksize;
|
|
Packit |
dd8086 |
offset -= this_track->sec_count*this_track->datasize;
|
|
Packit |
dd8086 |
env->pos.lba += this_track->sec_count;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i==env->gen.i_tracks) {
|
|
Packit |
dd8086 |
cdio_warn ("seeking outside range of disk image");
|
|
Packit |
dd8086 |
return -1;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
real_offset += env->tocent[i].datastart;
|
|
Packit |
dd8086 |
return cdio_stream_seek(env->tocent[i].data_source, real_offset, whence);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads into buf the next size bytes.
|
|
Packit |
dd8086 |
Returns -1 on error.
|
|
Packit |
dd8086 |
FIXME:
|
|
Packit |
dd8086 |
At present we assume a read doesn't cross sector or track
|
|
Packit |
dd8086 |
boundaries.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static ssize_t
|
|
Packit |
dd8086 |
_read_cdrdao (void *user_data, void *data, size_t size)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
|
|
Packit |
dd8086 |
char *p = data;
|
|
Packit |
dd8086 |
ssize_t final_size=0;
|
|
Packit |
dd8086 |
ssize_t this_size;
|
|
Packit |
dd8086 |
track_info_t *this_track=&(env->tocent[env->pos.index]);
|
|
Packit |
dd8086 |
ssize_t skip_size = this_track->datastart + this_track->endsize;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
while (size > 0) {
|
|
Packit |
dd8086 |
int rem = (int) (this_track->datasize - env->pos.buff_offset);
|
|
Packit |
dd8086 |
if (size <= rem) {
|
|
Packit |
dd8086 |
this_size = cdio_stream_read(this_track->data_source, buf, size, 1);
|
|
Packit |
dd8086 |
final_size += this_size;
|
|
Packit |
dd8086 |
memcpy (p, buf, this_size);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Finish off reading this sector. */
|
|
Packit |
dd8086 |
cdio_warn ("Reading across block boundaries not finished");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
size -= rem;
|
|
Packit |
dd8086 |
this_size = cdio_stream_read(this_track->data_source, buf, rem, 1);
|
|
Packit |
dd8086 |
final_size += this_size;
|
|
Packit |
dd8086 |
memcpy (p, buf, this_size);
|
|
Packit |
dd8086 |
p += this_size;
|
|
Packit |
dd8086 |
cdio_stream_read(this_track->data_source, buf, rem, 1);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Skip over stuff at end of this sector and the beginning of the next.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
cdio_stream_read(this_track->data_source, buf, skip_size, 1);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Get ready to read another sector. */
|
|
Packit |
dd8086 |
env->pos.buff_offset=0;
|
|
Packit |
dd8086 |
env->pos.lba++;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Have gone into next track. */
|
|
Packit |
dd8086 |
if (env->pos.lba >= env->tocent[env->pos.index+1].start_lba) {
|
|
Packit |
dd8086 |
env->pos.index++;
|
|
Packit |
dd8086 |
this_track=&(env->tocent[env->pos.index]);
|
|
Packit |
dd8086 |
skip_size = this_track->datastart + this_track->endsize;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return final_size;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return the size of the CD in logical block address (LBA) units.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
FIXME: this assumes there is only one source for data or
|
|
Packit |
dd8086 |
one track of silence.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static lsn_t
|
|
Packit |
dd8086 |
get_disc_last_lsn_cdrdao (void *p_user_data)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *p_env = p_user_data;
|
|
Packit |
dd8086 |
track_t i_leadout = p_env->gen.i_tracks;
|
|
Packit |
dd8086 |
uint16_t i_blocksize = p_env->tocent[i_leadout-1].blocksize;
|
|
Packit |
dd8086 |
off_t i_size;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_env->tocent[i_leadout-1].sec_count) {
|
|
Packit |
dd8086 |
i_size = p_env->tocent[i_leadout-1].sec_count;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
if (NULL == p_env->tocent[i_leadout-1].data_source) {
|
|
Packit |
dd8086 |
if (!p_env->tocent[i_leadout-1].silence) {
|
|
Packit |
dd8086 |
cdio_warn ("Data source for image %s is null",
|
|
Packit |
dd8086 |
p_env->gen.source_name);
|
|
Packit |
dd8086 |
return -1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
/* FIXME: this is only correct if there is one
|
|
Packit |
dd8086 |
track of silence. */
|
|
Packit |
dd8086 |
i_size = p_env->tocent[i_leadout-1].silence;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
/* FIXME: this is only correct if there is one data source. */
|
|
Packit |
dd8086 |
i_size = cdio_stream_stat(p_env->tocent[i_leadout-1].data_source)
|
|
Packit |
dd8086 |
- p_env->tocent[i_leadout-1].offset;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (i_size < 0) {
|
|
Packit |
dd8086 |
cdio_error ("Disc data size too small for track specification in image %s",
|
|
Packit |
dd8086 |
p_env->gen.source_name);
|
|
Packit |
dd8086 |
return (lsn_t)i_size;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (check_track_is_blocksize_multiple(p_env->tocent[i_leadout-1].filename,
|
|
Packit |
dd8086 |
i_leadout-1, i_size, i_blocksize)) {
|
|
Packit |
dd8086 |
i_size /= i_blocksize;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
/* Round up */
|
|
Packit |
dd8086 |
i_size = (i_size / i_blocksize) + 1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_size += p_env->tocent[i_leadout-1].start_lba;
|
|
Packit |
dd8086 |
i_size -= CDIO_PREGAP_SECTORS;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return (lsn_t)i_size;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define MAXLINE 512
|
|
Packit |
dd8086 |
#define UNIMPLIMENTED_MSG \
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: unimplimented keyword: %s", \
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_keyword)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
parse_tocfile (_img_private_t *cd, const char *psz_cue_name)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
/* The below declarations may be common in other image-parse routines. */
|
|
Packit |
dd8086 |
FILE *fp;
|
|
Packit |
dd8086 |
char psz_line[MAXLINE]; /* text of current line read in file fp. */
|
|
Packit |
dd8086 |
unsigned int i_line=0; /* line number in file of psz_line. */
|
|
Packit |
dd8086 |
int i = -1; /* Position in tocent. Same as
|
|
Packit |
dd8086 |
cd->gen.i_tracks - 1 */
|
|
Packit |
dd8086 |
char *psz_keyword, *psz_field, *psz_cue_name_dup;
|
|
Packit |
dd8086 |
cdio_log_level_t log_level = (cd) ? CDIO_LOG_WARN : CDIO_LOG_INFO ;
|
|
Packit |
dd8086 |
cdtext_field_t cdtext_key;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* The below declaration(s) may be unique to this image-parse routine. */
|
|
Packit |
dd8086 |
unsigned int i_cdtext_nest = 0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == psz_cue_name)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
psz_cue_name_dup = _cdio_strdup_fixpath(psz_cue_name);
|
|
Packit |
dd8086 |
if (NULL == psz_cue_name_dup)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fp = CDIO_FOPEN (psz_cue_name_dup, "r");
|
|
Packit |
dd8086 |
cdio_free(psz_cue_name_dup);
|
|
Packit |
dd8086 |
if (fp == NULL) {
|
|
Packit |
dd8086 |
cdio_log(log_level, "error opening %s for reading: %s",
|
|
Packit |
dd8086 |
psz_cue_name, strerror(errno));
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
cd->gen.b_cdtext_error = false;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
while (fgets(psz_line, MAXLINE, fp)) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_line++;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* strip comment from line */
|
|
Packit |
dd8086 |
/* todo: // in quoted strings? */
|
|
Packit |
dd8086 |
/* //comment */
|
|
Packit |
dd8086 |
if ((psz_field = strstr (psz_line, "//")))
|
|
Packit |
dd8086 |
*psz_field = '\0';
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ((psz_keyword = strtok (psz_line, " \t\n\r"))) {
|
|
Packit |
dd8086 |
/* CATALOG "ddddddddddddd" */
|
|
Packit |
dd8086 |
if (0 == strcmp ("CATALOG", psz_keyword)) {
|
|
Packit |
dd8086 |
if (-1 == i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
|
Packit |
dd8086 |
if (13 != strlen(psz_field)) {
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"%s line %d after word CATALOG:",
|
|
Packit |
dd8086 |
psz_cue_name, i_line);
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"Token %s has length %ld. Should be 13 digits.",
|
|
Packit |
dd8086 |
psz_field, (long int) strlen(psz_field));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
/* Check that we have all digits*/
|
|
Packit |
dd8086 |
unsigned int j;
|
|
Packit |
dd8086 |
for (j=0; j<13; j++) {
|
|
Packit |
dd8086 |
if (!isdigit((unsigned char) psz_field[j])) {
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"%s line %d after word CATALOG:",
|
|
Packit |
dd8086 |
psz_cue_name, i_line);
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"Character \"%c\" at postition %i of token \"%s\""
|
|
Packit |
dd8086 |
" is not all digits.",
|
|
Packit |
dd8086 |
psz_field[j], j+1, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != cd) cd->psz_mcn = strdup (psz_field);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"%s line %d after word CATALOG:",
|
|
Packit |
dd8086 |
psz_cue_name, i_line);
|
|
Packit |
dd8086 |
cdio_log(log_level, "Expecting 13 digits; nothing seen.");
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* CD_DA | CD_ROM | CD_ROM_XA */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("CD_DA", psz_keyword)) {
|
|
Packit |
dd8086 |
if (-1 == i) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_DA;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("CD_ROM", psz_keyword)) {
|
|
Packit |
dd8086 |
if (-1 == i) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_DATA;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("CD_ROM_XA", psz_keyword)) {
|
|
Packit |
dd8086 |
if (-1 == i) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* TRACK <track-mode> [<sub-channel-mode>] */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("TRACK", psz_keyword)) {
|
|
Packit |
dd8086 |
i++;
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
if (0 == strcmp ("AUDIO", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_AUDIO;
|
|
Packit |
dd8086 |
cd->tocent[i].blocksize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = 0;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = 0;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_DA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE1", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_DATA;
|
|
Packit |
dd8086 |
cd->tocent[i].blocksize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_HEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = CDIO_CD_EDC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_M1F1_ZERO_SIZE + CDIO_CD_ECC_SIZE;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_DATA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE1_RAW", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_DATA;
|
|
Packit |
dd8086 |
cd->tocent[i].blocksize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_HEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = CDIO_CD_EDC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_M1F1_ZERO_SIZE + CDIO_CD_ECC_SIZE;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_DATA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE2", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_XA;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_HEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = M2RAW_SECTOR_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = 0;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE2_FORM1", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_XA;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_HEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = 0;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE2_FORM2", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_XA;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = CDIO_CD_SYNC_SIZE
|
|
Packit |
dd8086 |
+ CDIO_CD_ECC_SIZE;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE2_FORM_MIX", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_XA;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = M2RAW_SECTOR_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].blocksize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE +
|
|
Packit |
dd8086 |
CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].track_green = true;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = 0;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("MODE2_RAW", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].track_format = TRACK_FORMAT_XA;
|
|
Packit |
dd8086 |
cd->tocent[i].blocksize = CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
cd->tocent[i].datastart = CDIO_CD_SYNC_SIZE +
|
|
Packit |
dd8086 |
CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].datasize = CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
cd->tocent[i].track_green = true;
|
|
Packit |
dd8086 |
cd->tocent[i].endsize = 0;
|
|
Packit |
dd8086 |
switch(cd->disc_mode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_NO_INFO:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_XA;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_ERROR:
|
|
Packit |
dd8086 |
/* Disc type stays the same. */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
cd->disc_mode = CDIO_DISC_MODE_ERROR;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d after TRACK:",
|
|
Packit |
dd8086 |
psz_cue_name, i_line);
|
|
Packit |
dd8086 |
cdio_log(log_level, "'%s' not a valid mode.", psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
/* \todo: set sub-channel-mode */
|
|
Packit |
dd8086 |
#ifdef TODO
|
|
Packit |
dd8086 |
if (0 == strcmp ("RW", psz_field))
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
else if (0 == strcmp ("RW_RAW", psz_field))
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* track flags */
|
|
Packit |
dd8086 |
/* [NO] COPY | [NO] PRE_EMPHASIS */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("NO", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
if (0 == strcmp ("COPY", psz_field)) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_COPY_PERMITTED;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("PRE_EMPHASIS", psz_field))
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_PRE_EMPHASIS;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("COPY", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != cd && i >= 0)
|
|
Packit |
dd8086 |
cd->tocent[i].flags |= CDIO_TRACK_FLAG_COPY_PERMITTED;
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("PRE_EMPHASIS", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != cd && i >= 0)
|
|
Packit |
dd8086 |
cd->tocent[i].flags |= CDIO_TRACK_FLAG_PRE_EMPHASIS;
|
|
Packit |
dd8086 |
/* TWO_CHANNEL_AUDIO */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("TWO_CHANNEL_AUDIO", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != cd && i >= 0)
|
|
Packit |
dd8086 |
cd->tocent[i].flags &= ~CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO;
|
|
Packit |
dd8086 |
/* FOUR_CHANNEL_AUDIO */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("FOUR_CHANNEL_AUDIO", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != cd && i >= 0)
|
|
Packit |
dd8086 |
cd->tocent[i].flags |= CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ISRC "CCOOOYYSSSSS" */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("ISRC", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->tocent[i].isrc = strdup(psz_field);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* SILENCE <length> */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("SILENCE", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->tocent[i].silence = cdio_mmssff_to_lba (psz_field);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: SILENCE not fully implimented",
|
|
Packit |
dd8086 |
psz_cue_name, i_line);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ZERO <length> */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("ZERO", psz_keyword)) {
|
|
Packit |
dd8086 |
UNIMPLIMENTED_MSG;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* [FILE|AUDIOFILE] "<filename>" <start-msf> [<length-msf>] */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("FILE", psz_keyword)
|
|
Packit |
dd8086 |
|| 0 == strcmp ("AUDIOFILE", psz_keyword)) {
|
|
Packit |
dd8086 |
if (0 <= i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
|
Packit |
dd8086 |
/* Handle "<filename>" */
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
char *psz_dirname = cdio_dirname(psz_cue_name);
|
|
Packit |
dd8086 |
char *psz_filename = cdio_abspath(psz_dirname, psz_field);
|
|
Packit |
dd8086 |
cd->tocent[i].filename = strdup (psz_filename);
|
|
Packit |
dd8086 |
free(psz_filename);
|
|
Packit |
dd8086 |
free(psz_dirname);
|
|
Packit |
dd8086 |
/* To do: do something about reusing existing files. */
|
|
Packit |
dd8086 |
if (!(cd->tocent[i].data_source = cdio_stdio_new (psz_field))) {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: can't open file `%s' for reading",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
CdioDataSource_t *s = cdio_stdio_new (psz_field);
|
|
Packit |
dd8086 |
if (!s) {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: can't open file `%s' for reading",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
cdio_stdio_destroy (s);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cdio_stdio_destroy (s);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
/* Handle <start-msf> */
|
|
Packit |
dd8086 |
lba_t i_start_lba =
|
|
Packit |
dd8086 |
cdio_lsn_to_lba(cdio_mmssff_to_lba (psz_field));
|
|
Packit |
dd8086 |
if (CDIO_INVALID_LBA == i_start_lba) {
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: invalid MSF string %s",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].start_lba = i_start_lba;
|
|
Packit |
dd8086 |
cdio_lba_to_msf(i_start_lba, &(cd->tocent[i].start_msf));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
/* Handle <length-msf> */
|
|
Packit |
dd8086 |
lba_t lba = cdio_mmssff_to_lba (psz_field);
|
|
Packit |
dd8086 |
if (CDIO_INVALID_LBA == lba) {
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: invalid MSF string %s",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
off_t i_size = cdio_stream_stat(cd->tocent[i].data_source);
|
|
Packit |
dd8086 |
if (lba) {
|
|
Packit |
dd8086 |
if ( (lba * cd->tocent[i].datasize) > i_size) {
|
|
Packit |
dd8086 |
cdio_log(log_level,
|
|
Packit |
dd8086 |
"%s line %d: MSF length %s exceeds end of file",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
lba = (lba_t) (i_size / cd->tocent[i].blocksize);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cd->tocent[i].sec_count = lba;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* DATAFILE "<filename>" #byte-offset <start-msf> */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("DATAFILE", psz_keyword)) {
|
|
Packit |
dd8086 |
if (0 <= i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {
|
|
Packit |
dd8086 |
/* Handle <filename> */
|
|
Packit |
dd8086 |
char *psz_dirname = cdio_dirname(psz_cue_name);
|
|
Packit |
dd8086 |
char *psz_filename = cdio_abspath(psz_dirname, psz_field);
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].filename = strdup(psz_filename);
|
|
Packit |
dd8086 |
/* To do: do something about reusing existing files. */
|
|
Packit |
dd8086 |
if (!(cd->tocent[i].data_source = cdio_stdio_new (psz_field))) {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: can't open file `%s' for reading",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
free(psz_filename);
|
|
Packit |
dd8086 |
free(psz_dirname);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
CdioDataSource_t *s = cdio_stdio_new (psz_filename);
|
|
Packit |
dd8086 |
if (!s) {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: can't open file `%s' for reading",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
free(psz_filename);
|
|
Packit |
dd8086 |
free(psz_dirname);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cdio_stdio_destroy (s);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
free(psz_filename);
|
|
Packit |
dd8086 |
free(psz_dirname);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
psz_field = strtok (NULL, " \t\n\r");
|
|
Packit |
dd8086 |
if (psz_field) {
|
|
Packit |
dd8086 |
/* Handle optional #byte-offset */
|
|
Packit |
dd8086 |
if ( psz_field[0] == '#') {
|
|
Packit |
dd8086 |
long int offset;
|
|
Packit |
dd8086 |
psz_field++;
|
|
Packit |
dd8086 |
errno = 0;
|
|
Packit |
dd8086 |
offset = strtol(psz_field, (char **)NULL, 10);
|
|
Packit |
dd8086 |
if ( (LONG_MIN == offset || LONG_MAX == offset)
|
|
Packit |
dd8086 |
&& 0 != errno ) {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: can't convert `%s' to byte offset",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].offset = offset;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
psz_field = strtok (NULL, " \t\n\r");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (psz_field) {
|
|
Packit |
dd8086 |
/* Handle start-msf */
|
|
Packit |
dd8086 |
lba_t lba = cdio_mmssff_to_lba (psz_field);
|
|
Packit |
dd8086 |
if (CDIO_INVALID_LBA == lba) {
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: invalid MSF string %s",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_field);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].start_lba = lba;
|
|
Packit |
dd8086 |
cdio_lba_to_msf(cd->tocent[i].start_lba,
|
|
Packit |
dd8086 |
&(cd->tocent[i].start_msf));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
/* No start-msf. */
|
|
Packit |
dd8086 |
if (cd) {
|
|
Packit |
dd8086 |
if (i) {
|
|
Packit |
dd8086 |
uint16_t i_blocksize = cd->tocent[i-1].blocksize;
|
|
Packit |
dd8086 |
off_t i_size =
|
|
Packit |
dd8086 |
cdio_stream_stat(cd->tocent[i-1].data_source);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
check_track_is_blocksize_multiple(cd->tocent[i-1].filename,
|
|
Packit |
dd8086 |
i-1, i_size, i_blocksize);
|
|
Packit |
dd8086 |
/* Append size of previous datafile. */
|
|
Packit |
dd8086 |
cd->tocent[i].start_lba = (lba_t) (cd->tocent[i-1].start_lba +
|
|
Packit |
dd8086 |
(i_size / i_blocksize));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cd->tocent[i].offset = 0;
|
|
Packit |
dd8086 |
cd->tocent[i].start_lba += CDIO_PREGAP_SECTORS;
|
|
Packit |
dd8086 |
cdio_lba_to_msf(cd->tocent[i].start_lba,
|
|
Packit |
dd8086 |
&(cd->tocent[i].start_msf));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* FIFO "<fifo path>" [<length>] */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("FIFO", psz_keyword)) {
|
|
Packit |
dd8086 |
goto unimplimented_error;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* START MM:SS:FF */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("START", psz_keyword)) {
|
|
Packit |
dd8086 |
if (0 <= i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
/* todo: line is too long! */
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->tocent[i].pregap = cd->tocent[i].start_lba;
|
|
Packit |
dd8086 |
cd->tocent[i].start_lba += cdio_mmssff_to_lba (psz_field);
|
|
Packit |
dd8086 |
cdio_lba_to_msf(cd->tocent[i].start_lba,
|
|
Packit |
dd8086 |
&(cd->tocent[i].start_msf));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* PREGAP MM:SS:FF */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("PREGAP", psz_keyword)) {
|
|
Packit |
dd8086 |
if (0 <= i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
if (NULL != cd)
|
|
Packit |
dd8086 |
cd->tocent[i].pregap = cdio_mmssff_to_lba (psz_field);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* INDEX MM:SS:FF */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("INDEX", psz_keyword)) {
|
|
Packit |
dd8086 |
if (0 <= i) {
|
|
Packit |
dd8086 |
if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
#if 0
|
|
Packit |
dd8086 |
if (1 == cd->tocent[i].nindex) {
|
|
Packit |
dd8086 |
cd->tocent[i].indexes[1] = cd->tocent[i].indexes[0];
|
|
Packit |
dd8086 |
cd->tocent[i].nindex++;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cd->tocent[i].indexes[cd->tocent[i].nindex++] =
|
|
Packit |
dd8086 |
cdio_mmssff_to_lba (psz_field) + cd->tocent[i].indexes[0];
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != strtok (NULL, " \t\n\r")) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
goto not_in_global_section;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* CD_TEXT { ... } */
|
|
Packit |
dd8086 |
/* todo: opening { must be on same line as CD_TEXT */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("CD_TEXT", psz_keyword)) {
|
|
Packit |
dd8086 |
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if ( 0 == strcmp( "{", psz_field ) ) {
|
|
Packit |
dd8086 |
i_cdtext_nest++;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
cdio_log (log_level,
|
|
Packit |
dd8086 |
"%s line %d: expecting '{'", psz_cue_name, i_line);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
// TODO: implement language mapping
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("LANGUAGE_MAP", psz_keyword)) {
|
|
Packit |
dd8086 |
/* LANGUAGE d { ... } */
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("LANGUAGE", psz_keyword)) {
|
|
Packit |
dd8086 |
/* Language number */
|
|
Packit |
dd8086 |
if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {
|
|
Packit |
dd8086 |
goto format_error;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if ( 0 == strcmp( "{", psz_field ) ) {
|
|
Packit |
dd8086 |
i_cdtext_nest++;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("{", psz_keyword)) {
|
|
Packit |
dd8086 |
i_cdtext_nest++;
|
|
Packit |
dd8086 |
} else if (0 == strcmp ("}", psz_keyword)) {
|
|
Packit |
dd8086 |
if (i_cdtext_nest > 0) i_cdtext_nest--;
|
|
Packit |
dd8086 |
} else if ( CDTEXT_FIELD_INVALID !=
|
|
Packit |
dd8086 |
(cdtext_key = cdtext_is_field (psz_keyword)) ) {
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
if (NULL == cd->gen.cdtext) {
|
|
Packit |
dd8086 |
cd->gen.cdtext = cdtext_init ();
|
|
Packit |
dd8086 |
/* until language mapping is implemented ...*/
|
|
Packit |
dd8086 |
cd->gen.cdtext->block[cd->gen.cdtext->block_i].language_code = CDTEXT_LANGUAGE_ENGLISH;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cdtext_set (cd->gen.cdtext, cdtext_key, (uint8_t*) strtok (NULL, "\"\t\n\r"),
|
|
Packit |
dd8086 |
(-1 == i ? 0 : cd->gen.i_first_track + i),
|
|
Packit |
dd8086 |
"ISO-8859-1");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* unrecognized line */
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: warning: unrecognized word: %s",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_keyword);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != cd) {
|
|
Packit |
dd8086 |
cd->gen.i_tracks = i+1;
|
|
Packit |
dd8086 |
cd->gen.toc_init = true;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fclose (fp);
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
unimplimented_error:
|
|
Packit |
dd8086 |
UNIMPLIMENTED_MSG;
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
format_error:
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d after word %s",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_keyword);
|
|
Packit |
dd8086 |
goto err_exit;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
not_in_global_section:
|
|
Packit |
dd8086 |
cdio_log(log_level, "%s line %d: word %s only allowed in global section",
|
|
Packit |
dd8086 |
psz_cue_name, i_line, psz_keyword);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
err_exit:
|
|
Packit |
dd8086 |
fclose (fp);
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads a single audio sector from CD device into data starting
|
|
Packit |
dd8086 |
from lsn. Returns 0 if no error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static driver_return_code_t
|
|
Packit |
dd8086 |
_read_audio_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
|
|
Packit |
dd8086 |
unsigned int nblocks)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
int ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_stream_seek (env->tocent[0].data_source,
|
|
Packit |
dd8086 |
lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET);
|
|
Packit |
dd8086 |
if (ret!=0) return ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_stream_read (env->tocent[0].data_source, data,
|
|
Packit |
dd8086 |
CDIO_CD_FRAMESIZE_RAW, nblocks);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ret is number of bytes if okay, but we need to return 0 okay. */
|
|
Packit |
dd8086 |
return ret == 0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads a single mode2 sector from cd device into data starting
|
|
Packit |
dd8086 |
from lsn. Returns 0 if no error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static driver_return_code_t
|
|
Packit |
dd8086 |
_read_mode1_sector_cdrdao (void *user_data, void *data, lsn_t lsn,
|
|
Packit |
dd8086 |
bool b_form2)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
int ret;
|
|
Packit |
dd8086 |
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_stream_seek (env->tocent[0].data_source,
|
|
Packit |
dd8086 |
lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET);
|
|
Packit |
dd8086 |
if (ret!=0) return ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* FIXME: Not completely sure the below is correct. */
|
|
Packit |
dd8086 |
ret = cdio_stream_read (env->tocent[0].data_source, buf,
|
|
Packit |
dd8086 |
CDIO_CD_FRAMESIZE_RAW, 1);
|
|
Packit |
dd8086 |
if (ret==0) return ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
|
|
Packit |
dd8086 |
b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return DRIVER_OP_SUCCESS;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads nblocks of mode1 sectors from cd device into data starting
|
|
Packit |
dd8086 |
from lsn.
|
|
Packit |
dd8086 |
Returns 0 if no error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static int
|
|
Packit |
dd8086 |
_read_mode1_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
|
|
Packit |
dd8086 |
bool b_form2, unsigned int nblocks)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
int i;
|
|
Packit |
dd8086 |
int retval;
|
|
Packit |
dd8086 |
unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (i = 0; i < nblocks; i++) {
|
|
Packit |
dd8086 |
if ( (retval = _read_mode1_sector_cdrdao (env,
|
|
Packit |
dd8086 |
((char *)data) + (blocksize * i),
|
|
Packit |
dd8086 |
lsn + i, b_form2)) )
|
|
Packit |
dd8086 |
return retval;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return DRIVER_OP_SUCCESS;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads a single mode1 sector from cd device into data starting
|
|
Packit |
dd8086 |
from lsn. Returns 0 if no error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static driver_return_code_t
|
|
Packit |
dd8086 |
_read_mode2_sector_cdrdao (void *user_data, void *data, lsn_t lsn,
|
|
Packit |
dd8086 |
bool b_form2)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
int ret;
|
|
Packit |
dd8086 |
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
|
|
Packit |
dd8086 |
long unsigned int i_off = lsn * CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* For sms's VCD's (mwc1.toc) it is more like this:
|
|
Packit |
dd8086 |
if (i_off > 272) i_off -= 272;
|
|
Packit |
dd8086 |
There is that magic 272 that we find in read_audio_sectors_cdrdao again.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* NOTE: The logic below seems a bit wrong and convoluted
|
|
Packit |
dd8086 |
to me, but passes the regression tests. (Perhaps it is why we get
|
|
Packit |
dd8086 |
valgrind errors in vcdxrip). Leave it the way it was for now.
|
|
Packit |
dd8086 |
Review this sector 2336 stuff later.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_stream_seek (env->tocent[0].data_source, i_off, SEEK_SET);
|
|
Packit |
dd8086 |
if (ret!=0) return ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_stream_read (env->tocent[0].data_source, buf,
|
|
Packit |
dd8086 |
CDIO_CD_FRAMESIZE_RAW, 1);
|
|
Packit |
dd8086 |
if (ret==0) return ret;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* See NOTE above. */
|
|
Packit |
dd8086 |
if (b_form2)
|
|
Packit |
dd8086 |
memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE,
|
|
Packit |
dd8086 |
M2RAW_SECTOR_SIZE);
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
memcpy (data, buf + CDIO_CD_XA_SYNC_HEADER, CDIO_CD_FRAMESIZE);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return DRIVER_OP_SUCCESS;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Reads nblocks of mode2 sectors from cd device into data starting
|
|
Packit |
dd8086 |
from lsn.
|
|
Packit |
dd8086 |
Returns 0 if no error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static driver_return_code_t
|
|
Packit |
dd8086 |
_read_mode2_sectors_cdrdao (void *user_data, void *data, lsn_t lsn,
|
|
Packit |
dd8086 |
bool b_form2, unsigned int nblocks)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
int i;
|
|
Packit |
dd8086 |
int retval;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (i = 0; i < nblocks; i++) {
|
|
Packit |
dd8086 |
if ( (retval = _read_mode2_sector_cdrdao (env,
|
|
Packit |
dd8086 |
((char *)data) + (CDIO_CD_FRAMESIZE * i),
|
|
Packit |
dd8086 |
lsn + i, b_form2)) )
|
|
Packit |
dd8086 |
return retval;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return 0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return an array of strings giving possible TOC disk images.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
char **
|
|
Packit |
dd8086 |
cdio_get_devices_cdrdao (void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char **drives = NULL;
|
|
Packit |
dd8086 |
unsigned int num_files=0;
|
|
Packit |
dd8086 |
#ifdef HAVE_GLOB_H
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
glob_t globbuf;
|
|
Packit |
dd8086 |
globbuf.gl_offs = 0;
|
|
Packit |
dd8086 |
glob("*.toc", GLOB_DOOFFS, NULL, &globbuf);
|
|
Packit |
dd8086 |
for (i=0; i
|
|
Packit |
dd8086 |
cdio_add_device_list(&drives, globbuf.gl_pathv[i], &num_files);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
globfree(&globbuf);
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
cdio_add_device_list(&drives, DEFAULT_CDIO_DEVICE, &num_files);
|
|
Packit |
dd8086 |
#endif /*HAVE_GLOB_H*/
|
|
Packit |
dd8086 |
cdio_add_device_list(&drives, NULL, &num_files);
|
|
Packit |
dd8086 |
return drives;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return a string containing the default CD device.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
char *
|
|
Packit |
dd8086 |
cdio_get_default_device_cdrdao(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char **drives = cdio_get_devices_nrg();
|
|
Packit |
dd8086 |
char *drive = (drives[0] == NULL) ? NULL : strdup(drives[0]);
|
|
Packit |
dd8086 |
cdio_free_device_list(drives);
|
|
Packit |
dd8086 |
return drive;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
get_hwinfo_cdrdao ( const CdIo_t *p_cdio, /*out*/ cdio_hwinfo_t *hw_info)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
strncpy(hw_info->psz_vendor, "libcdio",
|
|
Packit |
dd8086 |
sizeof(hw_info->psz_vendor)-1);
|
|
Packit |
dd8086 |
hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
|
|
Packit |
dd8086 |
strncpy(hw_info->psz_model, "cdrdao",
|
|
Packit |
dd8086 |
sizeof(hw_info->psz_model)-1);
|
|
Packit |
dd8086 |
hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
|
|
Packit |
dd8086 |
strncpy(hw_info->psz_revision, CDIO_VERSION,
|
|
Packit |
dd8086 |
sizeof(hw_info->psz_revision)-1);
|
|
Packit |
dd8086 |
hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return the number of tracks in the current medium.
|
|
Packit |
dd8086 |
CDIO_INVALID_TRACK is returned on error.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static track_format_t
|
|
Packit |
dd8086 |
_get_track_format_cdrdao(void *p_user_data, track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *p_env = p_user_data;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!p_env->gen.init) return TRACK_FORMAT_ERROR;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_track > p_env->gen.i_tracks || i_track == 0)
|
|
Packit |
dd8086 |
return TRACK_FORMAT_ERROR;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return p_env->tocent[i_track-p_env->gen.i_first_track].track_format;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return true if we have XA data (green, mode2 form1) or
|
|
Packit |
dd8086 |
XA data (green, mode2 form2). That is track begins:
|
|
Packit |
dd8086 |
sync - header - subheader
|
|
Packit |
dd8086 |
12 4 - 8
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
FIXME: there's gotta be a better design for this and get_track_format?
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
_get_track_green_cdrdao(void *user_data, track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *env = user_data;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!env->gen.init) _init_cdrdao(env);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_track > env->gen.i_tracks || i_track == 0)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return env->tocent[i_track-env->gen.i_first_track].track_green;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Return the starting LSN track number
|
|
Packit |
dd8086 |
i_track in obj. Track numbers start at 1.
|
|
Packit |
dd8086 |
The "leadout" track is specified either by
|
|
Packit |
dd8086 |
using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
|
|
Packit |
dd8086 |
False is returned if there is no track entry.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static lba_t
|
|
Packit |
dd8086 |
_get_lba_track_cdrdao(void *p_user_data, track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
_img_private_t *p_env = p_user_data;
|
|
Packit |
dd8086 |
_init_cdrdao (p_env);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_track == CDIO_CDROM_LEADOUT_TRACK)
|
|
Packit |
dd8086 |
i_track = p_env->gen.i_tracks+1;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_track <= p_env->gen.i_tracks+1 && i_track != 0) {
|
|
Packit |
dd8086 |
return p_env->tocent[i_track-1].start_lba;
|
|
Packit |
dd8086 |
} else
|
|
Packit |
dd8086 |
return CDIO_INVALID_LBA;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Check that a TOC file is valid. We parse the entire file.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
bool
|
|
Packit |
dd8086 |
cdio_is_tocfile(const char *psz_cue_name)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (psz_cue_name == NULL) return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i=strlen(psz_cue_name)-strlen("toc");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i>0) {
|
|
Packit |
dd8086 |
if ( (psz_cue_name[i]=='t' && psz_cue_name[i+1]=='o' && psz_cue_name[i+2]=='c')
|
|
Packit |
dd8086 |
|| (psz_cue_name[i]=='T' && psz_cue_name[i+1]=='O' && psz_cue_name[i+2]=='C') ) {
|
|
Packit |
dd8086 |
return parse_tocfile(NULL, psz_cue_name);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Initialization routine. This is the only thing that doesn't
|
|
Packit |
dd8086 |
get called via a function pointer. In fact *we* are the
|
|
Packit |
dd8086 |
ones to set that up.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
CdIo_t *
|
|
Packit |
dd8086 |
cdio_open_am_cdrdao (const char *psz_source_name, const char *psz_access_mode)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (psz_access_mode != NULL && strcmp(psz_access_mode, "image"))
|
|
Packit |
dd8086 |
cdio_warn ("there is only one access mode, 'image' for cdrdao. Arg %s ignored",
|
|
Packit |
dd8086 |
psz_access_mode);
|
|
Packit |
dd8086 |
return cdio_open_cdrdao(psz_source_name);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*!
|
|
Packit |
dd8086 |
Initialization routine. This is the only thing that doesn't
|
|
Packit |
dd8086 |
get called via a function pointer. In fact *we* are the
|
|
Packit |
dd8086 |
ones to set that up.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
CdIo_t *
|
|
Packit |
dd8086 |
cdio_open_cdrdao (const char *psz_cue_name)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
CdIo_t *ret;
|
|
Packit |
dd8086 |
_img_private_t *p_data;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_funcs_t _funcs;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset( &_funcs, 0, sizeof(_funcs) );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_funcs.eject_media = _eject_media_image;
|
|
Packit |
dd8086 |
_funcs.free = _free_image;
|
|
Packit |
dd8086 |
_funcs.get_arg = _get_arg_image;
|
|
Packit |
dd8086 |
_funcs.get_cdtext = _get_cdtext_image;
|
|
Packit |
dd8086 |
_funcs.get_cdtext_raw = NULL;
|
|
Packit |
dd8086 |
_funcs.get_devices = cdio_get_devices_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_default_device = cdio_get_default_device_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_disc_last_lsn = get_disc_last_lsn_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_discmode = _get_discmode_image;
|
|
Packit |
dd8086 |
_funcs.get_drive_cap = _get_drive_cap_image;
|
|
Packit |
dd8086 |
_funcs.get_first_track_num = _get_first_track_num_image;
|
|
Packit |
dd8086 |
_funcs.get_hwinfo = get_hwinfo_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_media_changed = get_media_changed_image;
|
|
Packit |
dd8086 |
_funcs.get_mcn = _get_mcn_image;
|
|
Packit |
dd8086 |
_funcs.get_num_tracks = _get_num_tracks_image;
|
|
Packit |
dd8086 |
_funcs.get_track_channels = get_track_channels_image;
|
|
Packit |
dd8086 |
_funcs.get_track_copy_permit = get_track_copy_permit_image;
|
|
Packit |
dd8086 |
_funcs.get_track_format = _get_track_format_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_track_green = _get_track_green_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_track_lba = _get_lba_track_cdrdao;
|
|
Packit |
dd8086 |
_funcs.get_track_msf = _get_track_msf_image;
|
|
Packit |
dd8086 |
_funcs.get_track_preemphasis = get_track_preemphasis_image;
|
|
Packit |
dd8086 |
_funcs.get_track_pregap_lba = get_track_pregap_lba_image;
|
|
Packit |
dd8086 |
_funcs.get_track_isrc = get_track_isrc_image;
|
|
Packit |
dd8086 |
_funcs.lseek = _lseek_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read = _read_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read_audio_sectors = _read_audio_sectors_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read_data_sectors = read_data_sectors_image;
|
|
Packit |
dd8086 |
_funcs.read_mode1_sector = _read_mode1_sector_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read_mode1_sectors = _read_mode1_sectors_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read_mode2_sector = _read_mode2_sector_cdrdao;
|
|
Packit |
dd8086 |
_funcs.read_mode2_sectors = _read_mode2_sectors_cdrdao;
|
|
Packit |
dd8086 |
_funcs.run_mmc_cmd = NULL;
|
|
Packit |
dd8086 |
_funcs.set_arg = _set_arg_image;
|
|
Packit |
dd8086 |
_funcs.set_speed = cdio_generic_unimplemented_set_speed;
|
|
Packit |
dd8086 |
_funcs.set_blocksize = cdio_generic_unimplemented_set_blocksize;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == psz_cue_name) return NULL;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_data = calloc(1, sizeof (_img_private_t));
|
|
Packit |
dd8086 |
p_data->gen.init = false;
|
|
Packit |
dd8086 |
p_data->psz_cue_name = NULL;
|
|
Packit |
dd8086 |
p_data->gen.data_source = NULL;
|
|
Packit |
dd8086 |
p_data->gen.source_name = NULL;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret = cdio_new ((void *)p_data, &_funcs);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (ret == NULL) {
|
|
Packit |
dd8086 |
free(p_data);
|
|
Packit |
dd8086 |
return NULL;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
ret->driver_id = DRIVER_CDRDAO;
|
|
Packit |
dd8086 |
if (!cdio_is_tocfile(psz_cue_name)) {
|
|
Packit |
dd8086 |
cdio_debug ("source name %s is not recognized as a TOC file",
|
|
Packit |
dd8086 |
psz_cue_name);
|
|
Packit |
dd8086 |
free(p_data);
|
|
Packit |
dd8086 |
free(ret);
|
|
Packit |
dd8086 |
return NULL;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_set_arg_image (p_data, "cue", psz_cue_name);
|
|
Packit |
dd8086 |
_set_arg_image (p_data, "source", psz_cue_name);
|
|
Packit |
dd8086 |
_set_arg_image (p_data, "access-mode", "cdrdao");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (_init_cdrdao(p_data)) {
|
|
Packit |
dd8086 |
return ret;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
_free_image(p_data);
|
|
Packit |
dd8086 |
free(ret);
|
|
Packit |
dd8086 |
return NULL;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
bool
|
|
Packit |
dd8086 |
cdio_have_cdrdao (void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
}
|