Augmented struct burn_toc_entry by new off_t block addresses and counters

This commit is contained in:
Thomas Schmitt 2024-02-27 20:48:11 +01:00
parent 069b4edecd
commit 17a020e9fc
5 changed files with 128 additions and 45 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2024.02.26.150632" #define Cdrskin_timestamP "2024.02.27.194737"

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2023 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
This is the official API definition of libburn. This is the official API definition of libburn.
@ -9,6 +9,8 @@
*/ */
/* Important: If you add a public API function then add its name to file /* Important: If you add a public API function then add its name to file
libburn/libburn.ver libburn/libburn.ver
in the node LIBBURN4_Major.Minor.Micro with the numbers of
the next release version, citing the previous node.
*/ */
@ -376,6 +378,9 @@ struct burn_toc_entry
@since 0.5.2 : DVD extensions are made valid for CD too @since 0.5.2 : DVD extensions are made valid for CD too
bit1= LRA extension is valid @since 0.7.2 bit1= LRA extension is valid @since 0.7.2
bit2= Track status bits extension is valid @since 1.2.8 bit2= Track status bits extension is valid @since 1.2.8
bit3= Long block address is valid:
long_start_lba, long_track_blocks, long_last_rec_adr
@since 1.5.8
*/ */
unsigned char extensions_valid; unsigned char extensions_valid;
@ -386,8 +391,10 @@ struct burn_toc_entry
unsigned char session_msb; unsigned char session_msb;
unsigned char point_msb; unsigned char point_msb;
/* pmin, psec, and pframe may be too small if DVD extension is valid */ /* pmin, psec, and pframe may be too small if DVD extension is valid */
/* -1 means that only long_start_lba is valid */
int start_lba; int start_lba;
/* min, sec, and frame may be too small if DVD extension is valid */ /* min, sec, and frame may be too small if DVD extension is valid */
/* -1 means that only long_track_blocks is valid */
int track_blocks; int track_blocks;
/* ts A90909 : LRA extension. extensions_valid:bit1 */ /* ts A90909 : LRA extension. extensions_valid:bit1 */
@ -396,6 +403,7 @@ struct burn_toc_entry
DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R. DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R.
This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42 This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42
*/ */
/* -1 means that only long_last_rec_adr is valid */
int last_recorded_address; int last_recorded_address;
/* ts B30112 : Track status bits extension. extensions_valid:bit2 */ /* ts B30112 : Track status bits extension. extensions_valid:bit2 */
@ -415,6 +423,12 @@ struct burn_toc_entry
*/ */
int track_status_bits; int track_status_bits;
/* ts C40221 : Long block address extension. extensions_valid:bit3 */
/* @since 1.5.8 */
off_t long_start_lba;
off_t long_track_blocks;
off_t long_last_rec_adr;
}; };

View File

@ -300,6 +300,14 @@ int mmc_four_char_to_int(unsigned char *data)
} }
/* ts C40226 */
unsigned int mmc_four_char_to_uint(unsigned char *data)
{
return (((unsigned int) data[0]) << 24) | (data[1] << 16) |
(data[2] << 8) | data[3];
}
/* ts A70201 */ /* ts A70201 */
int mmc_int_to_four_char(unsigned char *data, int num) int mmc_int_to_four_char(unsigned char *data, int num)
{ {
@ -311,6 +319,17 @@ int mmc_int_to_four_char(unsigned char *data, int num)
} }
/* ts C40226 */
int mmc_uint_to_four_char(unsigned char *data, unsigned int num)
{
data[0] = (num >> 24) & 0xff;
data[1] = (num >> 16) & 0xff;
data[2] = (num >> 8) & 0xff;
data[3] = num & 0xff;
return 1;
}
static int mmc_start_for_bit0 = 0; static int mmc_start_for_bit0 = 0;
/* @param flag bit0= the calling function should need no START UNIT. /* @param flag bit0= the calling function should need no START UNIT.
@ -1087,10 +1106,11 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
unsigned char *size_data, unsigned char *start_data, unsigned char *size_data, unsigned char *start_data,
unsigned char *last_adr_data) unsigned char *last_adr_data)
{ {
int min, sec, frames, num; int min, sec, frames;
unsigned int num;
/* mark DVD extensions and Track Info extension as valid */ /* mark extensions as valid: DVD, Track Info, Long block address */
entry->extensions_valid |= (1 | 2); entry->extensions_valid |= (1 | 2 | 8);
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */ /* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
entry->session = session_number & 0xff; entry->session = session_number & 0xff;
@ -1100,9 +1120,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->tno = 0; entry->tno = 0;
entry->point = track_number & 0xff; entry->point = track_number & 0xff;
entry->point_msb = (track_number >> 8) & 0xff; entry->point_msb = (track_number >> 8) & 0xff;
num = mmc_four_char_to_int(size_data); num = mmc_four_char_to_uint(size_data);
entry->track_blocks = num; if (num < 0x80000000) {
burn_lba_to_msf(num, &min, &sec, &frames); entry->track_blocks = num;
burn_lba_to_msf(num, &min, &sec, &frames);
} else {
entry->track_blocks = -1;
min = 477218; /* ~=LBA 0x7fffffff */
sec = frames = 0;
}
entry->long_track_blocks = num;
if (min > 255) { if (min > 255) {
min = 255; min = 255;
sec = 255; sec = 255;
@ -1112,9 +1139,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->sec = sec; entry->sec = sec;
entry->frame = frames; entry->frame = frames;
entry->zero = 0; entry->zero = 0;
num = mmc_four_char_to_int(start_data); num = mmc_four_char_to_uint(start_data);
entry->start_lba = num; if (num < 0x80000000) {
burn_lba_to_msf(num, &min, &sec, &frames); entry->start_lba = num;
burn_lba_to_msf(num, &min, &sec, &frames);
} else {
entry->start_lba = -1;
min = 477218;
sec = frames = 0;
}
entry->long_start_lba = num;
if (min > 255) { if (min > 255) {
min = 255; min = 255;
sec = 255; sec = 255;
@ -1123,7 +1157,13 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->pmin = min; entry->pmin = min;
entry->psec = sec; entry->psec = sec;
entry->pframe = frames; entry->pframe = frames;
entry->last_recorded_address = mmc_four_char_to_int(last_adr_data); num = mmc_four_char_to_uint(last_adr_data);
if (num < 0x80000000) {
entry->last_recorded_address = num;
} else {
entry->last_recorded_address = -1;
}
entry->long_last_rec_adr = num;
return 1; return 1;
} }
@ -1137,7 +1177,7 @@ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
int dlen, i, old_alloc_len, session_number, prev_session = -1, ret; int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
int lba, size; unsigned int lba, size;
unsigned char *tdata, size_data[4], start_data[4], end_data[4]; unsigned char *tdata, size_data[4], start_data[4], end_data[4];
if (*alloc_len < 4) if (*alloc_len < 4)
@ -1216,11 +1256,11 @@ err_ex:;
if (session_number != prev_session && prev_session > 0) { if (session_number != prev_session && prev_session > 0) {
/* leadout entry previous session */ /* leadout entry previous session */
entry = &(d->toc_entry[(i - 1) + prev_session]); entry = &(d->toc_entry[(i - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) + lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_int(size_data); mmc_four_char_to_uint(size_data);
mmc_int_to_four_char(start_data, lba); mmc_uint_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0); mmc_uint_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1); mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2, mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data); size_data, start_data, end_data);
entry->min= entry->sec= entry->frame= 0; entry->min= entry->sec= entry->frame= 0;
@ -1245,11 +1285,11 @@ err_ex:;
memcpy(start_data, tdata + 4, 4); memcpy(start_data, tdata + 4, 4);
/* size_data are estimated from next track start */ /* size_data are estimated from next track start */
memcpy(size_data, tdata + 8 + 4, 4); memcpy(size_data, tdata + 8 + 4, 4);
mmc_int_to_four_char(end_data, mmc_uint_to_four_char(end_data,
mmc_four_char_to_int(size_data) - 1); mmc_four_char_to_uint(size_data) - 1);
size = mmc_four_char_to_int(size_data) - size = mmc_four_char_to_uint(size_data) -
mmc_four_char_to_int(start_data); mmc_four_char_to_uint(start_data);
mmc_int_to_four_char(size_data, size); mmc_uint_to_four_char(size_data, size);
mmc_fake_toc_entry(entry, session_number, i + 1, mmc_fake_toc_entry(entry, session_number, i + 1,
size_data, start_data, end_data); size_data, start_data, end_data);
if (prev_session != session_number) if (prev_session != session_number)
@ -1262,9 +1302,9 @@ err_ex:;
tdata = c->page->data + 4 + d->last_track_no * 8; tdata = c->page->data + 4 + d->last_track_no * 8;
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]); entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
memcpy(start_data, tdata + 4, 4); memcpy(start_data, tdata + 4, 4);
mmc_int_to_four_char(size_data, 0); mmc_uint_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, mmc_uint_to_four_char(end_data,
mmc_four_char_to_int(start_data) - 1); mmc_four_char_to_uint(start_data) - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2, mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data); size_data, start_data, end_data);
entry->min= entry->sec= entry->frame= 0; entry->min= entry->sec= entry->frame= 0;
@ -1301,7 +1341,8 @@ int mmc_fake_toc(struct burn_drive *d)
struct burn_session *session; struct burn_session *session;
struct burn_toc_entry *entry; struct burn_toc_entry *entry;
struct buffer *buf = NULL; struct buffer *buf = NULL;
int i, session_number, prev_session = -1, ret, lba, alloc_len = 34; int i, session_number, prev_session = -1, ret, alloc_len = 34;
unsigned int lba;
unsigned char *tdata, size_data[4], start_data[4], end_data[4]; unsigned char *tdata, size_data[4], start_data[4], end_data[4];
char *msg = NULL; char *msg = NULL;
@ -1406,11 +1447,11 @@ int mmc_fake_toc(struct burn_drive *d)
if (session_number != prev_session && prev_session > 0) { if (session_number != prev_session && prev_session > 0) {
/* leadout entry previous session */ /* leadout entry previous session */
entry = &(d->toc_entry[(i - 1) + prev_session]); entry = &(d->toc_entry[(i - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) + lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_int(size_data); mmc_four_char_to_uint(size_data);
mmc_int_to_four_char(start_data, lba); mmc_uint_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0); mmc_uint_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1); mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2, mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data); size_data, start_data, end_data);
entry->min= entry->sec= entry->frame= 0; entry->min= entry->sec= entry->frame= 0;
@ -1431,7 +1472,7 @@ int mmc_fake_toc(struct burn_drive *d)
if (i == d->last_track_no - 1) { if (i == d->last_track_no - 1) {
/* ts A70212 : Last track field Free Blocks */ /* ts A70212 : Last track field Free Blocks */
burn_drive_set_media_capacity_remaining(d, burn_drive_set_media_capacity_remaining(d,
((off_t) mmc_four_char_to_int(tdata + 16)) * ((off_t) mmc_four_char_to_uint(tdata + 16)) *
((off_t) 2048)); ((off_t) 2048));
d->media_lba_limit = 0; d->media_lba_limit = 0;
} }
@ -1477,11 +1518,11 @@ int mmc_fake_toc(struct burn_drive *d)
if (prev_session > 0 && prev_session <= d->disc->sessions) { if (prev_session > 0 && prev_session <= d->disc->sessions) {
/* leadout entry of last session of closed disc */ /* leadout entry of last session of closed disc */
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]); entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) + lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_int(size_data); mmc_four_char_to_uint(size_data);
mmc_int_to_four_char(start_data, lba); mmc_uint_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0); mmc_uint_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1); mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2, mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data); size_data, start_data, end_data);
entry->min= entry->sec= entry->frame= 0; entry->min= entry->sec= entry->frame= 0;
@ -1774,12 +1815,12 @@ void mmc_read_toc(struct burn_drive *d)
} }
/* ts A70131 : This tries to get the start of the last complete session */ /* ts C40226 : long address reply version of mmc_read_multi_session_c1 */
/* man mkisofs , option -C : /* man mkisofs , option -C :
The first number is the sector number of the first sector in The first number is the sector number of the first sector in
the last session of the disk that should be appended to. the last session of the disk that should be appended to.
*/ */
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start) int mmc_read_msc1_long(struct burn_drive *d, int *trackno, off_t *start)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
@ -1812,7 +1853,11 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
continue; continue;
burn_track_get_entry(tracks[0], &toc_entry); burn_track_get_entry(tracks[0], &toc_entry);
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */ if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
*start = toc_entry.start_lba; if (toc_entry.extensions_valid & 8) { /* Long adr */
*start = toc_entry.long_start_lba;
} else {
*start = toc_entry.start_lba;
}
*trackno = (toc_entry.point_msb << 8)| toc_entry.point; *trackno = (toc_entry.point_msb << 8)| toc_entry.point;
} else { } else {
*start = burn_msf_to_lba(toc_entry.pmin, *start = burn_msf_to_lba(toc_entry.pmin,
@ -1847,7 +1892,7 @@ inquire_drive:;
tdata = c->page->data + 4; tdata = c->page->data + 4;
*trackno = tdata[2]; *trackno = tdata[2];
*start = mmc_four_char_to_int(tdata + 4); *start = mmc_four_char_to_uint(tdata + 4);
ret = 1; ret = 1;
ex:; ex:;
BURN_FREE_MEM(buf); BURN_FREE_MEM(buf);
@ -1856,6 +1901,24 @@ ex:;
} }
/* ts A70131 : This tries to get the start of the last complete session */
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
{
int ret;
off_t num;
ret = mmc_read_msc1_long(d, trackno, &num);
if (ret <= 0)
return ret;
if(num >= 0x80000000) {
*start = 0x7fffffff;
return 0;
}
*start = num;
return 1;
}
/* ts A61201 */ /* ts A61201 */
char *mmc_obtain_profile_name(int profile_number) char *mmc_obtain_profile_name(int profile_number)
{ {

View File

@ -78,6 +78,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
/* ts A70201 */ /* ts A70201 */
int mmc_four_char_to_int(unsigned char *data); int mmc_four_char_to_int(unsigned char *data);
/* ts C40226 */
unsigned int mmc_four_char_to_uint(unsigned char *data);
/* ts A70201 : /* ts A70201 :
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc() Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()

View File

@ -768,7 +768,7 @@ int burn_session_get_hidefirst(struct burn_session *session)
} }
/* ts A80808 : Enhance CD toc to DVD toc */ /* ts A80808,C40226 : Enhance CD toc to DVD toc with Long block addresses */
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag) int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
{ {
int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34; int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
@ -836,6 +836,7 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
entry->point_msb = 0; entry->point_msb = 0;
entry->start_lba = burn_msf_to_lba(entry->pmin, entry->start_lba = burn_msf_to_lba(entry->pmin,
entry->psec, entry->pframe); entry->psec, entry->pframe);
entry->long_start_lba = entry->start_lba;
if (tidx > 0) { if (tidx > 0) {
prev_entry->track_blocks = prev_entry->track_blocks =
entry->start_lba entry->start_lba
@ -855,13 +856,16 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
ret < prev_entry->track_blocks - 2)) ret < prev_entry->track_blocks - 2))
prev_entry->track_blocks = ret; prev_entry->track_blocks = ret;
} }
prev_entry->extensions_valid |= 1; prev_entry->long_track_blocks =
prev_entry->track_blocks;
prev_entry->extensions_valid |= 1 | 8;
} }
if (tidx == d->session[sidx]->tracks) { if (tidx == d->session[sidx]->tracks) {
entry->session_msb = 0; entry->session_msb = 0;
entry->point_msb = 0; entry->point_msb = 0;
entry->track_blocks = 0; entry->track_blocks = 0;
entry->extensions_valid |= 1; entry->long_track_blocks = entry->track_blocks;
entry->extensions_valid |= 1 | 8;
} }
prev_entry = entry; prev_entry = entry;
} }