⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdrdao.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    $Id: cdrdao.c,v 1.1 2005/01/01 02:43:58 rockyb Exp $    Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>    toc reading routine adapted from cuetools    Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* This code implements low-level access functions for a CD images   residing inside a disk file (*.bin) and its associated cue sheet.   (*.cue).*/static const char _rcsid[] = "$Id: cdrdao.c,v 1.1 2005/01/01 02:43:58 rockyb Exp $";#include "image.h"#include "cdio_assert.h"#include "_cdio_stdio.h"#include <cdio/logging.h>#include <cdio/sector.h>#include <cdio/util.h>#include <cdio/version.h>#ifdef HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#ifdef HAVE_GLOB_H#include <glob.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include <ctype.h>#include "portable.h"/* reader */#define DEFAULT_CDIO_DEVICE "videocd.bin"#define DEFAULT_CDIO_CDRDAO "videocd.toc"typedef struct {  /* Things common to all drivers like this.      This must be first. */  generic_img_private_t gen;   internal_position_t pos;     char         *psz_cue_name;  char         *psz_mcn;        /* Media Catalog Number (5.22.3) 				   exactly 13 bytes */  track_info_t  tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track 					         add 1 for leadout. */  discmode_t    disc_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"/*!  Initialize image structures. */static bool_init_cdrdao (_img_private_t *env){  lsn_t lead_lsn;  if (env->gen.init)    return false;  /* Have to set init before calling _stat_size_cdrdao() or we will     get into infinite recursion calling passing right here.   */  env->gen.init      = true;    env->gen.i_first_track = 1;  env->psz_mcn       = NULL;  env->disc_mode     = CDIO_DISC_MODE_NO_INFO;  cdtext_init (&(env->gen.cdtext));  /* Read in TOC sheet. */  if ( !parse_tocfile(env, env->psz_cue_name) ) return false;    lead_lsn = _stat_size_cdrdao( (_img_private_t *) env);  if (-1 == lead_lsn)     return false;  /* Fake out leadout track and sector count for last track*/  cdio_lsn_to_msf (lead_lsn, &env->tocent[env->gen.i_tracks].start_msf);  env->tocent[env->gen.i_tracks].start_lba = cdio_lsn_to_lba(lead_lsn);  env->tocent[env->gen.i_tracks-env->gen.i_first_track].sec_count =     cdio_lsn_to_lba(lead_lsn - env->tocent[env->gen.i_tracks-1].start_lba);  return true;}/*!  Reads into buf the next size bytes.  Returns -1 on error.   Would be libc's seek() but we have to adjust for the extra track header   information in each sector.*/static off_t_lseek_cdrdao (void *user_data, off_t offset, int whence){  _img_private_t *env = user_data;  /* real_offset is the real byte offset inside the disk image     The number below was determined empirically. I'm guessing     the 1st 24 bytes of a bin file are used for something.  */  off_t real_offset=0;  unsigned int i;  env->pos.lba = 0;  for (i=0; i<env->gen.i_tracks; i++) {    track_info_t  *this_track=&(env->tocent[i]);    env->pos.index = i;    if ( (this_track->sec_count*this_track->datasize) >= offset) {      int blocks            = offset / this_track->datasize;      int rem               = offset % this_track->datasize;      int block_offset      = blocks * this_track->blocksize;      real_offset          += block_offset + rem;      env->pos.buff_offset = rem;      env->pos.lba        += blocks;      break;    }    real_offset   += this_track->sec_count*this_track->blocksize;    offset        -= this_track->sec_count*this_track->datasize;    env->pos.lba += this_track->sec_count;  }  if (i==env->gen.i_tracks) {    cdio_warn ("seeking outside range of disk image");    return -1;  } else {    real_offset += env->tocent[i].datastart;    return cdio_stream_seek(env->tocent[i].data_source, real_offset, whence);  }}/*!  Reads into buf the next size bytes.  Returns -1 on error.   FIXME:    At present we assume a read doesn't cross sector or track   boundaries.*/static ssize_t_read_cdrdao (void *user_data, void *data, size_t size){  _img_private_t *env = user_data;  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };  char *p = data;  ssize_t final_size=0;  ssize_t this_size;  track_info_t  *this_track=&(env->tocent[env->pos.index]);  ssize_t skip_size = this_track->datastart + this_track->endsize;  while (size > 0) {    int rem = this_track->datasize - env->pos.buff_offset;    if (size <= rem) {      this_size = cdio_stream_read(this_track->data_source, buf, size, 1);      final_size += this_size;      memcpy (p, buf, this_size);      break;    }    /* Finish off reading this sector. */    cdio_warn ("Reading across block boundaries not finished");    size -= rem;    this_size = cdio_stream_read(this_track->data_source, buf, rem, 1);    final_size += this_size;    memcpy (p, buf, this_size);    p += this_size;    this_size = cdio_stream_read(this_track->data_source, buf, rem, 1);        /* Skip over stuff at end of this sector and the beginning of the next.     */    cdio_stream_read(this_track->data_source, buf, skip_size, 1);    /* Get ready to read another sector. */    env->pos.buff_offset=0;    env->pos.lba++;    /* Have gone into next track. */    if (env->pos.lba >= env->tocent[env->pos.index+1].start_lba) {      env->pos.index++;      this_track=&(env->tocent[env->pos.index]);      skip_size = this_track->datastart + this_track->endsize;    }  }  return final_size;}/*!   Return the size of the CD in logical block address (LBA) units. */static uint32_t _stat_size_cdrdao (void *user_data){  _img_private_t *env = user_data;  long size;  size = cdio_stream_stat (env->tocent[0].data_source);  if (size % CDIO_CD_FRAMESIZE_RAW)    {      cdio_warn ("image %s size (%ld) not multiple of blocksize (%d)", 		 env->tocent[0].filename, size, CDIO_CD_FRAMESIZE_RAW);      if (size % M2RAW_SECTOR_SIZE == 0)	cdio_warn ("this may be a 2336-type disc image");      else if (size % CDIO_CD_FRAMESIZE_RAW == 0)	cdio_warn ("this may be a 2352-type disc image");      /* exit (EXIT_FAILURE); */    }  size /= CDIO_CD_FRAMESIZE_RAW;  return size;}#define MAXLINE 512#define UNIMPLIMENTED_MSG \  cdio_log(log_level, "%s line %d: unimplimented keyword: %s",  \	   psz_cue_name, i_line, psz_keyword)static boolparse_tocfile (_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];   /* 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->gen.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;    fp = fopen (psz_cue_name, "r");  if (fp == NULL) {    cdio_log(log_level, "error opening %s for reading: %s", 	     psz_cue_name, strerror(errno));    return false;  }  if (cd) {    cd->gen.b_cdtext_init  = true;    cd->gen.b_cdtext_error = false;  }  while ((fgets(psz_line, MAXLINE, fp)) != NULL) {    i_line++;    /* strip comment from line */    /* todo: // in quoted strings? */    /* //comment */    if (NULL != (psz_field = strstr (psz_line, "//")))      *psz_field = '\0';        if (NULL != (psz_keyword = strtok (psz_line, " \t\n\r"))) {      /* CATALOG "ddddddddddddd" */      if (0 == strcmp ("CATALOG", psz_keyword)) {	if (-1 == i) {	  if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {	    if (13 != strlen(psz_field)) {	      cdio_log(log_level, 		       "%s line %d after word CATALOG:", 		       psz_cue_name, i_line);	      cdio_log(log_level, 		       "Token %s has length %ld. Should be 13 digits.", 		       psz_field, (long int) strlen(psz_field));	      	      goto err_exit;	    } else {	      /* Check that we have all digits*/	      unsigned int i;	      for (i=0; i<13; i++) {		if (!isdigit(psz_field[i])) {		    cdio_log(log_level, 			     "%s line %d after word CATALOG:", 			     psz_cue_name, i_line);		    cdio_log(log_level, 			     "Character \"%c\" at postition %i of token \"%s\""			     " is not all digits.", 			     psz_field[i], i+1, psz_field);		    goto err_exit;		}	      }	      if (NULL != cd) cd->psz_mcn = strdup (psz_field); 	    }	  } else {	    cdio_log(log_level, 		     "%s line %d after word CATALOG:", 		     psz_cue_name, i_line);	    cdio_log(log_level, "Expecting 13 digits; nothing seen.");	    goto err_exit;	  }	} else {	  goto err_exit;	}		/* CD_DA | CD_ROM | CD_ROM_XA */      } else if (0 == strcmp ("CD_DA", psz_keyword)) {	if (-1 == i) {	  if (NULL != cd)	    cd->disc_mode = CDIO_DISC_MODE_CD_DA;	} else {	  goto not_in_global_section;	}      } else if (0 == strcmp ("CD_ROM", psz_keyword)) {	if (-1 == i) {	  if (NULL != cd)	    cd->disc_mode = CDIO_DISC_MODE_CD_DATA;	} else {	  goto not_in_global_section;	}	      } else if (0 == strcmp ("CD_ROM_XA", psz_keyword)) {	if (-1 == i) {	  if (NULL != cd)	    cd->disc_mode = CDIO_DISC_MODE_CD_XA;	} else {	  goto not_in_global_section;	}		/* TRACK <track-mode> [<sub-channel-mode>] */      } else if (0 == strcmp ("TRACK", psz_keyword)) {	i++;	if (NULL != cd) cdtext_init (&(cd->gen.cdtext_track[i]));	if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {	  if (0 == strcmp ("AUDIO", psz_field)) {	    if (NULL != cd) {	      cd->tocent[i].track_format = TRACK_FORMAT_AUDIO;	      cd->tocent[i].blocksize    = CDIO_CD_FRAMESIZE_RAW;	      cd->tocent[i].datasize     = CDIO_CD_FRAMESIZE_RAW;	      cd->tocent[i].datastart    = 0;	      cd->tocent[i].endsize      = 0;	      switch(cd->disc_mode) {	      case CDIO_DISC_MODE_NO_INFO:		cd->disc_mode = CDIO_DISC_MODE_CD_DA;		break;	      case CDIO_DISC_MODE_CD_DA:	      case CDIO_DISC_MODE_CD_MIXED:	      case CDIO_DISC_MODE_ERROR:		/* Disc type stays the same. */		break;	      case CDIO_DISC_MODE_CD_DATA:	      case CDIO_DISC_MODE_CD_XA:		cd->disc_mode = CDIO_DISC_MODE_CD_MIXED;		break;	      default:		cd->disc_mode = CDIO_DISC_MODE_ERROR;	      }	    }	  } else if (0 == strcmp ("MODE1", psz_field)) {	    if (NULL != cd) {	      cd->tocent[i].track_format = TRACK_FORMAT_DATA;	      cd->tocent[i].blocksize    = CDIO_CD_FRAMESIZE_RAW;	      cd->tocent[i].datastart    = CDIO_CD_SYNC_SIZE 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -