Moved burn_cdtext_from_session() from write.c to cdtext.c
This commit is contained in:
parent
e15e949a20
commit
a34596d7b7
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2011.12.15.161349"
|
||||
#define Cdrskin_timestamP "2011.12.15.174914"
|
||||
|
421
libburn/cdtext.c
421
libburn/cdtext.c
@ -19,11 +19,432 @@
|
||||
|
||||
#include "libburn.h"
|
||||
#include "init.h"
|
||||
#include "structure.h"
|
||||
#include "options.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
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 ------------- */
|
||||
|
||||
|
||||
|
416
libburn/write.c
416
libburn/write.c
@ -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,
|
||||
struct burn_session *s,
|
||||
int flag)
|
||||
|
Loading…
Reference in New Issue
Block a user