📄 cdrdao.c
字号:
cdio_log(log_level, "%s line %d: warning: unrecognized word: %s", psz_cue_name, i_line, psz_keyword); goto err_exit; } } } if (NULL != cd) { cd->gen.i_tracks = i+1; cd->gen.toc_init = true; } fclose (fp); return true; unimplimented_error: UNIMPLIMENTED_MSG; goto err_exit; format_error: 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: word %s only allowed in global section", psz_cue_name, i_line, psz_keyword); err_exit: fclose (fp); return false;}/*! Reads a single audio sector from CD device into data starting from lsn. Returns 0 if no error. */static int_read_audio_sectors_cdrdao (void *user_data, void *data, lsn_t lsn, unsigned int nblocks){ _img_private_t *env = user_data; int ret; /* Why the adjustment of 272, I don't know. It seems to work though */ if (lsn != 0) { ret = cdio_stream_seek (env->tocent[0].data_source, (lsn * CDIO_CD_FRAMESIZE_RAW) - 272, SEEK_SET); if (ret!=0) return ret; ret = cdio_stream_read (env->tocent[0].data_source, data, CDIO_CD_FRAMESIZE_RAW, nblocks); } else { /* We need to pad out the first 272 bytes with 0's */ BZERO(data, 272); ret = cdio_stream_seek (env->tocent[0].data_source, 0, SEEK_SET); if (ret!=0) return ret; ret = cdio_stream_read (env->tocent[0].data_source, (uint8_t *) data+272, CDIO_CD_FRAMESIZE_RAW - 272, nblocks); } /* ret is number of bytes if okay, but we need to return 0 okay. */ return ret == 0;}/*! Reads a single mode2 sector from cd device into data starting from lsn. Returns 0 if no error. */static int_read_mode1_sector_cdrdao (void *user_data, void *data, lsn_t lsn, bool b_form2){ _img_private_t *env = user_data; int ret; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; ret = cdio_stream_seek (env->tocent[0].data_source, lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); if (ret!=0) return ret; /* FIXME: Not completely sure the below is correct. */ ret = cdio_stream_read (env->tocent[0].data_source, buf, CDIO_CD_FRAMESIZE_RAW, 1); if (ret==0) return ret; memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE); return 0;}/*! Reads nblocks of mode1 sectors from cd device into data starting from lsn. Returns 0 if no error. */static int_read_mode1_sectors_cdrdao (void *user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks){ _img_private_t *env = user_data; int i; int retval; unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; for (i = 0; i < nblocks; i++) { if ( (retval = _read_mode1_sector_cdrdao (env, ((char *)data) + (blocksize * i), lsn + i, b_form2)) ) return retval; } return 0;}/*! Reads a single mode1 sector from cd device into data starting from lsn. Returns 0 if no error. */static int_read_mode2_sector_cdrdao (void *user_data, void *data, lsn_t lsn, bool b_form2){ _img_private_t *env = user_data; int ret; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; /* NOTE: The logic below seems a bit wrong and convoluted to me, but passes the regression tests. (Perhaps it is why we get valgrind errors in vcdxrip). Leave it the way it was for now. Review this sector 2336 stuff later. */ ret = cdio_stream_seek (env->tocent[0].data_source, lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); if (ret!=0) return ret; ret = cdio_stream_read (env->tocent[0].data_source, buf, CDIO_CD_FRAMESIZE_RAW, 1); if (ret==0) return ret; /* See NOTE above. */ if (b_form2) memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, M2RAW_SECTOR_SIZE); else memcpy (data, buf + CDIO_CD_XA_SYNC_HEADER, CDIO_CD_FRAMESIZE); return 0;}/*! Reads nblocks of mode2 sectors from cd device into data starting from lsn. Returns 0 if no error. */static int_read_mode2_sectors_cdrdao (void *user_data, void *data, lsn_t lsn, bool b_form2, unsigned int nblocks){ _img_private_t *env = user_data; int i; int retval; for (i = 0; i < nblocks; i++) { if ( (retval = _read_mode2_sector_cdrdao (env, ((char *)data) + (CDIO_CD_FRAMESIZE * i), lsn + i, b_form2)) ) return retval; } return 0;}/*! Return an array of strings giving possible TOC disk images. */char **cdio_get_devices_cdrdao (void){ char **drives = NULL; unsigned int num_files=0;#ifdef HAVE_GLOB_H unsigned int i; glob_t globbuf; globbuf.gl_offs = 0; glob("*.toc", GLOB_DOOFFS, NULL, &globbuf); for (i=0; i<globbuf.gl_pathc; i++) { cdio_add_device_list(&drives, globbuf.gl_pathv[i], &num_files); } globfree(&globbuf);#else cdio_add_device_list(&drives, DEFAULT_CDIO_DEVICE, &num_files);#endif /*HAVE_GLOB_H*/ cdio_add_device_list(&drives, NULL, &num_files); return drives;}/*! Return a string containing the default CD device. */char *cdio_get_default_device_cdrdao(void){ char **drives = cdio_get_devices_nrg(); char *drive = (drives[0] == NULL) ? NULL : strdup(drives[0]); cdio_free_device_list(drives); return drive;}static boolget_hwinfo_cdrdao ( const CdIo *p_cdio, /*out*/ cdio_hwinfo_t *hw_info){ strcpy(hw_info->psz_vendor, "libcdio"); strcpy(hw_info->psz_model, "cdrdao"); strcpy(hw_info->psz_revision, CDIO_VERSION); return true; }/*! Return the number of tracks in the current medium. CDIO_INVALID_TRACK is returned on error.*/static track_format_t_get_track_format_cdrdao(void *user_data, track_t i_track) { _img_private_t *env = user_data; if (!env->gen.init) _init_cdrdao(env); if (i_track > env->gen.i_tracks || i_track == 0) return TRACK_FORMAT_ERROR; return env->tocent[i_track-env->gen.i_first_track].track_format;}/*! Return true if we have XA data (green, mode2 form1) or XA data (green, mode2 form2). That is track begins: sync - header - subheader 12 4 - 8 FIXME: there's gotta be a better design for this and get_track_format?*/static bool_get_track_green_cdrdao(void *user_data, track_t i_track) { _img_private_t *env = user_data; if (!env->gen.init) _init_cdrdao(env); if (i_track > env->gen.i_tracks || i_track == 0) return false; return env->tocent[i_track-env->gen.i_first_track].track_green;}/*! Return the starting LSN track number i_track in obj. Track numbers start at 1. The "leadout" track is specified either by using i_track LEADOUT_TRACK or the total tracks+1. False is returned if there is no track entry.*/static lba_t_get_lba_track_cdrdao(void *user_data, track_t i_track){ _img_private_t *env = user_data; _init_cdrdao (env); if (i_track == CDIO_CDROM_LEADOUT_TRACK) i_track = env->gen.i_tracks+1; if (i_track <= env->gen.i_tracks+1 && i_track != 0) { return env->tocent[i_track-1].start_lba; } else return CDIO_INVALID_LBA;}/*! Check that a TOC file is valid. We parse the entire file.*/boolcdio_is_tocfile(const char *psz_cue_name) { int i; if (psz_cue_name == NULL) return false; i=strlen(psz_cue_name)-strlen("toc"); if (i>0) { if ( (psz_cue_name[i]=='t' && psz_cue_name[i+1]=='o' && psz_cue_name[i+2]=='c') || (psz_cue_name[i]=='T' && psz_cue_name[i+1]=='O' && psz_cue_name[i+2]=='C') ) { return parse_tocfile(NULL, psz_cue_name); } } return false;}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_am_cdrdao (const char *psz_source_name, const char *psz_access_mode){ if (psz_access_mode != NULL && strcmp(psz_access_mode, "image")) cdio_warn ("there is only one access mode, 'image' for cdrdao. Arg %s ignored", psz_access_mode); return cdio_open_cdrdao(psz_source_name);}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_cdrdao (const char *psz_cue_name){ CdIo *ret; _img_private_t *_data; cdio_funcs _funcs; memset( &_funcs, 0, sizeof(_funcs) ); _funcs.eject_media = _eject_media_image; _funcs.free = _free_image; _funcs.get_arg = _get_arg_image; _funcs.get_cdtext = get_cdtext_generic; _funcs.get_devices = cdio_get_devices_cdrdao; _funcs.get_default_device = cdio_get_default_device_cdrdao; _funcs.get_discmode = _get_discmode_image; _funcs.get_drive_cap = _get_drive_cap_image; _funcs.get_first_track_num= _get_first_track_num_image; _funcs.get_hwinfo = get_hwinfo_cdrdao; _funcs.get_mcn = _get_mcn_image; _funcs.get_num_tracks = _get_num_tracks_image; _funcs.get_track_format = _get_track_format_cdrdao; _funcs.get_track_green = _get_track_green_cdrdao; _funcs.get_track_lba = _get_lba_track_cdrdao; _funcs.get_track_msf = _get_track_msf_image; _funcs.lseek = _lseek_cdrdao; _funcs.read = _read_cdrdao; _funcs.read_audio_sectors = _read_audio_sectors_cdrdao; _funcs.read_mode1_sector = _read_mode1_sector_cdrdao; _funcs.read_mode1_sectors = _read_mode1_sectors_cdrdao; _funcs.read_mode2_sector = _read_mode2_sector_cdrdao; _funcs.read_mode2_sectors = _read_mode2_sectors_cdrdao; _funcs.set_arg = _set_arg_image; _funcs.stat_size = _stat_size_cdrdao; if (NULL == psz_cue_name) return NULL; _data = _cdio_malloc (sizeof (_img_private_t)); _data->gen.init = false; _data->psz_cue_name = NULL; _data->gen.data_source = NULL; _data->gen.source_name = NULL; ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) { free(_data); return NULL; } if (!cdio_is_tocfile(psz_cue_name)) { cdio_debug ("source name %s is not recognized as a TOC file", psz_cue_name); return NULL; } _set_arg_image (_data, "cue", psz_cue_name); _set_arg_image (_data, "source", psz_cue_name); if (_init_cdrdao(_data)) { return ret; } else { _free_image(_data); free(ret); return NULL; }}boolcdio_have_cdrdao (void){ return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -