📄 ifo_read.c
字号:
CHECK_ZERO(vmgi_mat->zero_5); CHECK_ZERO(vmgi_mat->zero_6); CHECK_ZERO(vmgi_mat->zero_7); CHECK_ZERO(vmgi_mat->zero_8); CHECK_ZERO(vmgi_mat->zero_9); CHECK_ZERO(vmgi_mat->zero_10); CHECK_VALUE(vmgi_mat->vmg_last_sector != 0); CHECK_VALUE(vmgi_mat->vmgi_last_sector != 0); CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector); CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector); CHECK_VALUE(vmgi_mat->vmg_nr_of_volumes != 0); CHECK_VALUE(vmgi_mat->vmg_this_volume_nr != 0); CHECK_VALUE(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes); CHECK_VALUE(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2); CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets != 0); CHECK_VALUE(vmgi_mat->vmgi_last_byte >= 341); CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <= vmgi_mat->vmgi_last_sector); /* It seems that first_play_pgc is optional. */ CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte); CHECK_VALUE(vmgi_mat->vmgm_vobs == 0 || (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector && vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector)); CHECK_VALUE(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->nr_of_vmgm_audio_streams <= 1); CHECK_VALUE(vmgi_mat->nr_of_vmgm_subp_streams <= 1); return 1;}static int ifoRead_VTS(ifo_handle_t *ifofile) { vtsi_mat_t *vtsi_mat; int i; vtsi_mat = malloc(sizeof(vtsi_mat_t)); if(!vtsi_mat) return 0; ifofile->vtsi_mat = vtsi_mat; if(!DVDFileSeek_(ifofile->file, 0)) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } if(!(DVDReadBytes(ifofile->file, vtsi_mat, sizeof(vtsi_mat_t)))) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } if(strncmp("DVDVIDEO-VTS", vtsi_mat->vts_identifier, 12) != 0) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } B2N_32(vtsi_mat->vts_last_sector); B2N_32(vtsi_mat->vtsi_last_sector); B2N_32(vtsi_mat->vts_category); B2N_32(vtsi_mat->vtsi_last_byte); B2N_32(vtsi_mat->vtsm_vobs); B2N_32(vtsi_mat->vtstt_vobs); B2N_32(vtsi_mat->vts_ptt_srpt); B2N_32(vtsi_mat->vts_pgcit); B2N_32(vtsi_mat->vtsm_pgci_ut); B2N_32(vtsi_mat->vts_tmapt); B2N_32(vtsi_mat->vtsm_c_adt); B2N_32(vtsi_mat->vtsm_vobu_admap); B2N_32(vtsi_mat->vts_c_adt); B2N_32(vtsi_mat->vts_vobu_admap); B2N_16(vtsi_mat->vtsm_audio_attr.lang_code); B2N_16(vtsi_mat->vtsm_subp_attr.lang_code); for(i = 0; i < 8; i++) B2N_16(vtsi_mat->vts_audio_attr[i].lang_code); for(i = 0; i < 32; i++) B2N_16(vtsi_mat->vts_subp_attr[i].lang_code); CHECK_ZERO(vtsi_mat->zero_1); CHECK_ZERO(vtsi_mat->zero_2); CHECK_ZERO(vtsi_mat->zero_3); CHECK_ZERO(vtsi_mat->zero_4); CHECK_ZERO(vtsi_mat->zero_5); CHECK_ZERO(vtsi_mat->zero_6); CHECK_ZERO(vtsi_mat->zero_7); CHECK_ZERO(vtsi_mat->zero_8); CHECK_ZERO(vtsi_mat->zero_9); CHECK_ZERO(vtsi_mat->zero_10); CHECK_ZERO(vtsi_mat->zero_11); CHECK_ZERO(vtsi_mat->zero_12); CHECK_ZERO(vtsi_mat->zero_13); CHECK_ZERO(vtsi_mat->zero_14); CHECK_ZERO(vtsi_mat->zero_15); CHECK_ZERO(vtsi_mat->zero_16); CHECK_ZERO(vtsi_mat->zero_17); CHECK_ZERO(vtsi_mat->zero_18); CHECK_ZERO(vtsi_mat->zero_19); CHECK_ZERO(vtsi_mat->zero_20); CHECK_ZERO(vtsi_mat->zero_21); CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector); CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_vobs == 0 || (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector && vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector)); CHECK_VALUE(vtsi_mat->vtstt_vobs == 0 || (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector && vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector)); CHECK_VALUE(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->nr_of_vtsm_audio_streams <= 1); CHECK_VALUE(vtsi_mat->nr_of_vtsm_subp_streams <= 1); CHECK_VALUE(vtsi_mat->nr_of_vts_audio_streams <= 8); for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++) CHECK_ZERO(vtsi_mat->vts_audio_attr[i]); CHECK_VALUE(vtsi_mat->nr_of_vts_subp_streams <= 32); for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++) CHECK_ZERO(vtsi_mat->vts_subp_attr[i]); for(i = 0; i < 8; i++) { CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero4); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero5); CHECK_ZERO(vtsi_mat->vts_mu_audio_attr[i].zero6); } return 1;}static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile, pgc_command_tbl_t *cmd_tbl, unsigned int offset) { unsigned int total; memset(cmd_tbl, 0, sizeof(pgc_command_tbl_t)); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cmd_tbl, PGC_COMMAND_TBL_SIZE))) return 0; B2N_16(cmd_tbl->nr_of_pre); B2N_16(cmd_tbl->nr_of_post); B2N_16(cmd_tbl->nr_of_cell); B2N_16(cmd_tbl->last_byte); total = cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell; CHECK_VALUE(PGC_COMMAND_TBL_SIZE + total * COMMAND_DATA_SIZE <= cmd_tbl->last_byte + 1U); CHECK_VALUE(total <= 255); if(cmd_tbl->nr_of_pre != 0) { unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE; cmd_tbl->pre_cmds = malloc(pre_cmds_size); if(!cmd_tbl->pre_cmds) return 0; if(!(DVDReadBytes(ifofile->file, cmd_tbl->pre_cmds, pre_cmds_size))) { free(cmd_tbl->pre_cmds); return 0; } } if(cmd_tbl->nr_of_post != 0) { unsigned int post_cmds_size = cmd_tbl->nr_of_post * COMMAND_DATA_SIZE; cmd_tbl->post_cmds = malloc(post_cmds_size); if(!cmd_tbl->post_cmds) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); return 0; } if(!(DVDReadBytes(ifofile->file, cmd_tbl->post_cmds, post_cmds_size))) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); free(cmd_tbl->post_cmds); return 0; } } if(cmd_tbl->nr_of_cell != 0) { unsigned int cell_cmds_size = cmd_tbl->nr_of_cell * COMMAND_DATA_SIZE; cmd_tbl->cell_cmds = malloc(cell_cmds_size); if(!cmd_tbl->cell_cmds) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); return 0; } if(!(DVDReadBytes(ifofile->file, cmd_tbl->cell_cmds, cell_cmds_size))) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); free(cmd_tbl->cell_cmds); return 0; } } /* * Make a run over all the commands and see that we can interpret them all? */ return 1;}static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) { if(cmd_tbl) { if(cmd_tbl->nr_of_pre && cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->nr_of_post && cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); if(cmd_tbl->nr_of_cell && cmd_tbl->cell_cmds) free(cmd_tbl->cell_cmds); free(cmd_tbl); }}static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile, pgc_program_map_t *program_map, unsigned int nr, unsigned int offset) { unsigned int size = nr * sizeof(pgc_program_map_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, program_map, size))) return 0; return 1;}static int ifoRead_CELL_PLAYBACK_TBL(ifo_handle_t *ifofile, cell_playback_t *cell_playback, unsigned int nr, unsigned int offset) { unsigned int i; unsigned int size = nr * sizeof(cell_playback_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cell_playback, size))) return 0; for(i = 0; i < nr; i++) { B2N_32(cell_playback[i].first_sector); B2N_32(cell_playback[i].first_ilvu_end_sector); B2N_32(cell_playback[i].last_vobu_start_sector); B2N_32(cell_playback[i].last_sector); /* Changed < to <= because this was false in the movie 'Pi'. */ CHECK_VALUE(cell_playback[i].last_vobu_start_sector <= cell_playback[i].last_sector); CHECK_VALUE(cell_playback[i].first_sector <= cell_playback[i].last_vobu_start_sector); } return 1;}static int ifoRead_CELL_POSITION_TBL(ifo_handle_t *ifofile, cell_position_t *cell_position, unsigned int nr, unsigned int offset) { unsigned int i; unsigned int size = nr * sizeof(cell_position_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cell_position, size))) return 0; for(i = 0; i < nr; i++) { B2N_16(cell_position[i].vob_id_nr); CHECK_ZERO(cell_position[i].zero_1); } return 1;}static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int offset) { unsigned int i; if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, pgc, PGC_SIZE))) return 0; B2N_16(pgc->next_pgc_nr); B2N_16(pgc->prev_pgc_nr); B2N_16(pgc->goup_pgc_nr); B2N_16(pgc->command_tbl_offset); B2N_16(pgc->program_map_offset); B2N_16(pgc->cell_playback_offset); B2N_16(pgc->cell_position_offset); for(i = 0; i < 16; i++) B2N_32(pgc->palette[i]); CHECK_ZERO(pgc->zero_1); CHECK_VALUE(pgc->nr_of_programs <= pgc->nr_of_cells); /* verify time (look at print_time) */ for(i = 0; i < 8; i++) if(!pgc->audio_control[i].present) CHECK_ZERO(pgc->audio_control[i]); for(i = 0; i < 32; i++) if(!pgc->subp_control[i].present) CHECK_ZERO(pgc->subp_control[i]); /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */ if(pgc->nr_of_programs == 0) { CHECK_ZERO(pgc->still_time); CHECK_ZERO(pgc->pg_playback_mode); // ?? CHECK_VALUE(pgc->program_map_offset == 0); CHECK_VALUE(pgc->cell_playback_offset == 0); CHECK_VALUE(pgc->cell_position_offset == 0); } else { CHECK_VALUE(pgc->program_map_offset != 0); CHECK_VALUE(pgc->cell_playback_offset != 0); CHECK_VALUE(pgc->cell_position_offset != 0); } if(pgc->command_tbl_offset != 0) { pgc->command_tbl = malloc(sizeof(pgc_command_tbl_t)); if(!pgc->command_tbl) return 0; if(!ifoRead_PGC_COMMAND_TBL(ifofile, pgc->command_tbl, offset + pgc->command_tbl_offset)) { free(pgc->command_tbl); return 0; } } else { pgc->command_tbl = NULL; } if(pgc->program_map_offset != 0) { if(pgc->nr_of_programs != 0) { pgc->program_map = malloc(pgc->nr_of_programs * sizeof(pgc_program_map_t)); if(!pgc->program_map) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); return 0; } if(!ifoRead_PGC_PROGRAM_MAP(ifofile, pgc->program_map,pgc->nr_of_programs, offset + pgc->program_map_offset)) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); free(pgc->program_map); return 0; } } else { pgc->program_map = NULL; } } else { pgc->program_map = NULL; } if(pgc->cell_playback_offset != 0) { if(pgc->nr_of_cells != 0) { pgc->cell_playback = malloc(pgc->nr_of_cells * sizeof(cell_playback_t)); if(!pgc->cell_playback) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); if(pgc->program_map) free(pgc->program_map); return 0; } if(!ifoRead_CELL_PLAYBACK_TBL(ifofile, pgc->cell_playback, pgc->nr_of_cells, offset + pgc->cell_playback_offset)) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); if(pgc->program_map) free(pgc->program_map); free(pgc->cell_playback); return 0; } } else { pgc->cell_playback = NULL; } } else { pgc->cell_playback = NULL; } if(pgc->cell_position_offset != 0) { if(pgc->nr_of_cells != 0) { pgc->cell_position = malloc(pgc->nr_of_cells * sizeof(cell_position_t)); if(!pgc->cell_position) { ifoFree_PGC(pgc); return 0; } if(!ifoRead_CELL_POSITION_TBL(ifofile, pgc->cell_position, pgc->nr_of_cells, offset + pgc->cell_position_offset)) { ifoFree_PGC(pgc); return 0; } } else { pgc->cell_position = NULL; } } else { pgc->cell_position = NULL; } return 1;}int ifoRead_FP_PGC(ifo_handle_t *ifofile) { if(!ifofile) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -