📄 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(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE <= 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(ptl_mait->countries[i].pf_ptl_mai_start_byte + 8*2 * (ptl_mait->nr_of_vtss + 1) <= 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 < ((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 < 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 + -