New API calls for composing CD-TEXT
This commit is contained in:
parent
2063dc2ca7
commit
620871c91d
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2011.12.09.092152"
|
#define Cdrskin_timestamP "2011.12.12.092602"
|
||||||
|
@ -589,7 +589,7 @@ void *burn_alloc_mem(size_t size, size_t count, int flag)
|
|||||||
{
|
{
|
||||||
void *pt;
|
void *pt;
|
||||||
|
|
||||||
pt = calloc(size, count);
|
pt = calloc(count, size);
|
||||||
if(pt == NULL)
|
if(pt == NULL)
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
@ -1291,45 +1291,17 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
|
|||||||
int *valid);
|
int *valid);
|
||||||
|
|
||||||
/* ts B11201 */
|
/* ts B11201 */
|
||||||
/** Read CD-TEXT packs from the Lead-in of an audio CD.
|
/** Read the array of CD-TEXT packs from the Lead-in of an audio CD.
|
||||||
Each pack consists of 18 bytes, of which 4 are header. 12 bytes are pieces
|
Each pack consists of 18 bytes, of which 4 are header. 12 bytes are pieces
|
||||||
of 0-terminated texts or binary data. 2 bytes hold a CRC.
|
of 0-terminated texts or binary data. 2 bytes hold a CRC.
|
||||||
See also MMC-3 Annex J.
|
For a description of the format of the array, see file doc/cdtext.txt.
|
||||||
The first byte of each pack tells the pack type (text meaning):
|
|
||||||
0x80 = Title
|
|
||||||
0x81 = Names of performers
|
|
||||||
0x82 = Songwriters
|
|
||||||
0x83 = Composers,
|
|
||||||
0x84 = Arrangers
|
|
||||||
0x85 = Messages
|
|
||||||
0x86 = text-and-binary: Disc Identification
|
|
||||||
0x87 = text-and-binary: Genre Identification
|
|
||||||
0x88 = binary: Table of Content information
|
|
||||||
0x89 = binary: Second Table of Content information
|
|
||||||
0x8e = UPC/EAN code of the album and ISRC code of each track
|
|
||||||
0x8f = binary: Size Information of the Block
|
|
||||||
The second byte tells the track number to which the first text piece in
|
|
||||||
a pack is associated. Number 0 means the whole album. Higher numbers are
|
|
||||||
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
|
|
||||||
one text for the disc and one for each track.
|
|
||||||
The third byte is a sequential counter.
|
|
||||||
The fourth byte is the Block Number and Character Position Indicator.
|
|
||||||
It consists of three bit fields:
|
|
||||||
bit7 = Double Bytes Character Code (0= single byte characters)
|
|
||||||
bit4-6 = Block Number (groups text packs in language blocks)
|
|
||||||
bit0-3 = Character position. 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.
|
|
||||||
The two CRC bytes are optional. Polynomial is x^16 + x^12 + x^5 + 1.
|
|
||||||
"All bits shall be inverted."
|
|
||||||
|
|
||||||
@param d The drive to query.
|
@param d The drive to query.
|
||||||
@param text_packs Will point to an allocated memory buffer with CD-TEXT.
|
@param text_packs Will point to an allocated memory buffer with CD-TEXT.
|
||||||
It will only contain text packs, and not be prepended
|
It will only contain text packs, and not be prepended
|
||||||
by the TOC header of four bytes, which gets stored with
|
by the TOC header of four bytes, which gets stored with
|
||||||
file cdtext.dat by cdrecord -vv -toc. The first two of
|
file cdtext.dat by cdrecord -vv -toc. (The first two of
|
||||||
these bytes are supposed to hold the number of CD-TEXT
|
these bytes are supposed to hold the number of CD-TEXT
|
||||||
bytes + 2. The other two bytes are supposed to be 0.
|
bytes + 2. The other two bytes are supposed to be 0.)
|
||||||
Dispose this buffer by free(), when no longer needed.
|
Dispose this buffer by free(), when no longer needed.
|
||||||
@param num_packs Will tell the number of text packs, i.e. the number of
|
@param num_packs Will tell the number of text packs, i.e. the number of
|
||||||
bytes in text_packs divided by 18.
|
bytes in text_packs divided by 18.
|
||||||
@ -1903,6 +1875,172 @@ int burn_session_add_track(struct burn_session *s, struct burn_track *t,
|
|||||||
int burn_session_remove_track(struct burn_session *s, struct burn_track *t);
|
int burn_session_remove_track(struct burn_session *s, struct burn_track *t);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Set the Character Codes, the Copyright bytes, and the Language Codes
|
||||||
|
for CD-TEXT blocks 0 to 7. They will be used in the block summaries
|
||||||
|
of text packs which get generated from text or binary data submitted
|
||||||
|
by burn_session_set_cdtext() and burn_track_set_cdtext().
|
||||||
|
Character Code value can be
|
||||||
|
0x00 = ISO-8859-1
|
||||||
|
0x01 = 7 bit ASCII
|
||||||
|
0x80 = MS-JIS (japanesei Kanji, double byte characters)
|
||||||
|
Copyright byte value can be
|
||||||
|
0x00 = not copyrighted
|
||||||
|
0x03 = copyrighted
|
||||||
|
Language Code value can be
|
||||||
|
0x00 = Unknown 0x04 = Croatian 0x08 = German 0x09 = English
|
||||||
|
0x0a = Spanish 0x0f = French 0x15 = Italian 0x27 = Finnish
|
||||||
|
0x29 = Turkish 0x69 = Japanese
|
||||||
|
or other latin alphabet codes from EBU Tech 3264, appendix 3, like
|
||||||
|
0x06 = Czech 0x07 = Danish 0x11 = Irish 0x17 = Latin
|
||||||
|
0x1b = Hungarian 0x1d = Dutch 0x20 = Polish 0x21 = Portuguese
|
||||||
|
as well as such where character representation is unclear
|
||||||
|
0x56 = Russian 0x6b = Hindi 0x6c = Hebrew 0x70 = Greek
|
||||||
|
0x75 = Chinese 0x77 = Bulgarian 0x7e = Arabic 0x7f = Amharic
|
||||||
|
Default is 0x09 = English for block 0 and 0x00 = Unknown for block 1 to 7.
|
||||||
|
Copyright and Character Code are 0x00 for all blocks by default.
|
||||||
|
For a detailed description of these parameters see file
|
||||||
|
doc/cdtext.txt, "Format of a CD-TEXT packs array", "Pack type 0x8f".
|
||||||
|
|
||||||
|
Parameter value -1 leaves the current setting of the session parameter
|
||||||
|
unchanged.
|
||||||
|
@param s Session where to change settings
|
||||||
|
@param char_codes Character Codes for block 0 to 7
|
||||||
|
@param copyrights Copyright bytes for block 0 to 7
|
||||||
|
@param languages Language Codes for block 0 to 7
|
||||||
|
@param flag Bitfiled for control purposes. Unused yet. Submit 0.
|
||||||
|
@return <=0 failure, > 0 success
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_session_set_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int languages[8], int flag);
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Obtain the current settings as of burn_session_set_cdtext_par() resp.
|
||||||
|
by default.
|
||||||
|
@param s Session which to inquire
|
||||||
|
@param char_codes Will return Character Codes for block 0 to 7
|
||||||
|
@param copyrights Will return Copyright bytes for block 0 to 7
|
||||||
|
@param languages Will return Language Codes for block 0 to 7
|
||||||
|
@param flag Bitfiled for control purposes. Unused yet. Submit 0.
|
||||||
|
@return <=0 failure, reply invalid, > 0 success, reply valid
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_session_get_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int block_languages[8], int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Attach text or binary data as CD-TEXT attributes to a session.
|
||||||
|
They can be used to generate CD-TEXT packs by burn_cdtext_from_session()
|
||||||
|
or to write CD-TEXT packs into the lead-in of a CD SAO session.
|
||||||
|
The latter happens only if no array of CD-TEXT packs is attached to
|
||||||
|
the write options by burn_write_opts_set_leadin_text().
|
||||||
|
For details of the CD-TEXT format and of the payload content, see file
|
||||||
|
doc/cdtext.txt .
|
||||||
|
@param s Session where to attach CD-TEXT attribute
|
||||||
|
@param block Number of the language block in which the attribute
|
||||||
|
shall appear. Possible values: 0 to 7.
|
||||||
|
@param pack_type Pack type number. 0x80 to 0x8e. Used if pack_type_name
|
||||||
|
is NULL or empty text. Else submit 0 and a name.
|
||||||
|
Pack type 0x8f is generated automatically and may not
|
||||||
|
be set by applications.
|
||||||
|
@param pack_type_name The pack type by name. Defined names are:
|
||||||
|
0x80 = "TITLE" 0x81 = "PERFORMER"
|
||||||
|
0x82 = "SONGWRITER" 0x83 = "COMPOSER"
|
||||||
|
0x84 = "ARRANGER" 0x85 = "MESSAGE"
|
||||||
|
0x86 = "DISCID" 0x87 = "GENRE"
|
||||||
|
0x88 = "TOC" 0x89 = "TOC2"
|
||||||
|
0x8d = "CLOSED" 0x8e = "UPC_ISRC"
|
||||||
|
Names are recognized uppercase and lowercase.
|
||||||
|
@param payload Text or binary bytes. The data will be copied to
|
||||||
|
session-internal memory.
|
||||||
|
Pack types 0x80 to 0x85 and 0x8e contain 0-terminated
|
||||||
|
cleartext. If double byte characters are used, then
|
||||||
|
two 0-bytes terminate the cleartext.
|
||||||
|
Pack type 0x86 is 0-terminated ASCII cleartext.
|
||||||
|
Pack type 0x87 consists of two byte big-endian
|
||||||
|
Genre code, and 0-terminated genre cleartext.
|
||||||
|
Pack type 0x88 mirrors the session table-of-content.
|
||||||
|
Pack type 0x89 is not understood yet.
|
||||||
|
Pack types 0x8a to 0x8c are reserved.
|
||||||
|
Pack type 0x8e contains cleartext which is not to be
|
||||||
|
shown by commercial audio CD players.
|
||||||
|
@pram length Number of bytes in payload. Including terminating
|
||||||
|
0-bytes.
|
||||||
|
@param flag Bitfield for control purposes.
|
||||||
|
bit0= payload contains double byte characters
|
||||||
|
(with character code 0x80 MS-JIS japanese Kanji)
|
||||||
|
@return > 0 indicates success , <= 0 is failure
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_session_set_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag);
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Obtain a CD-TEXT attribute that was set by burn_session_set_cdtext()
|
||||||
|
@param s Session to inquire
|
||||||
|
@param block Number of the language block to inquire.
|
||||||
|
@param pack_type Pack type number to inquire. Used if pack_type_name
|
||||||
|
is NULL or empty text. Else submit 0 and a name.
|
||||||
|
Pack type 0x8f is generated automatically and may not
|
||||||
|
be inquire in advance. Use burn_cdtext_from_session()
|
||||||
|
to generate all packs including type 0x8f packs.
|
||||||
|
@param pack_type_name The pack type by name.
|
||||||
|
See above burn_session_set_cdtext().
|
||||||
|
@param payload Will return a pointer to text or binary bytes.
|
||||||
|
Not a copy of data. Do not free() this address.
|
||||||
|
@pram length Will return the number of bytes pointed to by payload.
|
||||||
|
Including terminating 0-bytes.
|
||||||
|
@param flag Bitfield for control purposes. Unused yet. Submit 0.
|
||||||
|
@return 1 single byte char, 2 double byte char, <=0 error
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_session_get_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag);
|
||||||
|
|
||||||
|
/* ts B11210 */
|
||||||
|
/** Produce an array of CD-TEXT packs that could be submitted to
|
||||||
|
burn_write_opts_set_leadin_text() or stored as *.cdt file.
|
||||||
|
For a description of the format of the array, see file doc/cdtext.txt.
|
||||||
|
The input data stem from burn_session_set_cdtext_par(),
|
||||||
|
burn_session_set_cdtext(), and burn_track_set_cdtext().
|
||||||
|
@param s Session from which to produce CD-TEXT packs.
|
||||||
|
@param text_packs Will return the buffer with the CD-TEXT packs.
|
||||||
|
Dispose by free() when no longer needed.
|
||||||
|
@param num_packs Will return the number of 18 byte text packs.
|
||||||
|
@param flag Bitfield for control purposes.
|
||||||
|
bit0= do not produce CD-TEXT packs, but return number
|
||||||
|
of packs. This happens also if
|
||||||
|
(text_packs == NULL || num_packs == NULL).
|
||||||
|
@return Without flag bit0: > 0 is success, <= 0 failure
|
||||||
|
With flag bit0: > 0 is number of packs,
|
||||||
|
0 means no packs will be generated,
|
||||||
|
< 0 means failure
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_cdtext_from_session(struct burn_session *s,
|
||||||
|
unsigned char **text_packs, int *num_packs,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Remove all CD-TEXT attributes of the given block from the session.
|
||||||
|
They were attached by burn_session_set_cdtext().
|
||||||
|
@param s Session where to remove the CD-TEXT attribute
|
||||||
|
@param block Number of the language block in which the attribute
|
||||||
|
shall appear. Possible values: 0 to 7.
|
||||||
|
-1 causes text packs of all blocks to be removed.
|
||||||
|
@return > 0 is success, <= 0 failure
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_session_dispose_cdtext(struct burn_session *s, int block);
|
||||||
|
|
||||||
|
|
||||||
/** Define the data in a track
|
/** Define the data in a track
|
||||||
@param t the track to define
|
@param t the track to define
|
||||||
@param offset The lib will write this many 0s before start of data
|
@param offset The lib will write this many 0s before start of data
|
||||||
@ -1926,6 +2064,72 @@ void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
|||||||
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
|
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Attach text or binary data as CD-TEXT attributes to a track.
|
||||||
|
The payload will be used to generate CD-TEXT packs by
|
||||||
|
burn_cdtext_from_session() or to write CD-TEXT packs into the lead-in
|
||||||
|
of a CD SAO session. This happens if the CD-TEXT attribute of the session
|
||||||
|
gets generated, which has the same block number and pack type. In this
|
||||||
|
case, each track should have such a CD-TEXT attribute, too.
|
||||||
|
See burn_session_set_cdtext().
|
||||||
|
@param t Track where to attach CD-TEXT attribute.
|
||||||
|
@param block Number of the language block in which the attribute
|
||||||
|
shall appear. Possible values: 0 to 7.
|
||||||
|
@param pack_type Pack type number. 0x80 to 0x85 or 0x8e. Used if
|
||||||
|
pack_type_name is NULL or empty text. Else submit 0
|
||||||
|
and a name.
|
||||||
|
@param pack_type_name The pack type by name. Applicable names are:
|
||||||
|
0x80 = "TITLE" 0x81 = "PERFORMER"
|
||||||
|
0x82 = "SONGWRITER" 0x83 = "COMPOSER"
|
||||||
|
0x84 = "ARRANGER" 0x85 = "MESSAGE"
|
||||||
|
0x8e = "UPC_ISRC"
|
||||||
|
@param payload 0-terminated cleartext. If double byte characters
|
||||||
|
are used, then two 0-bytes terminate the cleartext.
|
||||||
|
@pram length Number of bytes in payload. Including terminating
|
||||||
|
0-bytes.
|
||||||
|
@param flag Bitfield for control purposes.
|
||||||
|
bit0= payload contains double byte characters
|
||||||
|
(with character code 0x80 MS-JIS japanese Kanji)
|
||||||
|
@return > 0 indicates success , <= 0 is failure
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_track_set_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag);
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Obtain a CD-TEXT attribute that was set by burn_track_set_cdtext().
|
||||||
|
@param t Track to inquire
|
||||||
|
@param block Number of the language block to inquire.
|
||||||
|
@param pack_type Pack type number to inquire. Used if pack_type_name
|
||||||
|
is NULL or empty text. Else submit 0 and a name.
|
||||||
|
@param pack_type_name The pack type by name.
|
||||||
|
See above burn_track_set_cdtext().
|
||||||
|
@param payload Will return a pointer to text bytes.
|
||||||
|
Not a copy of data. Do not free() this address.
|
||||||
|
@pram length Will return the number of bytes pointed to by payload.
|
||||||
|
Including terminating 0-bytes.
|
||||||
|
@param flag Bitfield for control purposes. Unused yet. Submit 0.
|
||||||
|
@return 1=single byte char , 2= double byte char , <=0 error
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_track_get_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag);
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
/** Remove all CD-TEXT attributes of the given block from the track.
|
||||||
|
They were attached by burn_track_set_cdtext().
|
||||||
|
@param t Track where to remove the CD-TEXT attribute.
|
||||||
|
@param block Number of the language block in which the attribute
|
||||||
|
shall appear. Possible values: 0 to 7.
|
||||||
|
-1 causes text packs of all blocks to be removed.
|
||||||
|
@return > 0 is success, <= 0 failure
|
||||||
|
@since 1.2.0
|
||||||
|
*/
|
||||||
|
int burn_track_dispose_cdtext(struct burn_track *t, int block);
|
||||||
|
|
||||||
|
|
||||||
/* ts A90910 */
|
/* ts A90910 */
|
||||||
/** Activates CD XA compatibility modes.
|
/** Activates CD XA compatibility modes.
|
||||||
libburn currently writes data only in CD mode 1. Some programs insist in
|
libburn currently writes data only in CD mode 1. Some programs insist in
|
||||||
@ -2437,12 +2641,19 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
|
|||||||
of a SAO write run on CD.
|
of a SAO write run on CD.
|
||||||
@param opts The option object to be manipulated
|
@param opts The option object to be manipulated
|
||||||
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
|
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
|
||||||
each. See burn_disc_get_leadin_text() for a description
|
each. For a description of the format of the array,
|
||||||
of the text pack format.
|
see file doc/cdtext.txt.
|
||||||
No header of 4 bytes must be prepended which would
|
No header of 4 bytes must be prepended which would
|
||||||
tell the number of pack bytes + 2.
|
tell the number of pack bytes + 2.
|
||||||
|
This parameter may be NULL if the currently attached
|
||||||
|
array of packs shall be removed.
|
||||||
@param num_packs The number of 18 byte packs in text_packs.
|
@param num_packs The number of 18 byte packs in text_packs.
|
||||||
@param flag Bitfield for control purposes. Unused yet. Submit 0.
|
This parameter may be 0 if the currently attached
|
||||||
|
array of packs shall be removed.
|
||||||
|
@param flag Bitfield for control purposes.
|
||||||
|
bit0= do not verify checksums
|
||||||
|
bit1= repair mismatching checksums
|
||||||
|
bit2= repair checksums if they are 00 00 with each pack
|
||||||
@return 1 on success, <= 0 on failure
|
@return 1 on success, <= 0 on failure
|
||||||
@since 1.2.0
|
@since 1.2.0
|
||||||
*/
|
*/
|
||||||
@ -2450,6 +2661,7 @@ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
|||||||
unsigned char *text_packs,
|
unsigned char *text_packs,
|
||||||
int num_packs, int flag);
|
int num_packs, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A61222 */
|
/* ts A61222 */
|
||||||
/** Sets a start address for writing to media and write modes which allow to
|
/** Sets a start address for writing to media and write modes which allow to
|
||||||
choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW).
|
choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW).
|
||||||
|
@ -4,6 +4,7 @@ burn_abort;
|
|||||||
burn_abort_pacifier;
|
burn_abort_pacifier;
|
||||||
burn_allow_drive_role_4;
|
burn_allow_drive_role_4;
|
||||||
burn_allow_untested_profiles;
|
burn_allow_untested_profiles;
|
||||||
|
burn_cdtext_from_session;
|
||||||
burn_disc_add_session;
|
burn_disc_add_session;
|
||||||
burn_disc_available_space;
|
burn_disc_available_space;
|
||||||
burn_disc_close_damaged;
|
burn_disc_close_damaged;
|
||||||
@ -113,13 +114,18 @@ burn_scsi_transport_id;
|
|||||||
burn_sectors_to_msf;
|
burn_sectors_to_msf;
|
||||||
burn_session_add_track;
|
burn_session_add_track;
|
||||||
burn_session_create;
|
burn_session_create;
|
||||||
|
burn_session_dispose_cdtext;
|
||||||
burn_session_free;
|
burn_session_free;
|
||||||
|
burn_session_get_cdtext;
|
||||||
|
burn_session_get_cdtext_par;
|
||||||
burn_session_get_hidefirst;
|
burn_session_get_hidefirst;
|
||||||
burn_session_get_leadout_entry;
|
burn_session_get_leadout_entry;
|
||||||
burn_session_get_sectors;
|
burn_session_get_sectors;
|
||||||
burn_session_get_tracks;
|
burn_session_get_tracks;
|
||||||
burn_session_hide_first_track;
|
burn_session_hide_first_track;
|
||||||
burn_session_remove_track;
|
burn_session_remove_track;
|
||||||
|
burn_session_set_cdtext;
|
||||||
|
burn_session_set_cdtext_par;
|
||||||
burn_set_messenger;
|
burn_set_messenger;
|
||||||
burn_set_scsi_logging;
|
burn_set_scsi_logging;
|
||||||
burn_set_signal_handling;
|
burn_set_signal_handling;
|
||||||
@ -133,13 +139,16 @@ burn_text_to_sev;
|
|||||||
burn_track_clear_isrc;
|
burn_track_clear_isrc;
|
||||||
burn_track_create;
|
burn_track_create;
|
||||||
burn_track_define_data;
|
burn_track_define_data;
|
||||||
|
burn_track_dispose_cdtext;
|
||||||
burn_track_free;
|
burn_track_free;
|
||||||
|
burn_track_get_cdtext;
|
||||||
burn_track_get_counters;
|
burn_track_get_counters;
|
||||||
burn_track_get_entry;
|
burn_track_get_entry;
|
||||||
burn_track_get_mode;
|
burn_track_get_mode;
|
||||||
burn_track_get_sectors;
|
burn_track_get_sectors;
|
||||||
burn_track_set_byte_swap;
|
burn_track_set_byte_swap;
|
||||||
burn_track_set_cdxa_conv;
|
burn_track_set_cdxa_conv;
|
||||||
|
burn_track_set_cdtext;
|
||||||
burn_track_set_default_size;
|
burn_track_set_default_size;
|
||||||
burn_track_set_isrc;
|
burn_track_set_isrc;
|
||||||
burn_track_set_size;
|
burn_track_set_size;
|
||||||
|
@ -578,6 +578,11 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
|
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
|
||||||
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled.
|
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled.
|
||||||
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
|
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
|
||||||
|
0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range
|
||||||
|
0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range
|
||||||
|
0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block
|
||||||
|
0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch
|
||||||
|
0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "write.h"
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
@ -54,6 +55,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
opts->text_packs = NULL;
|
opts->text_packs = NULL;
|
||||||
opts->num_text_packs = 0;
|
opts->num_text_packs = 0;
|
||||||
|
opts->no_text_pack_crc_check = 0;
|
||||||
opts->has_mediacatalog = 0;
|
opts->has_mediacatalog = 0;
|
||||||
opts->format = BURN_CDROM;
|
opts->format = BURN_CDROM;
|
||||||
opts->multi = 0;
|
opts->multi = 0;
|
||||||
@ -196,6 +198,10 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
|
|||||||
|
|
||||||
|
|
||||||
/* ts B11204 */
|
/* ts B11204 */
|
||||||
|
/* @param flag bit0=do not verify checksums
|
||||||
|
bit1= repair mismatching checksums
|
||||||
|
bit2= repair checksums if they are 00 00 with each pack
|
||||||
|
*/
|
||||||
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
||||||
unsigned char *text_packs,
|
unsigned char *text_packs,
|
||||||
int num_packs, int flag)
|
int num_packs, int flag)
|
||||||
@ -203,12 +209,11 @@ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
|||||||
int ret;
|
int ret;
|
||||||
unsigned char *pack_buffer = NULL;
|
unsigned char *pack_buffer = NULL;
|
||||||
|
|
||||||
if (num_packs > 3640) {
|
if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
|
||||||
/* READ TOC/PMA/ATIP can at most return 3640.7 packs */
|
|
||||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||||
0x0002018b,
|
0x0002018b,
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Too many CD-TEXT packs (> 3640)", 0, 0);
|
"Too many CD-TEXT packs", 0, 0);
|
||||||
ret= 0; goto ex;
|
ret= 0; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +224,26 @@ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
|||||||
free(opts->text_packs);
|
free(opts->text_packs);
|
||||||
opts->text_packs = NULL;
|
opts->text_packs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flag & 1) {
|
||||||
|
opts->no_text_pack_crc_check = 1;
|
||||||
|
} else {
|
||||||
|
opts->no_text_pack_crc_check = 0;
|
||||||
|
ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
|
||||||
|
(flag >> 1) & 3);
|
||||||
|
if (ret > 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack CRC mismatch", 0, 0);
|
||||||
|
ret = 0; goto ex;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack CRC mismatch had to be corrected",
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (num_packs > 0) {
|
if (num_packs > 0) {
|
||||||
memcpy(pack_buffer, text_packs, num_packs * 18);
|
memcpy(pack_buffer, text_packs, num_packs * 18);
|
||||||
opts->text_packs = pack_buffer;
|
opts->text_packs = pack_buffer;
|
||||||
|
@ -72,6 +72,7 @@ struct burn_write_opts
|
|||||||
/* ts B11203 : CD-TEXT */
|
/* ts B11203 : CD-TEXT */
|
||||||
unsigned char *text_packs;
|
unsigned char *text_packs;
|
||||||
int num_text_packs;
|
int num_text_packs;
|
||||||
|
int no_text_pack_crc_check;
|
||||||
|
|
||||||
/** A disc can have a media catalog number */
|
/** A disc can have a media catalog number */
|
||||||
int has_mediacatalog;
|
int has_mediacatalog;
|
||||||
@ -87,6 +88,13 @@ struct burn_write_opts
|
|||||||
*/
|
*/
|
||||||
#define Libburn_stdio_fsync_limiT 8192
|
#define Libburn_stdio_fsync_limiT 8192
|
||||||
|
|
||||||
|
/* Maximum number of Lead-in text packs.
|
||||||
|
READ TOC/PMA/ATIP can at most return 3640.7 packs.
|
||||||
|
The sequence counters of the packs have 8 bits. There are 8 blocks at most.
|
||||||
|
Thus max 2048 packs.
|
||||||
|
*/
|
||||||
|
#define Libburn_leadin_cdtext_packs_maX 2048
|
||||||
|
|
||||||
|
|
||||||
/** Options for disc reading operations. This should be created with
|
/** Options for disc reading operations. This should be created with
|
||||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "structure.h"
|
#include "structure.h"
|
||||||
#include "write.h"
|
#include "write.h"
|
||||||
@ -75,6 +76,8 @@ void burn_disc_free(struct burn_disc *d)
|
|||||||
struct burn_session *burn_session_create(void)
|
struct burn_session *burn_session_create(void)
|
||||||
{
|
{
|
||||||
struct burn_session *s;
|
struct burn_session *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
s = calloc(1, sizeof(struct burn_session));
|
s = calloc(1, sizeof(struct burn_session));
|
||||||
if (s == NULL) /* ts A70825 */
|
if (s == NULL) /* ts A70825 */
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -82,6 +85,13 @@ struct burn_session *burn_session_create(void)
|
|||||||
s->tracks = 0;
|
s->tracks = 0;
|
||||||
s->track = NULL;
|
s->track = NULL;
|
||||||
s->hidefirst = 0;
|
s->hidefirst = 0;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
s->cdtext[i] = NULL;
|
||||||
|
s->cdtext_language[i] = 0x00; /* Unknown */
|
||||||
|
s->cdtext_char_code[i] = 0x00; /* ISO-8859-1 */
|
||||||
|
s->cdtext_copyright[i] = 0x00;
|
||||||
|
}
|
||||||
|
s->cdtext_language[0] = 0x09; /* Single-block default is English */
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,13 +102,15 @@ void burn_session_hide_first_track(struct burn_session *s, int onoff)
|
|||||||
|
|
||||||
void burn_session_free(struct burn_session *s)
|
void burn_session_free(struct burn_session *s)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
s->refcnt--;
|
s->refcnt--;
|
||||||
if (s->refcnt == 0) {
|
if (s->refcnt == 0) {
|
||||||
/* dec refs on all elements */
|
/* dec refs on all elements */
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < s->tracks; i++)
|
for (i = 0; i < s->tracks; i++)
|
||||||
burn_track_free(s->track[i]);
|
burn_track_free(s->track[i]);
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
burn_cdtext_free(&(s->cdtext[i]));
|
||||||
free(s->track);
|
free(s->track);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
@ -141,6 +153,8 @@ int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s)
|
|||||||
struct burn_track *burn_track_create(void)
|
struct burn_track *burn_track_create(void)
|
||||||
{
|
{
|
||||||
struct burn_track *t;
|
struct burn_track *t;
|
||||||
|
int i;
|
||||||
|
|
||||||
t = calloc(1, sizeof(struct burn_track));
|
t = calloc(1, sizeof(struct burn_track));
|
||||||
if (t == NULL) /* ts A70825 */
|
if (t == NULL) /* ts A70825 */
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -180,16 +194,25 @@ struct burn_track *burn_track_create(void)
|
|||||||
|
|
||||||
/* ts A61024 */
|
/* ts A61024 */
|
||||||
t->swap_source_bytes = 0;
|
t->swap_source_bytes = 0;
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
t->cdtext[i] = NULL;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_track_free(struct burn_track *t)
|
void burn_track_free(struct burn_track *t)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
t->refcnt--;
|
t->refcnt--;
|
||||||
if (t->refcnt == 0) {
|
if (t->refcnt == 0) {
|
||||||
/* dec refs on all elements */
|
/* dec refs on all elements */
|
||||||
if (t->source)
|
if (t->source)
|
||||||
burn_source_free(t->source);
|
burn_source_free(t->source);
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
burn_cdtext_free(&(t->cdtext[i]));
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,3 +698,267 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct burn_cdtext *burn_cdtext_create(void)
|
||||||
|
{
|
||||||
|
struct burn_cdtext *t;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
t = burn_alloc_mem(sizeof(struct burn_cdtext), 1, 0);
|
||||||
|
if (t == NULL)
|
||||||
|
return NULL;
|
||||||
|
for(i = 0; i < Libburn_pack_num_typeS; i ++) {
|
||||||
|
t->payload[i] = NULL;
|
||||||
|
t->length[i] = 0;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void burn_cdtext_free(struct burn_cdtext **cdtext)
|
||||||
|
{
|
||||||
|
struct burn_cdtext *t;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
t = *cdtext;
|
||||||
|
if (t == NULL)
|
||||||
|
return;
|
||||||
|
for (i = 0; i < Libburn_pack_num_typeS; i++)
|
||||||
|
if (t->payload[i] != NULL)
|
||||||
|
free(t->payload[i]);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int burn_cdtext_name_to_type(char *pack_type_name)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
static char *pack_type_names[] = {
|
||||||
|
Libburn_pack_type_nameS
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < Libburn_pack_num_typeS; i++) {
|
||||||
|
if (pack_type_names[i][0] == 0)
|
||||||
|
continue;
|
||||||
|
for (j = 0; pack_type_names[i][j]; j++)
|
||||||
|
if (pack_type_names[i][j] != pack_type_name[j] &&
|
||||||
|
tolower(pack_type_names[i][j]) !=
|
||||||
|
pack_type_name[j])
|
||||||
|
break;
|
||||||
|
if (pack_type_names[i][j] == 0)
|
||||||
|
return Libburn_pack_type_basE + i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= double byte characters
|
||||||
|
*/
|
||||||
|
static int burn_cdtext_set(struct burn_cdtext **cdtext,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct burn_cdtext *t;
|
||||||
|
|
||||||
|
if (pack_type_name != NULL)
|
||||||
|
if (pack_type_name[0])
|
||||||
|
pack_type = burn_cdtext_name_to_type(pack_type_name);
|
||||||
|
if (pack_type < Libburn_pack_type_basE ||
|
||||||
|
pack_type >= Libburn_pack_type_basE + Libburn_pack_num_typeS) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018c,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack type out of range", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
t = *cdtext;
|
||||||
|
if (t == NULL) {
|
||||||
|
*cdtext = t = burn_cdtext_create();
|
||||||
|
if (t == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
i = pack_type - Libburn_pack_type_basE;
|
||||||
|
if (t->payload[i] != NULL)
|
||||||
|
free(t->payload[i]);
|
||||||
|
t->payload[i] = burn_alloc_mem((size_t) length, 1, 0);
|
||||||
|
if (t->payload[i] == NULL)
|
||||||
|
return -1;
|
||||||
|
memcpy(t->payload[i], payload, length);
|
||||||
|
t->length[i] = length;
|
||||||
|
t->flags = (t->flags & ~(1 << i)) | (flag & (1 << i));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @return 1=single byte char , 2= double byte char , <=0 error */
|
||||||
|
static int burn_cdtext_get(struct burn_cdtext *t, int pack_type,
|
||||||
|
char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag)
|
||||||
|
{
|
||||||
|
if (pack_type_name != NULL)
|
||||||
|
if (pack_type_name[0])
|
||||||
|
pack_type = burn_cdtext_name_to_type(pack_type_name);
|
||||||
|
if (pack_type < Libburn_pack_type_basE ||
|
||||||
|
pack_type >= Libburn_pack_type_basE + Libburn_pack_num_typeS) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018c,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack type out of range", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*payload = t->payload[pack_type - Libburn_pack_type_basE];
|
||||||
|
*length = t->length[pack_type - Libburn_pack_type_basE];
|
||||||
|
return 1 + ((t->flags >> (pack_type - Libburn_pack_type_basE)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int burn_cdtext_check_blockno(int block)
|
||||||
|
{
|
||||||
|
if (block < 0 || block > 7) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018d,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT block number out of range", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
/* @param flag bit0= double byte characters
|
||||||
|
*/
|
||||||
|
int burn_track_set_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = burn_cdtext_set(&(t->cdtext[block]), pack_type, pack_type_name,
|
||||||
|
payload, length, flag & 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
/* @return 1=single byte char , 2= double byte char , <=0 error */
|
||||||
|
int burn_track_get_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = burn_cdtext_get(t->cdtext[block], pack_type, pack_type_name,
|
||||||
|
payload, length, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
int burn_track_dispose_cdtext(struct burn_track *t, int block)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (block == -1) {
|
||||||
|
for (i= 0; i < 8; i++)
|
||||||
|
burn_cdtext_free(&(t->cdtext[i]));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
burn_cdtext_free(&(t->cdtext[0]));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
/* @param flag bit0= double byte characters
|
||||||
|
*/
|
||||||
|
int burn_session_set_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = burn_cdtext_set(&(s->cdtext[block]), pack_type, pack_type_name,
|
||||||
|
payload, length, flag & 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
/* @return 1=single byte char , 2= double byte char , <=0 error */
|
||||||
|
int burn_session_get_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = burn_cdtext_get(s->cdtext[block], pack_type, pack_type_name,
|
||||||
|
payload, length, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
int burn_session_set_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int block_languages[8], int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (char_codes[i] >= 0 && char_codes[i] <= 255)
|
||||||
|
s->cdtext_char_code[i] = char_codes[i];
|
||||||
|
if (copyrights[i] >= 0 && copyrights[i] <= 255)
|
||||||
|
s->cdtext_copyright[i] = copyrights[i];
|
||||||
|
if (block_languages[i] >= 0 && block_languages[i] <= 255)
|
||||||
|
s->cdtext_language[i] = block_languages[i];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
int burn_session_get_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int block_languages[8], int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
char_codes[i] = s->cdtext_char_code[i];
|
||||||
|
copyrights[i] = s->cdtext_copyright[i];
|
||||||
|
block_languages[i]= s->cdtext_language[i];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 API */
|
||||||
|
int burn_session_dispose_cdtext(struct burn_session *s, int block)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (block == -1) {
|
||||||
|
for (i= 0; i < 8; i++) {
|
||||||
|
burn_session_dispose_cdtext(s, i);
|
||||||
|
s->cdtext_char_code[i] = 0x01; /* 7 bit ASCII */
|
||||||
|
s->cdtext_copyright[i] = 0;
|
||||||
|
s->cdtext_language[i] = 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (burn_cdtext_check_blockno(block) <= 0)
|
||||||
|
return 0;
|
||||||
|
burn_cdtext_free(&(s->cdtext[block]));
|
||||||
|
s->cdtext_language[block] = 0x09; /* english */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,22 @@ struct isrc
|
|||||||
unsigned int serial; /* must be 0-99999 */
|
unsigned int serial; /* must be 0-99999 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
#define Libburn_pack_type_basE 0x80
|
||||||
|
#define Libburn_pack_num_typeS 0x10
|
||||||
|
#define Libburn_pack_type_nameS \
|
||||||
|
"TITLE", "PERFORMER", "SONGWRITER", "COMPOSER", \
|
||||||
|
"ARRANGER", "MESSAGE", "DISCID", "GENRE", \
|
||||||
|
"TOC", "TOC2", "", "", \
|
||||||
|
"", "CLOSED", "UPC_ISRC", "BLOCKSIZE"
|
||||||
|
|
||||||
|
struct burn_cdtext
|
||||||
|
{
|
||||||
|
unsigned char *(payload[Libburn_pack_num_typeS]);
|
||||||
|
int length[Libburn_pack_num_typeS];
|
||||||
|
int flags; /* bit0 - bit15= double byte characters */
|
||||||
|
};
|
||||||
|
|
||||||
struct burn_track
|
struct burn_track
|
||||||
{
|
{
|
||||||
int refcnt;
|
int refcnt;
|
||||||
@ -82,6 +98,9 @@ struct burn_track
|
|||||||
/* ts A90910 : conversions from CD XA prepared input */
|
/* ts A90910 : conversions from CD XA prepared input */
|
||||||
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *cdtext[8];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_session
|
struct burn_session
|
||||||
@ -97,6 +116,13 @@ struct burn_session
|
|||||||
int tracks;
|
int tracks;
|
||||||
struct burn_track **track;
|
struct burn_track **track;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *cdtext[8];
|
||||||
|
unsigned char cdtext_char_code[8];
|
||||||
|
unsigned char cdtext_copyright[8];
|
||||||
|
unsigned char cdtext_language[8];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_disc
|
struct burn_disc
|
||||||
@ -131,4 +157,9 @@ off_t burn_track_get_default_size(struct burn_track *t);
|
|||||||
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
|
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *burn_cdtext_create(void);
|
||||||
|
void burn_cdtext_free(struct burn_cdtext **cdtext);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__STRUCTURE_H */
|
#endif /* BURN__STRUCTURE_H */
|
||||||
|
493
libburn/write.c
493
libburn/write.c
@ -405,10 +405,23 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||||||
"Track mode has unusable value", 0, 0);
|
"Track mode has unusable value", 0, 0);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
if (o->num_text_packs > 0)
|
if (o->num_text_packs > 0) {
|
||||||
leadin_form = 0x41;
|
leadin_form = 0x41;
|
||||||
else
|
} else {
|
||||||
leadin_form = 0x01;
|
leadin_form = 0x01;
|
||||||
|
|
||||||
|
/* Check for CD-TEXT in session. Not the final creation,
|
||||||
|
because the cue sheet content might be needed for CD-TEXT
|
||||||
|
pack type 0x88 "TOC".
|
||||||
|
*/
|
||||||
|
if (o->text_packs == NULL) {
|
||||||
|
ret = burn_cdtext_from_session(session, NULL, NULL, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto failed;
|
||||||
|
else if (ret > 0)
|
||||||
|
leadin_form = 0x41;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = add_cue(sheet, ctladr | 1, 0, 0, leadin_form, 0, runtime);
|
ret = add_cue(sheet, ctladr | 1, 0, 0, leadin_form, 0, runtime);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -656,10 +669,442 @@ int burn_write_leadout(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_write_leadin_cdtext(struct burn_write_opts *o, struct burn_session *s,
|
struct burn_pack_cursor {
|
||||||
int flag)
|
unsigned char *packs;
|
||||||
|
int num_packs;
|
||||||
|
int td_used;
|
||||||
|
int hiseq[8];
|
||||||
|
int pack_count[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= double_byte characters
|
||||||
|
*/
|
||||||
|
int burn_create_new_pack(int pack_type, int track_no, int double_byte,
|
||||||
|
int block, int char_pos,
|
||||||
|
struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (crs->num_packs >= Libburn_leadin_cdtext_packs_maX) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018b,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Too many CD-TEXT packs", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (crs->hiseq[block] >= 255) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018e,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Too many CD-TEXT packs in block", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (char_pos > 15)
|
||||||
|
char_pos = 15;
|
||||||
|
else if (char_pos < 0)
|
||||||
|
char_pos = 0;
|
||||||
|
idx = crs->num_packs * 18;
|
||||||
|
crs->packs[idx++] = pack_type;
|
||||||
|
crs->packs[idx++] = track_no;
|
||||||
|
crs->packs[idx++] = crs->hiseq[block];
|
||||||
|
crs->packs[idx++] = ((flag & 1) << 7) | (block << 4) | char_pos;
|
||||||
|
crs->hiseq[block]++;
|
||||||
|
crs->td_used = 0;
|
||||||
|
crs->pack_count[pack_type - Libburn_pack_type_basE]++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Plain implementation of polynomial division on a Galois field, where
|
||||||
|
addition and subtraction both are binary exor. Euclidian algorithm.
|
||||||
|
Divisor is x^16 + x^12 + x^5 + 1 = 0x11021.
|
||||||
|
*/
|
||||||
|
static int crc_11021(unsigned char *data, int count, int flag)
|
||||||
|
{
|
||||||
|
int acc = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < count * 8 + 16; i++) {
|
||||||
|
acc = (acc << 1);
|
||||||
|
if (i < count * 8)
|
||||||
|
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
|
||||||
|
if (acc & 0x10000)
|
||||||
|
acc ^= 0x11021;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= repair mismatching checksums
|
||||||
|
bit1= repair checksums if all pack CRCs are 0
|
||||||
|
@return 0= no mismatch , >0 number of unrepaired mismatches
|
||||||
|
<0 number of repaired mismatches that were not 0
|
||||||
|
*/
|
||||||
|
int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag)
|
||||||
|
{
|
||||||
|
int i, residue, count = 0, repair;
|
||||||
|
unsigned char crc[2];
|
||||||
|
|
||||||
|
repair = flag & 1;
|
||||||
|
if (flag & 2) {
|
||||||
|
for (i = 0; i < num_packs * 18; i += 18)
|
||||||
|
if (packs[i + 16] || packs[i + 17])
|
||||||
|
break;
|
||||||
|
if (i == num_packs * 18)
|
||||||
|
repair = 1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_packs * 18; i += 18) {
|
||||||
|
residue = crc_11021(packs + i, 16, 0);
|
||||||
|
crc[0] = ((residue >> 8) & 0xff) ^ 0xff;
|
||||||
|
crc[1] = ((residue ) & 0xff) ^ 0xff;
|
||||||
|
if(crc[0] != packs[i + 16] || crc[1] != packs[i + 17]) {
|
||||||
|
if (repair) {
|
||||||
|
if (packs[i + 16] || packs[i + 17])
|
||||||
|
count--;
|
||||||
|
packs[i + 16] = crc[0];
|
||||||
|
packs[i + 17] = crc[1];
|
||||||
|
} else
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int burn_finalize_text_pack(struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int residue = 0, i, idx;
|
||||||
|
|
||||||
|
idx = 18 * crs->num_packs;
|
||||||
|
for(i = 4 + crs->td_used; i < 16; i++)
|
||||||
|
crs->packs[idx + i] = 0;
|
||||||
|
crs->td_used = 12;
|
||||||
|
|
||||||
|
/* MMC-3 Annex J : CRC Field consists of 2 bytes.
|
||||||
|
The polynomial is X16 + X12 + X5 + 1. All bits shall be inverted.
|
||||||
|
*/
|
||||||
|
residue = crc_11021(crs->packs + idx, 16, 0) ^ 0xffff;
|
||||||
|
|
||||||
|
crs->packs[idx + 16] = (residue >> 8) & 0xff;
|
||||||
|
crs->packs[idx + 17] = residue & 0xff;
|
||||||
|
crs->num_packs++;
|
||||||
|
crs->td_used = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= double_byte characters
|
||||||
|
*/
|
||||||
|
static int burn_create_tybl_packs(unsigned char *payload, int length,
|
||||||
|
int track_no, int pack_type, int block,
|
||||||
|
struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int i, ret, binary_part = 0, char_pos;
|
||||||
|
|
||||||
|
if (pack_type == 0x87)
|
||||||
|
binary_part = 2;
|
||||||
|
else if ((pack_type >= 0x88 && pack_type <= 0x8c) || pack_type == 0x8f)
|
||||||
|
binary_part = length;
|
||||||
|
for(i = 0; i < length; i++) {
|
||||||
|
if (crs->td_used == 0 || crs->td_used >= 12) {
|
||||||
|
if (crs->td_used > 0) {
|
||||||
|
ret = burn_finalize_text_pack(crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
char_pos = (i - binary_part) / (1 + (flag & 1));
|
||||||
|
ret = burn_create_new_pack(pack_type, track_no,
|
||||||
|
(flag & 1), block, char_pos,
|
||||||
|
crs, flag & 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
crs->packs[crs->num_packs * 18 + 4 + crs->td_used] =
|
||||||
|
payload[i];
|
||||||
|
crs->td_used++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Finalize block by 0x8f. Set bytes 20 to 27 to 0 for now. */
|
||||||
|
static int burn_create_bl_size_packs(int block, unsigned char *char_codes,
|
||||||
|
unsigned char *copyrights,
|
||||||
|
unsigned char *languages,
|
||||||
|
int num_tracks,
|
||||||
|
struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
unsigned char payload[12];
|
||||||
|
/* Normal is track_offset = 0.
|
||||||
|
But if the CUE sheet supports offset, then it is needed here too */
|
||||||
|
int track_offset = 0;
|
||||||
|
|
||||||
|
payload[0] = char_codes[block];
|
||||||
|
payload[1] = 1 + track_offset;
|
||||||
|
payload[2] = num_tracks + track_offset;
|
||||||
|
payload[3] = copyrights[block];
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
payload[i + 4] = crs->pack_count[i];
|
||||||
|
ret = burn_create_tybl_packs(payload, 12, 0, 0x8f, block, crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
payload[i] = crs->pack_count[i + 8];
|
||||||
|
payload[7] = 3; /* always 3 packs of type 0x8f */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
/* Will be set when all blocks are done */
|
||||||
|
payload[i + 8] = 0;
|
||||||
|
}
|
||||||
|
ret = burn_create_tybl_packs(payload, 12, 1, 0x8f, block, crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
/* Will be set when all blocks are done */
|
||||||
|
payload[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
payload[i + 4] = languages[i];
|
||||||
|
}
|
||||||
|
ret = burn_create_tybl_packs(payload, 12, 2, 0x8f, block, crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
ret = burn_finalize_text_pack(crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
crs->pack_count[i] = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Text packs of track for type and block
|
||||||
|
@param flag bit0= write TAB, because content is identical to previous track
|
||||||
|
*/
|
||||||
|
static int burn_create_tybl_t_packs(struct burn_track *t, int track_no,
|
||||||
|
int pack_type, int block,
|
||||||
|
struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int ret, length = 0, idx, double_byte, flags= 0;
|
||||||
|
unsigned char *payload = NULL, dummy[8];
|
||||||
|
struct burn_cdtext *cdt;
|
||||||
|
|
||||||
|
cdt = t->cdtext[block];
|
||||||
|
idx = pack_type - Libburn_pack_type_basE;
|
||||||
|
if (cdt != NULL) {
|
||||||
|
if (cdt->length[idx] > 0) {
|
||||||
|
payload = cdt->payload[idx];
|
||||||
|
length = cdt->length[idx];
|
||||||
|
}
|
||||||
|
flags = cdt->flags;
|
||||||
|
}
|
||||||
|
if (payload == NULL) {
|
||||||
|
sprintf((char *) dummy, "%d", track_no);
|
||||||
|
payload = dummy;
|
||||||
|
length = strlen((char *) dummy) + 1;
|
||||||
|
}
|
||||||
|
double_byte = !!(flags & (1 <<(pack_type - Libburn_pack_type_basE)));
|
||||||
|
if (flag & 1) {
|
||||||
|
length = 0;
|
||||||
|
dummy[length++] = 9;
|
||||||
|
if (double_byte)
|
||||||
|
dummy[length++] = 9;
|
||||||
|
dummy[length++] = 0;
|
||||||
|
if (double_byte)
|
||||||
|
dummy[length++] = 0;
|
||||||
|
payload = dummy;
|
||||||
|
}
|
||||||
|
ret = burn_create_tybl_packs(payload, length, track_no,
|
||||||
|
pack_type, block, crs, double_byte);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether the content is the same as in the previous pack. If so,
|
||||||
|
advise to use the TAB abbreviation.
|
||||||
|
*/
|
||||||
|
static int burn_decide_cdtext_tab(int block, int pack_type,
|
||||||
|
struct burn_cdtext *cdt_curr,
|
||||||
|
struct burn_cdtext *cdt_prev, int flag)
|
||||||
|
{
|
||||||
|
int length, j, idx;
|
||||||
|
|
||||||
|
idx = pack_type - Libburn_pack_type_basE;
|
||||||
|
if (cdt_curr == NULL || cdt_prev == NULL)
|
||||||
|
return 0;
|
||||||
|
if (((cdt_curr->flags >> idx) & 1) != ((cdt_prev->flags >> idx) & 1))
|
||||||
|
return 0;
|
||||||
|
length = cdt_curr->length[idx];
|
||||||
|
if (length != cdt_prev->length[idx] || length == 0)
|
||||||
|
return 0;
|
||||||
|
for (j = 0; j < length; j++)
|
||||||
|
if (cdt_curr->payload[j] != cdt_prev->payload[j])
|
||||||
|
break;
|
||||||
|
if (j < length)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Text packs of session and of tracks (if applicable), for type and block
|
||||||
|
*/
|
||||||
|
static int burn_create_tybl_s_packs(struct burn_session *s,
|
||||||
|
int pack_type, int block,
|
||||||
|
struct burn_pack_cursor *crs, int flag)
|
||||||
|
{
|
||||||
|
int i, ret, idx, double_byte, use_tab;
|
||||||
|
struct burn_cdtext *cdt;
|
||||||
|
/* Normal is track_offset = 0.
|
||||||
|
But if the CUE sheet supports offset, then it is needed here too */
|
||||||
|
int track_offset = 0;
|
||||||
|
|
||||||
|
cdt = s->cdtext[block];
|
||||||
|
idx = pack_type - Libburn_pack_type_basE;
|
||||||
|
if (cdt->length[idx] == 0 || cdt->payload[idx] == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
double_byte = !!(cdt->flags &
|
||||||
|
(1 <<(pack_type - Libburn_pack_type_basE)));
|
||||||
|
ret = burn_create_tybl_packs(cdt->payload[idx], cdt->length[idx], 0,
|
||||||
|
pack_type, block, crs, double_byte);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((pack_type < 0x80 || pack_type > 0x85) && pack_type != 0x8e) {
|
||||||
|
ret = burn_finalize_text_pack(crs, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < s->tracks; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
use_tab = burn_decide_cdtext_tab(block, pack_type,
|
||||||
|
s->track[i]->cdtext[block],
|
||||||
|
s->track[i - 1]->cdtext[block], 0);
|
||||||
|
else
|
||||||
|
use_tab = 0;
|
||||||
|
ret = burn_create_tybl_t_packs(s->track[i],
|
||||||
|
i + 1 + track_offset, pack_type,
|
||||||
|
block, crs, use_tab);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* Fill up last pack with 0s */
|
||||||
|
ret = burn_finalize_text_pack(crs, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11210 : API */
|
||||||
|
/* @param flag bit0= do not return CD-TEXT packs, but return number of packs
|
||||||
|
*/
|
||||||
|
int burn_cdtext_from_session(struct burn_session *s,
|
||||||
|
unsigned char **text_packs, int *num_packs,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int pack_type, block, ret, i, idx, j, residue;
|
||||||
|
struct burn_pack_cursor crs;
|
||||||
|
|
||||||
|
if (text_packs == NULL || num_packs == NULL) {
|
||||||
|
flag |= 1;
|
||||||
|
} else if (!(flag & 1)) {
|
||||||
|
*text_packs = NULL;
|
||||||
|
*num_packs = 0;
|
||||||
|
}
|
||||||
|
memset(&crs, 0, sizeof(struct burn_pack_cursor));
|
||||||
|
BURN_ALLOC_MEM(crs.packs, unsigned char,
|
||||||
|
Libburn_leadin_cdtext_packs_maX * 18);
|
||||||
|
|
||||||
|
for (block = 0; block < 8; block++)
|
||||||
|
if (s->cdtext[block] != NULL)
|
||||||
|
break;
|
||||||
|
if (block == 8)
|
||||||
|
{ret = 1; goto ex;}
|
||||||
|
|
||||||
|
for (block= 0; block < 8; block++) {
|
||||||
|
if (s->cdtext[block] == NULL)
|
||||||
|
continue;
|
||||||
|
for (pack_type = 0x80;
|
||||||
|
pack_type < 0x80 + Libburn_pack_num_typeS; pack_type++) {
|
||||||
|
if (pack_type == 0x8f)
|
||||||
|
continue;
|
||||||
|
ret = burn_create_tybl_s_packs(s,
|
||||||
|
pack_type, block, &crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = burn_create_bl_size_packs(block,
|
||||||
|
s->cdtext_char_code, s->cdtext_copyright,
|
||||||
|
s->cdtext_language, s->tracks, &crs, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the highest sequence numbers of each block into
|
||||||
|
the 0x8f packs 2 and 3 (bytes 20 to 27)
|
||||||
|
*/
|
||||||
|
for (i = 0; i < crs.num_packs; i++) {
|
||||||
|
idx = i * 18;
|
||||||
|
if (crs.packs[idx] == 0x8f && crs.packs[idx + 1] == 1) {
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
if (crs.hiseq[j] > 0)
|
||||||
|
crs.packs[idx + 4 + 8 + j] =
|
||||||
|
crs.hiseq[j] - 1;
|
||||||
|
else
|
||||||
|
crs.packs[idx + 4 + 8 + j] = 0;
|
||||||
|
} else if (crs.packs[idx] == 0x8f && crs.packs[idx + 1] == 2) {
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
if (crs.hiseq[j + 4] > 0)
|
||||||
|
crs.packs[idx + 4 + j] =
|
||||||
|
crs.hiseq[j + 4] - 1;
|
||||||
|
else
|
||||||
|
crs.packs[idx + 4 + j] = 0;
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
/* Re-compute checksum */
|
||||||
|
residue = crc_11021(crs.packs + idx, 16, 0) ^ 0xffff;
|
||||||
|
crs.packs[idx + 16] = (residue >> 8) & 0xff;
|
||||||
|
crs.packs[idx + 17] = residue & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (ret <= 0 || (flag & 1)) {
|
||||||
|
if (ret > 0)
|
||||||
|
ret = crs.num_packs;
|
||||||
|
BURN_FREE_MEM(crs.packs);
|
||||||
|
} else if (crs.num_packs > 0) {
|
||||||
|
*text_packs = crs.packs;
|
||||||
|
*num_packs = crs.num_packs;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int burn_create_text_packs(struct burn_write_opts *o,
|
||||||
|
struct burn_session *s,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret, num_packs = 0;
|
||||||
|
unsigned char *text_packs = NULL;
|
||||||
|
|
||||||
|
ret = burn_cdtext_from_session(s, &text_packs, &num_packs, 0);
|
||||||
|
if (ret > 0) {
|
||||||
|
if (o->text_packs != NULL)
|
||||||
|
free(o->text_packs);
|
||||||
|
o->text_packs = text_packs;
|
||||||
|
o->num_text_packs = num_packs;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int burn_write_leadin_cdtext(struct burn_write_opts *o,
|
||||||
|
struct burn_session *s, int flag)
|
||||||
{
|
{
|
||||||
int ret, i, j, si, lba, sub_cursor = 0, err, write_lba, sectors = 0;
|
int ret, i, j, si, lba, sub_cursor = 0, err, write_lba, sectors = 0;
|
||||||
|
int self_made_text_packs = 0;
|
||||||
unsigned char *subdata = NULL;
|
unsigned char *subdata = NULL;
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
@ -668,8 +1113,29 @@ int burn_write_leadin_cdtext(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
unsigned char *packs;
|
unsigned char *packs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (o->num_text_packs <= 0)
|
if (o->num_text_packs <= 0) {
|
||||||
{ret = 1; goto ex;}
|
if (o->text_packs != NULL)
|
||||||
|
{ret = 1; goto ex;}
|
||||||
|
/* Try to create CD-TEXT from .cdtext_* of session and track */
|
||||||
|
ret = burn_create_text_packs(o, s, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
self_made_text_packs = 1;
|
||||||
|
if (o->num_text_packs <= 0)
|
||||||
|
{ret = 1; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!o->no_text_pack_crc_check) {
|
||||||
|
ret = burn_cdtext_crc_mismatches(o->text_packs,
|
||||||
|
o->num_text_packs, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Program error: CD-TEXT pack CRC mismatch",
|
||||||
|
0, 0);
|
||||||
|
{ ret = 0; goto ex; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_WRITING_LEADIN;
|
d->busy = BURN_DRIVE_WRITING_LEADIN;
|
||||||
|
|
||||||
@ -741,6 +1207,12 @@ int burn_write_leadin_cdtext(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
if (self_made_text_packs) {
|
||||||
|
if (o->text_packs != NULL)
|
||||||
|
free(o->text_packs);
|
||||||
|
o->text_packs = NULL;
|
||||||
|
o->num_text_packs = 0;
|
||||||
|
}
|
||||||
BURN_FREE_MEM(subdata);
|
BURN_FREE_MEM(subdata);
|
||||||
BURN_FREE_MEM(buf);
|
BURN_FREE_MEM(buf);
|
||||||
d->busy = was_busy;
|
d->busy = was_busy;
|
||||||
@ -864,7 +1336,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n",
|
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n",
|
||||||
tnum+1, nwa, ret, d->nwa, (double) burn_track_get_sectors(t) * 2048.0,
|
tnum+1, nwa, ret, d->nwa, (double) burn_track_get_sectors(t) * 2048.0,
|
||||||
(double) d->media_capacity_remaining);
|
(double) d->media_capacity_remaining);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
|
||||||
@ -1196,7 +1669,7 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
||||||
tnum+1, nwa, ret, d->nwa);
|
tnum+1, nwa, ret, d->nwa);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
||||||
if (nwa > d->nwa)
|
if (nwa > d->nwa)
|
||||||
d->nwa = nwa;
|
d->nwa = nwa;
|
||||||
@ -1256,7 +1729,7 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
||||||
tnum+1, nwa, ret, d->nwa);
|
tnum+1, nwa, ret, d->nwa);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
||||||
if (nwa > d->nwa)
|
if (nwa > d->nwa)
|
||||||
d->nwa = nwa;
|
d->nwa = nwa;
|
||||||
@ -2670,7 +3143,7 @@ return crap. so we send the command, then ignore the result.
|
|||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SAO appendable d->nwa= %d\n", d->nwa);
|
"SAO appendable d->nwa= %d\n", d->nwa);
|
||||||
libdax_msgs_submit(
|
libdax_msgs_submit(
|
||||||
libdax_messenger, d->global_index, 0x000002,
|
libdax_messenger, d->global_index, 0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
|
||||||
|
@ -39,6 +39,13 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
int tnum);
|
int tnum);
|
||||||
int burn_write_close_session(struct burn_write_opts *o);
|
int burn_write_close_session(struct burn_write_opts *o);
|
||||||
|
|
||||||
|
/* @param flag bit0= repair checksum
|
||||||
|
bit1= repair checksum if all pack CRCs are 0
|
||||||
|
@return 0= no mismatch , >0 number of unrepaired mismatches
|
||||||
|
<0 number of repaired mismatches
|
||||||
|
*/
|
||||||
|
int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
|
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
|
||||||
|
Loading…
Reference in New Issue
Block a user