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; -*- */
/* 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.
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
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
bit1= LRA extension is valid @since 0.7.2
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;
@ -386,8 +391,10 @@ struct burn_toc_entry
unsigned char session_msb;
unsigned char point_msb;
/* 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;
/* 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;
/* 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.
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;
/* ts B30112 : Track status bits extension. extensions_valid:bit2 */
@ -415,6 +423,12 @@ struct burn_toc_entry
*/
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 */
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;
/* @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 *last_adr_data)
{
int min, sec, frames, num;
int min, sec, frames;
unsigned int num;
/* mark DVD extensions and Track Info extension as valid */
entry->extensions_valid |= (1 | 2);
/* mark extensions as valid: DVD, Track Info, Long block address */
entry->extensions_valid |= (1 | 2 | 8);
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
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->point = track_number & 0xff;
entry->point_msb = (track_number >> 8) & 0xff;
num = mmc_four_char_to_int(size_data);
num = mmc_four_char_to_uint(size_data);
if (num < 0x80000000) {
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) {
min = 255;
sec = 255;
@ -1112,9 +1139,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->sec = sec;
entry->frame = frames;
entry->zero = 0;
num = mmc_four_char_to_int(start_data);
num = mmc_four_char_to_uint(start_data);
if (num < 0x80000000) {
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) {
min = 255;
sec = 255;
@ -1123,7 +1157,13 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->pmin = min;
entry->psec = sec;
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;
}
@ -1137,7 +1177,7 @@ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
struct buffer *buf = NULL;
struct command *c = NULL;
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];
if (*alloc_len < 4)
@ -1216,11 +1256,11 @@ err_ex:;
if (session_number != prev_session && prev_session > 0) {
/* leadout entry previous session */
entry = &(d->toc_entry[(i - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) +
mmc_four_char_to_int(size_data);
mmc_int_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1);
lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_uint(size_data);
mmc_uint_to_four_char(start_data, lba);
mmc_uint_to_four_char(size_data, 0);
mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data);
entry->min= entry->sec= entry->frame= 0;
@ -1245,11 +1285,11 @@ err_ex:;
memcpy(start_data, tdata + 4, 4);
/* size_data are estimated from next track start */
memcpy(size_data, tdata + 8 + 4, 4);
mmc_int_to_four_char(end_data,
mmc_four_char_to_int(size_data) - 1);
size = mmc_four_char_to_int(size_data) -
mmc_four_char_to_int(start_data);
mmc_int_to_four_char(size_data, size);
mmc_uint_to_four_char(end_data,
mmc_four_char_to_uint(size_data) - 1);
size = mmc_four_char_to_uint(size_data) -
mmc_four_char_to_uint(start_data);
mmc_uint_to_four_char(size_data, size);
mmc_fake_toc_entry(entry, session_number, i + 1,
size_data, start_data, end_data);
if (prev_session != session_number)
@ -1262,9 +1302,9 @@ err_ex:;
tdata = c->page->data + 4 + d->last_track_no * 8;
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
memcpy(start_data, tdata + 4, 4);
mmc_int_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data,
mmc_four_char_to_int(start_data) - 1);
mmc_uint_to_four_char(size_data, 0);
mmc_uint_to_four_char(end_data,
mmc_four_char_to_uint(start_data) - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data);
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_toc_entry *entry;
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];
char *msg = NULL;
@ -1406,11 +1447,11 @@ int mmc_fake_toc(struct burn_drive *d)
if (session_number != prev_session && prev_session > 0) {
/* leadout entry previous session */
entry = &(d->toc_entry[(i - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) +
mmc_four_char_to_int(size_data);
mmc_int_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1);
lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_uint(size_data);
mmc_uint_to_four_char(start_data, lba);
mmc_uint_to_four_char(size_data, 0);
mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data);
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) {
/* ts A70212 : Last track field Free Blocks */
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));
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) {
/* leadout entry of last session of closed disc */
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
lba = mmc_four_char_to_int(start_data) +
mmc_four_char_to_int(size_data);
mmc_int_to_four_char(start_data, lba);
mmc_int_to_four_char(size_data, 0);
mmc_int_to_four_char(end_data, lba - 1);
lba = mmc_four_char_to_uint(start_data) +
mmc_four_char_to_uint(size_data);
mmc_uint_to_four_char(start_data, lba);
mmc_uint_to_four_char(size_data, 0);
mmc_uint_to_four_char(end_data, lba - 1);
mmc_fake_toc_entry(entry, prev_session, 0xA2,
size_data, start_data, end_data);
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 :
The first number is the sector number of the first sector in
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 command *c = NULL;
@ -1812,7 +1853,11 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
continue;
burn_track_get_entry(tracks[0], &toc_entry);
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
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;
} else {
*start = burn_msf_to_lba(toc_entry.pmin,
@ -1847,7 +1892,7 @@ inquire_drive:;
tdata = c->page->data + 4;
*trackno = tdata[2];
*start = mmc_four_char_to_int(tdata + 4);
*start = mmc_four_char_to_uint(tdata + 4);
ret = 1;
ex:;
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 */
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 */
int mmc_four_char_to_int(unsigned char *data);
/* ts C40226 */
unsigned int mmc_four_char_to_uint(unsigned char *data);
/* ts A70201 :
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 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->start_lba = burn_msf_to_lba(entry->pmin,
entry->psec, entry->pframe);
entry->long_start_lba = entry->start_lba;
if (tidx > 0) {
prev_entry->track_blocks =
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))
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) {
entry->session_msb = 0;
entry->point_msb = 0;
entry->track_blocks = 0;
entry->extensions_valid |= 1;
entry->long_track_blocks = entry->track_blocks;
entry->extensions_valid |= 1 | 8;
}
prev_entry = entry;
}