📄 ifo_read.c
字号:
}
}
return 1;
}
void ifoFree_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
if(!ifofile)
return;
if(ifofile->vts_ptt_srpt) {
int i;
for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++)
free(ifofile->vts_ptt_srpt->title[i].ptt);
free(ifofile->vts_ptt_srpt->ttu_offset);
free(ifofile->vts_ptt_srpt->title);
free(ifofile->vts_ptt_srpt);
ifofile->vts_ptt_srpt = 0;
}
}
int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
ptl_mait_t *ptl_mait;
int info_length;
unsigned int i, j;
if(!ifofile)
return 0;
if(!ifofile->vmgi_mat)
return 0;
if(ifofile->vmgi_mat->ptl_mait == 0)
return 1;
if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
return 0;
ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t));
if(!ptl_mait)
return 0;
ifofile->ptl_mait = ptl_mait;
if(!(DVDReadBytes(ifofile->file, ptl_mait, PTL_MAIT_SIZE))) {
free(ptl_mait);
ifofile->ptl_mait = 0;
return 0;
}
B2N_16(ptl_mait->nr_of_countries);
B2N_16(ptl_mait->nr_of_vtss);
B2N_32(ptl_mait->last_byte);
CHECK_VALUE(ptl_mait->nr_of_countries != 0);
CHECK_VALUE(ptl_mait->nr_of_countries < 100); // ??
CHECK_VALUE(ptl_mait->nr_of_vtss != 0);
CHECK_VALUE(ptl_mait->nr_of_vtss < 100); // ??
CHECK_VALUE((int)ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE
<= (int)ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
info_length = ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t);
ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length);
if(!ptl_mait->countries) {
free(ptl_mait);
ifofile->ptl_mait = 0;
return 0;
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) {
fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
free(ptl_mait->countries);
free(ptl_mait);
ifofile->ptl_mait = 0;
return 0;
}
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
B2N_16(ptl_mait->countries[i].country_code);
B2N_16(ptl_mait->countries[i].pf_ptl_mai_start_byte);
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
CHECK_ZERO(ptl_mait->countries[i].zero_1);
CHECK_ZERO(ptl_mait->countries[i].zero_2);
CHECK_VALUE((int)ptl_mait->countries[i].pf_ptl_mai_start_byte
+ 8*2 * (ptl_mait->nr_of_vtss + 1) <= (int)ptl_mait->last_byte + 1);
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
uint16_t *pf_temp;
if(!DVDFileSeek_(ifofile->file,
ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
+ ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
free(ptl_mait->countries);
free(ptl_mait);
return 0;
}
info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
pf_temp = (uint16_t *)malloc(info_length);
if(!pf_temp) {
for(j = 0; j < i ; j++) {
free(ptl_mait->countries[j].pf_ptl_mai);
}
free(ptl_mait->countries);
free(ptl_mait);
return 0;
}
if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
free(pf_temp);
for(j = 0; j < i ; j++) {
free(ptl_mait->countries[j].pf_ptl_mai);
}
free(ptl_mait->countries);
free(ptl_mait);
return 0;
}
for (j = 0; j < (unsigned int)((ptl_mait->nr_of_vtss + 1) * 8); j++) {
B2N_16(pf_temp[j]);
}
ptl_mait->countries[i].pf_ptl_mai = (pf_level_t *)malloc(info_length);
if(!ptl_mait->countries[i].pf_ptl_mai) {
free(pf_temp);
for(j = 0; j < i ; j++) {
free(ptl_mait->countries[j].pf_ptl_mai);
}
free(ptl_mait->countries);
free(ptl_mait);
return 0;
}
{ /* Transpose the array so we can use C indexing. */
int level, vts;
for(level = 0; level < 8; level++) {
for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
ptl_mait->countries[i].pf_ptl_mai[vts][level] =
pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
}
}
free(pf_temp);
}
}
return 1;
}
void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) {
unsigned int i;
if(!ifofile)
return;
if(ifofile->ptl_mait) {
for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
}
free(ifofile->ptl_mait->countries);
free(ifofile->ptl_mait);
ifofile->ptl_mait = 0;
}
}
int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) {
vts_tmapt_t *vts_tmapt;
uint32_t *vts_tmap_srp;
unsigned int offset;
int info_length;
unsigned int i, j;
if(!ifofile)
return 0;
if(!ifofile->vtsi_mat)
return 0;
if(ifofile->vtsi_mat->vts_tmapt == 0) { /* optional(?) */
ifofile->vts_tmapt = NULL;
fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n");
return 1;
}
offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN;
if(!DVDFileSeek_(ifofile->file, offset))
return 0;
vts_tmapt = (vts_tmapt_t *)malloc(sizeof(vts_tmapt_t));
if(!vts_tmapt)
return 0;
ifofile->vts_tmapt = vts_tmapt;
if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) {
fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
free(vts_tmapt);
ifofile->vts_tmapt = NULL;
return 0;
}
B2N_16(vts_tmapt->nr_of_tmaps);
B2N_32(vts_tmapt->last_byte);
CHECK_ZERO(vts_tmapt->zero_1);
info_length = vts_tmapt->nr_of_tmaps * 4;
vts_tmap_srp = (uint32_t *)malloc(info_length);
if(!vts_tmap_srp) {
free(vts_tmapt);
ifofile->vts_tmapt = NULL;
return 0;
}
vts_tmapt->tmap_offset = vts_tmap_srp;
if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) {
fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
free(vts_tmap_srp);
free(vts_tmapt);
ifofile->vts_tmapt = NULL;
return 0;
}
for (i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
B2N_32(vts_tmap_srp[i]);
}
info_length = vts_tmapt->nr_of_tmaps * sizeof(vts_tmap_t);
vts_tmapt->tmap = (vts_tmap_t *)malloc(info_length);
if(!vts_tmapt->tmap) {
free(vts_tmap_srp);
free(vts_tmapt);
ifofile->vts_tmapt = NULL;
return 0;
}
memset(vts_tmapt->tmap, 0, info_length); /* So ifoFree_VTS_TMAPT works. */
for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
if(!DVDFileSeek_(ifofile->file, offset + vts_tmap_srp[i])) {
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE))) {
fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n");
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
B2N_16(vts_tmapt->tmap[i].nr_of_entries);
CHECK_ZERO(vts_tmapt->tmap[i].zero_1);
if(vts_tmapt->tmap[i].nr_of_entries == 0) { /* Early out if zero entries */
vts_tmapt->tmap[i].map_ent = NULL;
continue;
}
info_length = vts_tmapt->tmap[i].nr_of_entries * sizeof(map_ent_t);
vts_tmapt->tmap[i].map_ent = (map_ent_t *)malloc(info_length);
if(!vts_tmapt->tmap[i].map_ent) {
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_length))) {
fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
ifoFree_VTS_TMAPT(ifofile);
return 0;
}
for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++)
B2N_32(vts_tmapt->tmap[i].map_ent[j]);
}
return 1;
}
void ifoFree_VTS_TMAPT(ifo_handle_t *ifofile) {
unsigned int i;
if(!ifofile)
return;
if(ifofile->vts_tmapt) {
for(i = 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++)
if(ifofile->vts_tmapt->tmap[i].map_ent)
free(ifofile->vts_tmapt->tmap[i].map_ent);
free(ifofile->vts_tmapt->tmap);
free(ifofile->vts_tmapt->tmap_offset);
free(ifofile->vts_tmapt);
ifofile->vts_tmapt = NULL;
}
}
int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) {
if(!ifofile)
return 0;
if(!ifofile->vtsi_mat)
return 0;
if(ifofile->vtsi_mat->vts_c_adt == 0) /* mandatory */
return 0;
ifofile->vts_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t));
if(!ifofile->vts_c_adt)
return 0;
if(!ifoRead_C_ADT_internal(ifofile, ifofile->vts_c_adt,
ifofile->vtsi_mat->vts_c_adt)) {
free(ifofile->vts_c_adt);
ifofile->vts_c_adt = 0;
return 0;
}
return 1;
}
int ifoRead_C_ADT(ifo_handle_t *ifofile) {
unsigned int sector;
if(!ifofile)
return 0;
if(ifofile->vmgi_mat) {
if(ifofile->vmgi_mat->vmgm_c_adt == 0)
return 1;
sector = ifofile->vmgi_mat->vmgm_c_adt;
} else if(ifofile->vtsi_mat) {
if(ifofile->vtsi_mat->vtsm_c_adt == 0)
return 1;
sector = ifofile->vtsi_mat->vtsm_c_adt;
} else {
return 0;
}
ifofile->menu_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t));
if(!ifofile->menu_c_adt)
return 0;
if(!ifoRead_C_ADT_internal(ifofile, ifofile->menu_c_adt, sector)) {
free(ifofile->menu_c_adt);
ifofile->menu_c_adt = 0;
return 0;
}
return 1;
}
static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile,
c_adt_t *c_adt, unsigned int sector) {
int i, info_length;
if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
return 0;
if(!(DVDReadBytes(ifofile->file, c_adt, C_ADT_SIZE)))
return 0;
B2N_16(c_adt->nr_of_vobs);
B2N_32(c_adt->last_byte);
info_length = c_adt->last_byte + 1 - C_ADT_SIZE;
CHECK_ZERO(c_adt->zero_1);
/* assert(c_adt->nr_of_vobs > 0);
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with a VOBS that has no cells. */
CHECK_VALUE(info_length % sizeof(cell_adr_t) == 0);
/* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs);
Enemy of the State region 2 (de) has Titles where nr_of_vobs field
is to high, they high ones are never referenced though. */
if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) {
fprintf(stderr, "libdvdread: *C_ADT nr_of_vobs > avaiable info entries\n");
c_adt->nr_of_vobs = info_length / sizeof(cell_adr_t);
}
c_adt->cell_adr_table = (cell_adr_t *)malloc(info_length);
if(!c_adt->cell_adr_table)
return 0;
if(info_length &&
!(DVDReadBytes(ifofile->file, c_adt->cell_adr_table, info_length))) {
free(c_adt->cell_adr_table);
return 0;
}
for(i = 0; i < (int)( info_length/sizeof(cell_adr_t)); i++) {
B2N_16(c_adt->cell_adr_table[i].vob_id);
B2N_32(c_adt->cell_adr_table[i].start_sector);
B2N_32(c_adt->cell_adr_table[i].last_sector);
CHECK_ZERO(c_adt->cell_adr_table[i].zero_1);
CHECK_VALUE(c_adt->cell_adr_table[i].vob_id > 0);
CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs);
CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0);
CHECK_VALUE(c_adt->cell_adr_table[i].start_sector <
c_adt->cell_adr_table[i].last_sector);
}
return 1;
}
static void ifoFree_C_ADT_internal(c_adt_t *c_adt) {
if(c_adt) {
free(c_adt->cell_adr_table);
free(c_adt);
}
}
void ifoFree_C_ADT(ifo_handle_t *ifofile) {
if(!ifofile)
return;
ifoFree_C_ADT_internal(ifofile->menu_c_adt);
ifofile->menu_c_adt = 0;
}
void ifoFree_TITLE_C_ADT(ifo_handle_t *ifofile) {
if(!ifofile)
return;
ifoFree_C_ADT_internal(ifofile->vts_c_adt);
ifofile->vts_c_adt = 0;
}
int ifoRead_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) {
if(!ifofile)
return 0;
if(!ifofile->vtsi_mat)
return 0;
if(ifofile->vtsi_mat->vts_vobu_admap == 0) /* mandatory */
return 0;
ifofile->vts_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t));
if(!ifofile->vts_vobu_admap)
return 0;
if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->vts_vobu_admap,
ifofile->vtsi_mat->vts_vobu_admap)) {
free(ifofile->vts_vobu_admap);
ifofile->vts_vobu_admap = 0;
return 0;
}
return 1;
}
int ifoRead_VOBU_ADMAP(ifo_handle_t *ifofile) {
unsigned int sector;
if(!ifofile)
return 0;
if(ifofile->vmgi_mat) {
if(ifofile->vmgi_mat->vmgm_vobu_admap == 0)
return 1;
sector = ifofile->vmgi_mat->vmgm_vobu_admap;
} else if(ifofile->vtsi_mat) {
if(ifofile->vtsi_mat->vtsm_vobu_admap == 0)
return 1;
sector = ifofile->vtsi_mat->vtsm_vobu_admap;
} else {
return 0;
}
ifofile->menu_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t));
if(!ifofile->menu_vobu_admap)
return 0;
if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->menu_vobu_admap, sector)) {
free(ifofile->menu_vobu_admap);
ifofile->menu_vobu_admap = 0;
return 0;
}
return 1;
}
static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,
vobu_admap_t *vobu_admap,
unsigned int sector) {
unsigned int i;
int info_length;
if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
return 0;
if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE)))
return 0;
B2N_32(vobu_admap->last_byte);
info_length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -