Moved burn_cdtext_from_session() from write.c to cdtext.c

This commit is contained in:
Thomas Schmitt 2011-12-15 17:49:29 +00:00
parent 7640970ccc
commit 08f0c6c588
3 changed files with 422 additions and 417 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.12.15.161349" #define Cdrskin_timestamP "2011.12.15.174914"

View File

@ -19,11 +19,432 @@
#include "libburn.h" #include "libburn.h"
#include "init.h" #include "init.h"
#include "structure.h"
#include "options.h"
#include "libdax_msgs.h" #include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger; extern struct libdax_msgs *libdax_messenger;
/* --------------------- Production of CD-TEXT packs -------------------- */
struct burn_pack_cursor {
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) {
dummy[0]= 0;
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 <= 1 + ((cdt_curr->flags >> idx) & 1))
return 0;
for (j = 0; j < length; j++)
if (cdt_curr->payload[idx][j] != cdt_prev->payload[idx][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;
else if (flag & 1)
ret = -1;
BURN_FREE_MEM(crs.packs);
} else if (crs.num_packs > 0) {
*text_packs = crs.packs;
*num_packs = crs.num_packs;
}
return(ret);
}
/* ---------------- Reader of Sony Input Sheet Version 0.7T ------------- */ /* ---------------- Reader of Sony Input Sheet Version 0.7T ------------- */

View File

@ -669,422 +669,6 @@ int burn_write_leadout(struct burn_write_opts *o,
} }
struct burn_pack_cursor {
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) {
dummy[0]= 0;
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 <= 1 + ((cdt_curr->flags >> idx) & 1))
return 0;
for (j = 0; j < length; j++)
if (cdt_curr->payload[idx][j] != cdt_prev->payload[idx][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;
else if (flag & 1)
ret = -1;
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, static int burn_create_text_packs(struct burn_write_opts *o,
struct burn_session *s, struct burn_session *s,
int flag) int flag)