toc.c

来自「刻录光盘的程序」· C语言 代码 · 共 1,530 行 · 第 1/3 页

C
1,530
字号
		global.trackcreator[c->headerfield[1]-1] = (unsigned char *) malloc(len + 1);            if (global.trackcreator[c->headerfield[1]-1] != NULL) {               memcpy(global.trackcreator[c->headerfield[1]-1], line, len);               global.trackcreator[c->headerfield[1]-1][len] = '\0';            }          } else 	  if (c->headerfield[1] == 0	    && global.creator == NULL) {	    unsigned len;	    len = strlen((char *)line);            if (len > 0)            	global.creator = (unsigned char *) malloc(len + 1);            if (global.creator != NULL) {               memcpy(global.creator, line, len);               global.creator[len] = '\0';            }	  }        break;        case 0x82: /* Name(s) of the songwriter(s) */          if (DETAILED) fprintf(stderr, "Songwriter(s)");        break;        case 0x83: /* Name(s) of the composer(s) */          if (DETAILED) fprintf(stderr, "Composer(s)");        break;        case 0x84: /* Name(s) of the arranger(s) */          if (DETAILED) fprintf(stderr, "Arranger(s)");        break;        case 0x85: /* Message from content provider and/or artist */          if (DETAILED) fprintf(stderr, "Message");        break;        case 0x86: /* Disc Identification and information */          if (DETAILED) fprintf(stderr, "Disc identification");        break;        case 0x87: /* Genre Identification and information */          if (DETAILED) fprintf(stderr, "Genre identification");        break;        case 0x8e: /* UPC/EAN code or ISRC code */          if (DETAILED) fprintf(stderr, "UPC or ISRC");	  if (c->headerfield[1] > 0 && c->headerfield[1] < 100) {	    memcpy(g_toc[c->headerfield[1]-1].ISRC, line, sizeof(g_toc[0].ISRC));	  } else	  if (c->headerfield[1] == 0) {	    memcpy((char *)MCN, line, 13);	    MCN[13] = '\0';	  }        break;        case 0x88: /* Table of Content information */          if (DETAILED) fprintf(stderr, "Table of Content identification");	  if (DETAILED) dump_binary(c);         return 0;        case 0x89: /* Second Table of Content information */          if (DETAILED) fprintf(stderr, "Second Table of Content identification");	  if (DETAILED) dump_binary(c);         return 0;        case 0x8f: /* Size information of the block */	  if (!(DETAILED)) break;          switch (c->headerfield[1]) {	    case 0:	  fprintf(stderr, "first track is %d, last track is %d\n", 			c->textdatafield[1],			c->textdatafield[2]);	  if (c->textdatafield[3] & 0x80) {		fprintf(stderr, "Program Area CD Text information available\n");	        if (c->textdatafield[3] & 0x40) {		  fprintf(stderr, "Program Area copy protection available\n");	        }	  }	  if (c->textdatafield[3] & 0x07) {		fprintf(stderr, "message information is %scopyrighted\n", 			c->textdatafield[3] & 0x04 ? "": "not ");		fprintf(stderr, "Names of performer/songwriter/composer/arranger(s) are %scopyrighted\n", 			c->textdatafield[3] & 0x02 ? "": "not ");		fprintf(stderr, "album and track names are %scopyrighted\n", 			c->textdatafield[3] & 0x01 ? "": "not ");	  }	  fprintf(stderr, "%d packs with album/track names\n", c->textdatafield[4]);	  fprintf(stderr, "%d packs with performer names\n", c->textdatafield[5]);	  fprintf(stderr, "%d packs with songwriter names\n", c->textdatafield[6]);	  fprintf(stderr, "%d packs with composer names\n", c->textdatafield[7]);	  fprintf(stderr, "%d packs with arranger names\n", c->textdatafield[8]);	  fprintf(stderr, "%d packs with artist or content provider messages\n", c->textdatafield[9]);	  fprintf(stderr, "%d packs with disc identification information\n", c->textdatafield[10]);	  fprintf(stderr, "%d packs with genre identification/information\n", c->textdatafield[11]);	  break;	case 1:	  fprintf(stderr, "%d packs with table of contents information\n", c->textdatafield[0]);	  fprintf(stderr, "%d packs with second table of contents information\n", c->textdatafield[1]);	  fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[2]);	  fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[3]);	  fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[4]);	  fprintf(stderr, "%d packs with closed information\n", c->textdatafield[5]);	  fprintf(stderr, "%d packs with UPC/EAN ISRC information\n", c->textdatafield[6]);	  fprintf(stderr, "%d packs with size information\n", c->textdatafield[7]);	  fprintf(stderr, "last sequence numbers for blocks 1-8: %d %d %d %d "		 ,c->textdatafield[8]		 ,c->textdatafield[9]		 ,c->textdatafield[10]		 ,c->textdatafield[11]		);	  break;	case 2:	  fprintf(stderr, "%d %d %d %d\n"		 ,c->textdatafield[0]		 ,c->textdatafield[1]		 ,c->textdatafield[2]		 ,c->textdatafield[3]		);	  fprintf(stderr, "Language codes for blocks 1-8: %d %d %d %d %d %d %d %d\n"		 ,c->textdatafield[4]		 ,c->textdatafield[5]		 ,c->textdatafield[6]		 ,c->textdatafield[7]		 ,c->textdatafield[8]		 ,c->textdatafield[9]		 ,c->textdatafield[10]		 ,c->textdatafield[11]		);	  break;        }          if (DETAILED) fprintf(stderr, "Blocksize");	  if (DETAILED) dump_binary(c);         return 0;#if !defined DEBUG_CDTEXT        default:#else      }#endif          if (DETAILED) fprintf(stderr, ": header fields %02x %02x %02x  ",                          c->headerfield[1], c->headerfield[2], c->headerfield[3]);#if !defined DEBUG_CDTEXT      }      if (c->headerfield[1] == 0) {            if (DETAILED) fprintf(stderr, " for album   : ->");      } else {            if (DETAILED) fprintf(stderr, " for track %2u: ->", c->headerfield[1]);      }      if (DETAILED) fputs ((char *) line, stderr);      if (DETAILED) fputs ("<-", stderr);      if (dbcc != 0) {#else      {#endif          if (DETAILED) fprintf(stderr,"  %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"                        , c->textdatafield[0]                        , c->textdatafield[1]                        , c->textdatafield[2]                        , c->textdatafield[3]                        , c->textdatafield[4]                        , c->textdatafield[5]                        , c->textdatafield[6]                        , c->textdatafield[7]                        , c->textdatafield[8]                        , c->textdatafield[9]                        , c->textdatafield[10]                        , c->textdatafield[11]                 );      }      return 0;}#endif#if defined CDROMMULTISESSIONstatic int tmp_fd;#endif#ifdef CD_EXTRA/**************** CD-Extra special treatment *********************************/static unsigned char Extra_buffer[CD_FRAMESIZE_RAW];static int Read_CD_Extra_Info __PR(( unsigned long sector));static int Read_CD_Extra_Info(sector)	unsigned long sector;{  unsigned i;  static int offsets[] = {     75, 		/* this is observed for 12 cm discs */     60 };		/* this has been observed for 5 cm disks */  for (i = 0; i < sizeof(offsets)/sizeof(int); i++) {#ifdef DEBUG_XTRA    fprintf(stderr, "debug: Read_CD_Extra_Info at sector %lu\n", sector+offsets[i]);#endif    ReadCdRomData(get_scsi_p(), Extra_buffer, sector+offsets[i], 1);    /* If we are unlucky the drive cannot handle XA sectors by default.       We try to compensate by ignoring the first eight bytes.       Of course then we lack the last 8 bytes of the sector...     */#ifdef DEBUG_XTRA    { int ijk;      for (ijk = 0; ijk < 96; ijk++) {        fprintf(stderr, "%02x  ", Extra_buffer[ijk]);        if ((ijk+1) % 16 == 0) fprintf(stderr, "\n");      }    } #endif    if (Extra_buffer[0] == 0)      movebytes(Extra_buffer +8, Extra_buffer, CD_FRAMESIZE - 8);    /* check for cd extra */    if (Extra_buffer[0] == 'C' && Extra_buffer[1] == 'D')	return sector+offsets[i];  }  return 0;}static void Read_Subinfo __PR(( unsigned pos, unsigned length));static void Read_Subinfo(pos, length)	unsigned pos;	unsigned length;{  unsigned num_infos, num;  unsigned char *Subp, *orgSubp;  unsigned this_track = 0xff;#ifdef DEBUG_XTRA  unsigned char *up;  unsigned char *sp;  unsigned u;  unsigned short s;#endif  length += 8;  length = (length + CD_FRAMESIZE_RAW-1) / CD_FRAMESIZE_RAW;  length *= CD_FRAMESIZE_RAW;  orgSubp = Subp = (unsigned char *) malloc(length);  if (Subp == NULL) {    fprintf(stderr, "Read_Subinfo alloc error(%d)\n",length);    goto errorout;  }  ReadCdRomData(get_scsi_p(), Subp, pos, 1);  num_infos = Subp[45]+(Subp[44] << 8);#ifdef DEBUG_XTRA  fprintf(stderr, "subinfo version %c%c.%c%c, %d info packets\n",	  Subp[8],	  Subp[9],	  Subp[10],	  Subp[11],	  num_infos);#endif  length -= 46;  Subp += 46;  for (num = 0; num < num_infos && length > 0; num++) {    static const char *infopacketID[] = { "0", 			      "track identifier", 			      "album title",			      "universal product code", 			      "international standard book number",			      "copyright",			      "track title",			      "notes",			      "main interpret",			      "secondary interpret",			      "composer",			      "original composer",			      "creation date",			      "release  date",			      "publisher",			      "0f",			      "isrc audio track",			      "isrc lyrics",			      "isrc pictures",			      "isrc MIDI data",			      "14", "15", "16", "17", "18", "19",			      "copyright state SUB_INFO",			      "copyright state intro lyrics",			      "copyright state lyrics",			      "copyright state MIDI data",			      "1e", "1f",			      "intro lyrics",			      "pointer to lyrics text file and length", 			      "22", "23", "24", "25", "26", "27", "28",			      "29", "2a", "2b", "2c", "2d", "2e", "2f",			      "still picture descriptor",			      "31",			      "32", "33", "34", "35", "36", "37", "38",			      "39", "3a", "3b", "3c", "3d", "3e", "3f",			      "MIDI file descriptor",			      "genre code",			      "tempo",			      "key"			     };    unsigned id = *Subp;    unsigned len = *(Subp +1);    if (id >= sizeof(infopacketID)/sizeof(const char *)) {      fprintf(stderr, "Off=%4d, ind=%2d/%2d, unknown Id=%2u, len=%2u ",		Subp - orgSubp, num, num_infos, id, len);      Subp += 2 + 1;      length -= 2 + 1;      break;    }    switch (id) {    case 1:    /* track nummer or 0 */      this_track = 10 * (*(Subp + 2) - '0') + (*(Subp + 3) - '0');      break;    case 0x02: /* album title */	if (global.disctitle == NULL) {	    global.disctitle = (unsigned char *) malloc(len + 1);	    if (global.disctitle != NULL) {               memcpy(global.disctitle, Subp + 2, len);	       global.disctitle[len] = '\0';            }        }      break;    case 0x06: /* track title */	if (this_track > 0 && this_track < 100	    && global.tracktitle[this_track-1] == NULL) {            global.tracktitle[this_track-1] = (unsigned char *) malloc(len + 1);            if (global.tracktitle[this_track-1] != NULL) {               memcpy(global.tracktitle[this_track-1], Subp + 2, len);               global.tracktitle[this_track-1][len] = '\0';            }        }      break;    case 0x05: /* copyright message */	if (global.copyright_message == NULL) {	    global.copyright_message = (unsigned char *) malloc(len + 1);	    if (global.copyright_message != NULL) {               memcpy(global.copyright_message, Subp + 2, len);	       global.copyright_message[len] = '\0';            }        }      break;    case 0x08: /* creator */	if (global.creator == NULL) {	    global.creator = (unsigned char *) malloc(len + 1);	    if (global.creator != NULL) {               memcpy(global.creator, Subp + 2, len);	       global.creator[len] = '\0';            }        }      break;#if 0    case 0x03:    case 0x04:    case 0x07:    case 0x09:    case 0x0a:    case 0x0b:    case 0x0c:    case 0x0d:    case 0x0e:    case 0x0f:      fprintf(stderr, "%s: %*.*s\n",infopacketID[id], (int) len, (int) len, (Subp +2));      break;#ifdef DEBUG_XTRA    case 0x1a:    case 0x1b:    case 0x1c:    case 0x1d:	fprintf(stderr, "%s %scopyrighted\n", infopacketID[id], *(Subp + 2) == 0 ? "not " : "");      break;    case 0x21:      fprintf(stderr, "lyrics file beginning at sector %u",	      (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 2));      if (len == 8)	fprintf(stderr, ", having length: %u\n",                 (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 6));      else	fputs("\n", stderr);      break;    case 0x30:      sp = Subp + 2;      while (sp < Subp + 2 + len) {      /*while (len >= 10) {*/        s = be16_to_cpu((*(sp)) | (*(sp) << 8));        fprintf(stderr, "%04x, ", s);	sp += 2;        up = sp;	switch (s) {	case 0:	break;	case 4:	break;	case 5:	break;	case 6:	break;        }        u = GET_BE_UINT_FROM_CHARP(up);        fprintf(stderr, "%04lx, ", (long) u);        up += 4;        u = GET_BE_UINT_FROM_CHARP(up);        fprintf(stderr, "%04lx, ", (long) u);        up += 4;	sp += 8;      }      fputs("\n", stderr);      break;    case 0x40:      fprintf(stderr, "MIDI file beginning at sector %u",	      (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 2));      if (len == 8)	fprintf(stderr, ", having length: %u\n", 		(unsigned) GET_BE_UINT_FROM_CHARP(Subp + 6));      else	fputs("\n", stderr);      break;    case 0x42:      fprintf(stderr, "%s: %d beats per minute\n",infopacketID[id], *(Subp + 2));      break;    case 0x41:      if (len == 8)        fprintf(stderr, "%s: %x, %x, %x, %x, %x, %x, %x, %x\n",		infopacketID[id],		*(Subp + 2),		*(Subp + 3),		*(Subp + 4),		*(Subp + 5),		*(Subp + 6),		*(Subp + 7),		*(Subp + 8),		*(Subp + 9)	);      else        fprintf(stderr, "%s:\n",infopacketID[id]);      break;    case 0x43:      fprintf(stderr, "%s: %x\n",infopacketID[id], *(Subp + 2));      break;    default:      fprintf(stderr, "%s: %*.*s\n",infopacketID[id], (int) len, (int) len, (Subp +2));#endif#endif    }    if (len & 1) len++;    Subp += 2 + len;    length -= 2 + len;  }/* cleanup */  free(orgSubp);  return;errorout:  exit(2);}#endifstatic unsigned session_start;/*   A Cd-Extra is detected, if it is a multisession CD with   only audio tracks in the first session and a data track   in the last session. */static unsigned is_cd_extra(no_tracks)	unsigned no_tracks;{  unsigned mult_off;#if defined CDROMMULTISESSION  /*   * FIXME: we would have to do a ioctl (CDROMMULTISESSION)   *        for the cdrom device associated with the generic device   *	    not just AUX_DEVICE   */  struct cdrom_multisession ms_str;  if (interface == GENERIC_SCSI)    tmp_fd = open (global.aux_name, O_RDONLY);  else    tmp_fd = global.cooked_fd;  if (tmp_fd != -1) {    int result;    ms_str.addr_format = CDROM_LBA;    result = ioctl(tmp_fd, CDROMMULTISESSION, &ms_str);    if (result == -1) {      if (global.verbose != 0)        perror("multi session ioctl not supported: ");    } else {#ifdef DEBUG_XTRA  fprintf(stderr, "current ioctl multisession_offset = %u\n", ms_str.addr.lba);#endif	if (interface == GENERIC_SCSI)		close (tmp_fd);	if (ms_str.addr.lba > 0)	  return ms_str.addr.lba;    }  }#endif  mult_off = (no_tracks > 2 && !IS_AUDIO(no_tracks-2) && IS_AUDIO(no_tracks-3))                      ? g_toc[no_tracks-2].dwStartSector : 0;#ifdef DEBUG_XTRA  fprintf(stderr, "current guessed multisession_offset = %u\n", mult_off);#endif  return mult_off;

⌨️ 快捷键说明

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