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

📄 bincue.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    $Id: bincue.c,v 1.2 2005/01/01 02:43:58 rockyb Exp $    Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>    Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>    cue parsing 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: bincue.c,v 1.2 2005/01/01 02:43:58 rockyb Exp $";#include "image.h"#include "cdio_assert.h"#include "cdio_private.h"#include "_cdio_stdio.h"#include <cdio/logging.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_ERRNO_H#include <errno.h>#endif#ifdef HAVE_GLOB_H#include <glob.h>#endif#include <ctype.h>#include "portable.h"/* reader */#define DEFAULT_CDIO_DEVICE "videocd.bin"#define DEFAULT_CDIO_CUE    "videocd.cue"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_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"/*!  Initialize image structures. */static bool_init_bincue (_img_private_t *env){  lsn_t lead_lsn;  if (env->gen.init)    return false;  if (!(env->gen.data_source = cdio_stdio_new (env->gen.source_name))) {    cdio_warn ("init failed");    return false;  }  /* Have to set init before calling _stat_size_bincue() 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));  lead_lsn = _stat_size_bincue( (_img_private_t *) env);  if (-1 == lead_lsn) return false;  if ((env->psz_cue_name == NULL)) return false;  /* Read in CUE sheet. */  if ( !parse_cuefile(env, env->psz_cue_name) ) 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 - env->gen.i_first_track].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_bincue (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->gen.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_bincue (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) {    long int rem = this_track->datasize - env->pos.buff_offset;    if ((long int) size <= rem) {      this_size = cdio_stream_read(env->gen.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(env->gen.data_source, buf, rem, 1);    final_size += this_size;    memcpy (p, buf, this_size);    p += this_size;    this_size = cdio_stream_read(env->gen.data_source, buf, rem, 1);        /* Skip over stuff at end of this sector and the beginning of the next.     */    cdio_stream_read(env->gen.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_bincue (void *user_data){  _img_private_t *env = user_data;  long size;  size = cdio_stream_stat (env->gen.data_source);  if (size % CDIO_CD_FRAMESIZE_RAW)    {      cdio_warn ("image %s size (%ld) not multiple of blocksize (%d)", 		 env->gen.source_name, 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 4096		/* maximum line length + 1 */static boolparse_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];   /* 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 declarations may be unique to this image-parse routine. */  int start_index;  bool b_first_index_for_track=false;  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.i_tracks=0;    cd->gen.i_first_track=1;    cd->gen.b_cdtext_init  = true;    cd->gen.b_cdtext_error = false;    cd->psz_mcn=NULL;  }    while ((fgets(psz_line, MAXLINE, fp)) != NULL) {    i_line++;    if (NULL != (psz_keyword = strtok (psz_line, " \t\n\r"))) {      /* REM remarks ... */      if (0 == strcmp ("REM", psz_keyword)) {	;		/* global section */	/* CATALOG ddddddddddddd */      } else if (0 == strcmp ("CATALOG", psz_keyword)) {	if (-1 == i) {	  if (NULL == (psz_field = strtok (NULL, " \t\n\r"))) {	    cdio_log(log_level, 		     "%s line %d after word CATALOG: ",		     psz_cue_name, i_line);	    cdio_log(log_level, 		     "expecting 13-digit media catalog number, got nothing.");	    goto err_exit;	  }	  if (strlen(psz_field) != 13) {	    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 (cd) cd->psz_mcn = strdup (psz_field);	  if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {	    goto format_error;	  }	} else {	  goto not_in_global_section;	}		/* FILE "<filename>" <BINARY|WAVE|other?> */      } else if (0 == strcmp ("FILE", psz_keyword)) {	if (NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) {	  if (cd) cd->tocent[i + 1].filename = strdup (psz_field);	} else {	  goto format_error;	}		/* TRACK N <mode> */      } else if (0 == strcmp ("TRACK", psz_keyword)) {	int i_track;	if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {	  if (1!=sscanf(psz_field, "%d", &i_track)) {	    cdio_log(log_level, 		     "%s line %d after word TRACK:",		     psz_cue_name, i_line);	    cdio_log(log_level, 		     "Expecting a track number, got %s", psz_field);	    goto err_exit;	  }	}	if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) {	  track_info_t  *this_track=NULL;	  if (cd) {	    this_track = &(cd->tocent[cd->gen.i_tracks]);	    this_track->track_num   = cd->gen.i_tracks;	    this_track->num_indices = 0;	    b_first_index_for_track = false;	    cdtext_init (&(cd->gen.cdtext_track[cd->gen.i_tracks]));	    cd->gen.i_tracks++;	  }	  i++;	  	  if (0 == strcmp ("AUDIO", psz_field)) {	    if (cd) {	      this_track->mode           = AUDIO;	      this_track->blocksize      = CDIO_CD_FRAMESIZE_RAW;	      this_track->datasize       = CDIO_CD_FRAMESIZE_RAW;	      this_track->datastart      = 0;	      this_track->endsize        = 0;	      this_track->track_format   = TRACK_FORMAT_AUDIO;	      this_track->track_green    = false;	      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;

⌨️ 快捷键说明

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