Implemented cdrskin option textfile=

This commit is contained in:
Thomas Schmitt 2011-12-05 20:38:36 +00:00
parent 7be652ac6b
commit 7b0a23d553
3 changed files with 155 additions and 6 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Dec 02, 2011" .TH CDRSKIN 1 "Dec 05, 2011"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -760,6 +760,48 @@ the only mode which allows -multi.
.br .br
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL. Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
.TP .TP
.BI textfile= path
Read CD-TEXT packs from the file depicted by path and put them into the
Lead-in of the emerging session. This session has to be done by Session At Once
(SAO) mode and should contain audio tracks.
.br
path must lead to a regular file, which consists of an optional header of four
bytes and one or more text packs of 18 bytes each. Suitable would be the
file 'cdtext.dat' which gets extracted from CD media by options -vv -toc
and shown in human readable form by -vvv -toc.
.br
The header, if present, must tell the file size minus 2, encoded as big-endian
16 bit word. The other two bytes must be 0.
.br
A text pack consists of a pack type byte, a track number byte, a counter byte,
a Block Number and Character Indicator byte, 12 text characters or data bytes,
two optional CRC bytes.
.br
Pack types are: 0x80=Title, 0x81=Performers, 0x82=Songwriters,
0x83=Composers, 0x84=Arranger, 0x85=Messages, 0x86=Disc Identification,
0x87=Genre Identification, 0x88=Table of Content Information,
0x89=Second Table of Content Information, 0x8e=UPC/EAN resp. ISRC,
0x8f=Size Information of the Block.
.br
Track number 0 means the whole disc. Higher numbers are valid for types 0x80
to 0x85, and 0x8e. With these types, there has to be one text for the disc
and one for each track.
.br
Block Number and Character Position Indicator consists of three bit fields:
Bit 7 indicates two-byte characters. Bit 4 to bit 6 record the block number,
which groups texts into language blocks.
Bit 0 to bit 3 is either the number of characters which the current text
inherited from the previous pack, or 15 if the current text started before
the previous pack.
.br
The texts are terminated by 0 bytes. A text may span over several packs.
Unused characters in a pack are used for the next text of the same pack type.
If no text of the same type follows, then the remaining text bytes are
set to 0.
.br
The CRC algorithm is known as CRC-16-CCITT with divisor 0x11021.
MMC-3 says: "All bits shall be inverted."
.TP
.BI \-toc .BI \-toc
Print the table of content (TOC) which describes the tracks recorded on disc. Print the table of content (TOC) which describes the tracks recorded on disc.
The output contains all info from option -atip plus lines which begin with The output contains all info from option -atip plus lines which begin with
@ -768,13 +810,15 @@ start address of the track. Addresses are counted in CD sectors which with
SAO or TAO data tracks hold 2048 bytes each. SAO or TAO data tracks hold 2048 bytes each.
.br .br
If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in
of an audio CD gets extracted and written into file 'cdtext.dat', if that file of an audio CD get extracted and written into file 'cdtext.dat', if that file
does not yet exist. Prepended is a 4 byte header, followed by one or more does not yet exist. Prepended is a 4 byte header, followed by one or more
packs of 18 bytes each. packs of 18 bytes each.
.br .br
Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to
standard output. Bytes 4 to 15 of certain pack types are printed as ASCII standard output. Bytes 4 to 15 of certain pack types are printed as ASCII
characters if they have values in the range of 32 to 126. characters if they have values in the range of 32 to 126.
.br
See option textfile= for more information about the text pack format.
.RS .RS
.TP .TP
Example. Retrieve an afio archive from track number 2: Example. Retrieve an afio archive from track number 2:

View File

@ -2891,11 +2891,13 @@ see_cdrskin_eng_html:;
fprintf(stderr,"\ttsize=#\t\tannounces exact size of source data\n"); fprintf(stderr,"\ttsize=#\t\tannounces exact size of source data\n");
fprintf(stderr,"\tpadsize=#\tAmount of padding\n"); fprintf(stderr,"\tpadsize=#\tAmount of padding\n");
fprintf(stderr,
"\ttextfile=name\tSet the file with CD-Text data to 'name'\n");
fprintf(stderr,"\t-audio\t\tSubsequent tracks are CD-DA audio tracks\n"); fprintf(stderr,"\t-audio\t\tSubsequent tracks are CD-DA audio tracks\n");
fprintf(stderr, fprintf(stderr,
"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)\n"); "\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)\n");
fprintf(stderr, fprintf(stderr,
"\t-xa1\t\tSubsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n"); "\t-xa1\t\tSubsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
fprintf(stderr, fprintf(stderr,
"\t-isosize\tUse iso9660 file system size for next data track\n"); "\t-isosize\tUse iso9660 file system size for next data track\n");
fprintf(stderr,"\t-pad\t\tpadsize=30k\n"); fprintf(stderr,"\t-pad\t\tpadsize=30k\n");
@ -3310,6 +3312,10 @@ struct CdrskiN {
int track_type_by_default; /* 0= explicit, 1=not set, 2=by file extension */ int track_type_by_default; /* 0= explicit, 1=not set, 2=by file extension */
int swap_audio_bytes; int swap_audio_bytes;
/** CD-TEXT */
unsigned char *text_packs;
int num_text_packs;
/** The list of tracks with their data sources and parameters */ /** The list of tracks with their data sources and parameters */
struct CdrtracK *tracklist[Cdrskin_track_maX]; struct CdrtracK *tracklist[Cdrskin_track_maX];
int track_counter; int track_counter;
@ -3461,6 +3467,8 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->fill_up_media= 0; o->fill_up_media= 0;
o->track_type= BURN_MODE1; o->track_type= BURN_MODE1;
o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */ o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */
o->text_packs= NULL;
o->num_text_packs= 0;
o->track_type_by_default= 1; o->track_type_by_default= 1;
for(i=0;i<Cdrskin_track_maX;i++) for(i=0;i<Cdrskin_track_maX;i++)
o->tracklist[i]= NULL; o->tracklist[i]= NULL;
@ -3527,6 +3535,8 @@ int Cdrskin_destroy(struct CdrskiN **o, int flag)
Cdradrtrn_destroy(&(skin->adr_trn),0); Cdradrtrn_destroy(&(skin->adr_trn),0);
#endif /* ! Cdrskin_extra_leaN */ #endif /* ! Cdrskin_extra_leaN */
if(skin->text_packs != NULL)
free(skin->text_packs);
Cdrpreskin_destroy(&(skin->preskin),0); Cdrpreskin_destroy(&(skin->preskin),0);
if(skin->drives!=NULL) if(skin->drives!=NULL)
burn_drive_info_free(skin->drives); burn_drive_info_free(skin->drives);
@ -4601,7 +4611,7 @@ int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs,
printf("CD-TEXT data%s:\n", from_text); printf("CD-TEXT data%s:\n", from_text);
for(i= 0; i < num_packs; i++) { for(i= 0; i < num_packs; i++) {
pack= text_packs + 18 * i; pack= text_packs + 18 * i;
printf("%3d :", i); printf("%4d :", i);
for(j= 0; j < 18; j++) { for(j= 0; j < 18; j++) {
if(j >= 4 && j <= 15 && pack[j] >= 32 && pack[j] <= 126 && if(j >= 4 && j <= 15 && pack[j] >= 32 && pack[j] <= 126 &&
pack[0] != 0x88 && pack[0] != 0x89 && pack[0] != 0x8f) pack[0] != 0x88 && pack[0] != 0x89 && pack[0] != 0x8f)
@ -4768,6 +4778,10 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
free(text_packs); free(text_packs);
if(ret <= 0 && ret < final_ret) if(ret <= 0 && ret < final_ret)
final_ret= ret; final_ret= ret;
if(ret > 0)
printf("CD-Text len: %d\n", num_packs * 18 + 4);
} else {
fprintf(stderr, "cdrskin: No CD-Text or CD-Text unaware drive.\n");
} }
} }
@ -5298,6 +5312,81 @@ ex:;
} }
int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag)
{
int ret= 0, num_packs= 0, residue= 0;
struct stat stbuf;
FILE *fp= NULL;
unsigned char *text_packs = NULL, head[4];
if(stat(path, &stbuf) == -1) {
cannot_open:;
fprintf(stderr, "cdrskin: SORRY : Cannot open textfile='%s'\n", path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(!S_ISREG(stbuf.st_mode))
goto not_a_textfile;
residue= (stbuf.st_size % 18);
if(residue != 4 && residue != 0) {
not_a_textfile:;
fprintf(stderr,
"cdrskin: SORRY : File is not of usable type or content: textfile='%s'\n",
path);
ret= 0; goto ex;
}
if(stbuf.st_size < 18)
goto not_a_textfile;
fp= fopen(path, "rb");
if(fp == NULL)
goto cannot_open;
if(residue == 4) {
ret= fread(head, 4, 1, fp);
if(ret != 1) {
cannot_read:;
fprintf(stderr,
"cdrskin: SORRY : Cannot read all bytes from textfile='%s'\n", path);
fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno);
ret= 0; goto ex;
}
if(head[0] * 256 + head[1] != stbuf.st_size - 2)
goto not_a_textfile;
}
num_packs= (stbuf.st_size - residue) / 18;
if(num_packs > 3640) {
/* READ TOC/PMA/ATIP can at most return 65534 bytes = 3640.78 packs */
fprintf(stderr,
"cdrskin: SORRY : File too large (max. 65524 bytes): textfile='%s'\n",
path);
goto not_a_textfile;
}
text_packs= calloc(num_packs, 18);
if(text_packs == NULL) {
fprintf(stderr,
"cdrskin: FATAL : Cannot allocate %d bytes of memory for CD-TEXT\n",
num_packs * 18);
ret= -1; goto ex;
}
ret= fread(text_packs, num_packs * 18, 1, fp);
if(ret != 1)
goto cannot_read;
if(skin->text_packs != NULL)
free(skin->text_packs);
skin->text_packs= text_packs;
skin->num_text_packs= num_packs;
ret= 1;
ex:;
if(ret <= 0 && text_packs != NULL)
free(text_packs);
if(fp != NULL)
fclose(fp);
return(ret);
}
#ifndef Cdrskin_extra_leaN #ifndef Cdrskin_extra_leaN
/* A70324: proposal by Eduard Bloch */ /* A70324: proposal by Eduard Bloch */
@ -6525,6 +6614,12 @@ burn_failed:;
burn_write_opts_set_simulate(o, 1); burn_write_opts_set_simulate(o, 1);
} }
burn_write_opts_set_underrun_proof(o,skin->burnfree); burn_write_opts_set_underrun_proof(o,skin->burnfree);
if(skin->num_text_packs > 0) {
ret= burn_write_opts_set_leadin_text(o, skin->text_packs,
skin->num_text_packs, 0);
if(ret <= 0)
goto burn_failed;
}
ret= Cdrskin_activate_write_mode(skin,o,disc,0); ret= Cdrskin_activate_write_mode(skin,o,disc,0);
if(ret<=0) if(ret<=0)
goto burn_failed; goto burn_failed;
@ -6987,7 +7082,7 @@ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
/* cdrecord 2.01 options which are not scheduled for implementation, yet */ /* cdrecord 2.01 options which are not scheduled for implementation, yet */
static char ignored_partial_options[][41]= { static char ignored_partial_options[][41]= {
"timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=", "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=",
"pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=", "pregap=", "defpregap=", "mcn=", "isrc=", "index=",
"pktsize=", "cuefile=", "pktsize=", "cuefile=",
"" ""
}; };
@ -7750,6 +7845,16 @@ set_stream_recording:;
skin->tell_media_space= 1; skin->tell_media_space= 1;
skin->preskin->demands_cdrskin_caps= 1; skin->preskin->demands_cdrskin_caps= 1;
} else if(strncmp(argv[i],"-textfile=", 10)==0) {
value_pt= argv[i] + 10;
goto set_textfile;
} else if(strncmp(argv[i],"textfile=", 9)==0) {
value_pt= argv[i] + 9;
set_textfile:;
ret= Cdrskin_read_textfile(skin, value_pt, 0);
if(ret <= 0)
return(ret);
} else if(strcmp(argv[i],"-toc")==0) { } else if(strcmp(argv[i],"-toc")==0) {
skin->do_atip= 2; skin->do_atip= 2;
if(skin->verbosity>=Cdrskin_verbose_cmD) if(skin->verbosity>=Cdrskin_verbose_cmD)

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.12.05.203600" #define Cdrskin_timestamP "2011.12.05.203821"