📄 ifo_read.c
字号:
} 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; /* Seems to be optional, at least when there are no OneSequencial Titles */ if(ifofile->vtsi_mat->vts_tmapt == 0) { ifofile->vts_tmapt = NULL; return 1; } offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN; if(!DVDFileSeek_(ifofile->file, offset)) return 0; vts_tmapt = malloc(sizeof(vts_tmapt_t)); if(!vts_tmapt) return 0; ifofile->vts_tmapt = vts_tmapt; if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) { if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) { 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 = 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))) { if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) { 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 = 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))) { if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) { 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 = 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))) { if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) { 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 = 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 = 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) { if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) { 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 = 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 = 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 = 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; /* assert(info_length > 0); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with a VOBS that has no VOBUs. */ CHECK_VALUE(info_length % sizeof(uint32_t) == 0); vobu_admap->vobu_start_sectors = malloc(info_length); if(!vobu_admap->vobu_start_sectors) { return 0; } if(info_length && !(DVDReadBytes(ifofile->file, vobu_admap->vobu_start_sectors, info_length))) { free(vobu_admap->vobu_start_sectors); return 0; } for(i = 0; i < info_length/sizeof(uint32_t); i++) B2N_32(vobu_admap->vobu_start_sectors[i]); return 1;}static void ifoFree_VOBU_ADMAP_internal(vobu_admap_t *vobu_admap) { if(vobu_admap) { free(vobu_admap->vobu_start_sectors); free(vobu_admap); }}void ifoFree_VOBU_ADMAP(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_VOBU_ADMAP_internal(ifofile->menu_vobu_admap); ifofile->menu_vobu_admap = 0;}void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_VOBU_ADMAP_internal(ifofile->vts_vobu_admap); ifofile->vts_vobu_admap = 0;}int ifoRead_PGCIT(ifo_handle_t *ifofile) { if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_pgcit == 0) /* mandatory */ return 0; ifofile->vts_pgcit = malloc(sizeof(pgcit_t)); if(!ifofile->vts_pgcit) return 0; if(!ifoRead_PGCIT_internal(ifofile, ifofile->vts_pgcit, ifofile->vtsi_mat->vts_pgcit * DVD_BLOCK_LEN)) { free(ifofile->vts_pgcit); ifofile->vts_pgcit = 0; return 0; } return 1;}static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit, unsigned int offset) { int i, info_length; uint8_t *data, *ptr; if(!DVDFileSeek_(ifofile->file, offset)) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -