comparison libmpdvdkit2/ifo_read.c @ 15874:483e955893b8

update libdvdread to v0.9.4
author aurel
date Thu, 30 Jun 2005 22:48:26 +0000
parents 25df9508f9a8
children e1d6fbd607e0
comparison
equal deleted inserted replaced
15873:276da0bb6207 15874:483e955893b8
1 /* 1 /*
2 * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>, 2 * Copyright (C) 2000, 2001, 2002, 2003
3 * Håkan Hjort <d95hjort@dtek.chalmers.se> 3 * Björn Englund <d4bjorn@dtek.chalmers.se>,
4 * 4 * Håkan Hjort <d95hjort@dtek.chalmers.se>
5 * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
6 * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
7 * $Id$
8 * 5 *
9 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version. 9 * (at your option) any later version.
19 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 19 */
23 20
21 #include "config.h"
22
24 #include <stdio.h> 23 #include <stdio.h>
25 #include <stdlib.h> 24 #include <stdlib.h>
26 #include <unistd.h>
27 #include <inttypes.h> 25 #include <inttypes.h>
28 #include <string.h> 26 #include <string.h>
29 //#include <assert.h> 27
30
31 #include "dvd_reader.h"
32
33 #include "config.h" // Needed for WORDS_BIGENDIAN
34 #include "bswap.h" 28 #include "bswap.h"
35 #include "ifo_types.h" 29 #include "ifo_types.h"
36 #include "ifo_read.h" 30 #include "ifo_read.h"
31 #include "dvd_reader.h"
32 #include "dvdread_internal.h"
37 33
38 #ifndef DVD_BLOCK_LEN 34 #ifndef DVD_BLOCK_LEN
39 #define DVD_BLOCK_LEN 2048 35 #define DVD_BLOCK_LEN 2048
40 #endif 36 #endif
41 37
42 #ifndef NDEBUG 38 #ifndef NDEBUG
39 #define CHECK_ZERO0(arg) \
40 if(arg != 0) { \
41 fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x%x\n", \
42 __FILE__, __LINE__, # arg, arg); \
43 }
43 #define CHECK_ZERO(arg) \ 44 #define CHECK_ZERO(arg) \
44 if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \ 45 if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \
45 unsigned int i_CZ; \ 46 unsigned int i_CZ; \
46 fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x", \ 47 fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x", \
47 __FILE__, __LINE__, # arg ); \ 48 __FILE__, __LINE__, # arg ); \
49 fprintf(stderr, "%02x", *((uint8_t *)&arg + i_CZ)); \ 50 fprintf(stderr, "%02x", *((uint8_t *)&arg + i_CZ)); \
50 fprintf(stderr, "\n"); \ 51 fprintf(stderr, "\n"); \
51 } 52 }
52 static const uint8_t my_friendly_zeros[2048]; 53 static const uint8_t my_friendly_zeros[2048];
53 #else 54 #else
55 #define CHECK_ZERO0(arg) (void)(arg)
54 #define CHECK_ZERO(arg) (void)(arg) 56 #define CHECK_ZERO(arg) (void)(arg)
55 #endif 57 #endif
56 58
57 59
58 /* Prototypes for internal functions */ 60 /* Prototypes for internal functions */
85 static void ifoFree_PGC(pgc_t *pgc); 87 static void ifoFree_PGC(pgc_t *pgc);
86 static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl); 88 static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl);
87 static void ifoFree_PGCIT_internal(pgcit_t *pgcit); 89 static void ifoFree_PGCIT_internal(pgcit_t *pgcit);
88 90
89 91
90 static int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) { 92 static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
91 return (DVDFileSeek(dvd_file, (int)offset) == (int)offset); 93 return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
92 } 94 }
93 95
94 96
95 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { 97 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
100 return 0; 102 return 0;
101 103
102 memset(ifofile, 0, sizeof(ifo_handle_t)); 104 memset(ifofile, 0, sizeof(ifo_handle_t));
103 105
104 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); 106 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
107 if(!ifofile->file) /* Should really catch any error and try to fallback */
108 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
105 if(!ifofile->file) { 109 if(!ifofile->file) {
106 if(title) { 110 if(title) {
107 fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title); 111 fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
108 } else { 112 } else {
109 fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n"); 113 fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
148 return 0; 152 return 0;
149 } 153 }
150 154
151 155
152 ifoRead_PGCI_UT(ifofile); 156 ifoRead_PGCI_UT(ifofile);
157 ifoRead_VTS_TMAPT(ifofile);
153 ifoRead_C_ADT(ifofile); 158 ifoRead_C_ADT(ifofile);
154 ifoRead_VOBU_ADMAP(ifofile); 159 ifoRead_VOBU_ADMAP(ifofile);
155 160
156 if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) { 161 if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) {
157 fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", 162 fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n",
182 return 0; 187 return 0;
183 188
184 memset(ifofile, 0, sizeof(ifo_handle_t)); 189 memset(ifofile, 0, sizeof(ifo_handle_t));
185 190
186 ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE); 191 ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE);
192 if(!ifofile->file) /* Should really catch any error and try to fallback */
193 ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
187 if(!ifofile->file) { 194 if(!ifofile->file) {
188 fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n"); 195 fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
189 free(ifofile); 196 free(ifofile);
190 return 0; 197 return 0;
191 } 198 }
213 free(ifofile); 220 free(ifofile);
214 return 0; 221 return 0;
215 } 222 }
216 223
217 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); 224 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
225 if(!ifofile->file) /* Should really catch any error and try to fallback */
226 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
218 if(!ifofile->file) { 227 if(!ifofile->file) {
219 fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title); 228 fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
220 free(ifofile); 229 free(ifofile);
221 return 0; 230 return 0;
222 } 231 }
318 CHECK_ZERO(vmgi_mat->zero_6); 327 CHECK_ZERO(vmgi_mat->zero_6);
319 CHECK_ZERO(vmgi_mat->zero_7); 328 CHECK_ZERO(vmgi_mat->zero_7);
320 CHECK_ZERO(vmgi_mat->zero_8); 329 CHECK_ZERO(vmgi_mat->zero_8);
321 CHECK_ZERO(vmgi_mat->zero_9); 330 CHECK_ZERO(vmgi_mat->zero_9);
322 CHECK_ZERO(vmgi_mat->zero_10); 331 CHECK_ZERO(vmgi_mat->zero_10);
323 assert(vmgi_mat->vmg_last_sector != 0); 332 CHECK_VALUE(vmgi_mat->vmg_last_sector != 0);
324 assert(vmgi_mat->vmgi_last_sector != 0); 333 CHECK_VALUE(vmgi_mat->vmgi_last_sector != 0);
325 assert(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector); 334 CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
326 assert(vmgi_mat->vmg_nr_of_volumes != 0); 335 CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
327 assert(vmgi_mat->vmg_this_volume_nr != 0); 336 CHECK_VALUE(vmgi_mat->vmg_nr_of_volumes != 0);
328 assert(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes); 337 CHECK_VALUE(vmgi_mat->vmg_this_volume_nr != 0);
329 assert(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2); 338 CHECK_VALUE(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes);
330 assert(vmgi_mat->vmg_nr_of_title_sets != 0); 339 CHECK_VALUE(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2);
331 assert(vmgi_mat->vmgi_last_byte >= 341); 340 CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets != 0);
332 assert(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <= 341 CHECK_VALUE(vmgi_mat->vmgi_last_byte >= 341);
342 CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <=
333 vmgi_mat->vmgi_last_sector); 343 vmgi_mat->vmgi_last_sector);
334 /* It seems that first_play_pgc might be optional. */ 344 /* It seems that first_play_pgc is optional. */
335 assert(vmgi_mat->first_play_pgc != 0 && 345 CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte);
336 vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte); 346 CHECK_VALUE(vmgi_mat->vmgm_vobs == 0 ||
337 assert(vmgi_mat->vmgm_vobs == 0 ||
338 (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector && 347 (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector &&
339 vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector)); 348 vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector));
340 assert(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector); 349 CHECK_VALUE(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector);
341 assert(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector); 350 CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector);
342 assert(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector); 351 CHECK_VALUE(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector);
343 assert(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector); 352 CHECK_VALUE(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector);
344 assert(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector); 353 CHECK_VALUE(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector);
345 assert(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector); 354 CHECK_VALUE(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector);
346 assert(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector); 355 CHECK_VALUE(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector);
347 356
348 assert(vmgi_mat->nr_of_vmgm_audio_streams <= 1); 357 CHECK_VALUE(vmgi_mat->nr_of_vmgm_audio_streams <= 1);
349 assert(vmgi_mat->nr_of_vmgm_subp_streams <= 1); 358 CHECK_VALUE(vmgi_mat->nr_of_vmgm_subp_streams <= 1);
350 359
351 return 1; 360 return 1;
352 } 361 }
353 362
354 363
420 CHECK_ZERO(vtsi_mat->zero_16); 429 CHECK_ZERO(vtsi_mat->zero_16);
421 CHECK_ZERO(vtsi_mat->zero_17); 430 CHECK_ZERO(vtsi_mat->zero_17);
422 CHECK_ZERO(vtsi_mat->zero_18); 431 CHECK_ZERO(vtsi_mat->zero_18);
423 CHECK_ZERO(vtsi_mat->zero_19); 432 CHECK_ZERO(vtsi_mat->zero_19);
424 CHECK_ZERO(vtsi_mat->zero_20); 433 CHECK_ZERO(vtsi_mat->zero_20);
425 assert(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector); 434 CHECK_ZERO(vtsi_mat->zero_21);
426 assert(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector); 435 CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector);
427 assert(vtsi_mat->vtsm_vobs == 0 || 436 CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector);
428 (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector && 437 CHECK_VALUE(vtsi_mat->vtsm_vobs == 0 ||
438 (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
429 vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector)); 439 vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector));
430 assert(vtsi_mat->vtstt_vobs == 0 || 440 CHECK_VALUE(vtsi_mat->vtstt_vobs == 0 ||
431 (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector && 441 (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector &&
432 vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector)); 442 vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector));
433 assert(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector); 443 CHECK_VALUE(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector);
434 assert(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector); 444 CHECK_VALUE(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector);
435 assert(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector); 445 CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector);
436 assert(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector); 446 CHECK_VALUE(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector);
437 assert(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector); 447 CHECK_VALUE(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector);
438 assert(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector); 448 CHECK_VALUE(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector);
439 assert(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector); 449 CHECK_VALUE(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector);
440 assert(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector); 450 CHECK_VALUE(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector);
441 451
442 assert(vtsi_mat->nr_of_vtsm_audio_streams <= 1); 452 CHECK_VALUE(vtsi_mat->nr_of_vtsm_audio_streams <= 1);
443 assert(vtsi_mat->nr_of_vtsm_subp_streams <= 1); 453 CHECK_VALUE(vtsi_mat->nr_of_vtsm_subp_streams <= 1);
444 454
445 assert(vtsi_mat->nr_of_vts_audio_streams <= 8); 455 CHECK_VALUE(vtsi_mat->nr_of_vts_audio_streams <= 8);
446 for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++) 456 for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++)
447 CHECK_ZERO(vtsi_mat->vts_audio_attr[i]); 457 CHECK_ZERO(vtsi_mat->vts_audio_attr[i]);
448 458
449 assert(vtsi_mat->nr_of_vts_subp_streams <= 32); 459 CHECK_VALUE(vtsi_mat->nr_of_vts_subp_streams <= 32);
450 for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++) 460 for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++)
451 CHECK_ZERO(vtsi_mat->vts_subp_attr[i]); 461 CHECK_ZERO(vtsi_mat->vts_subp_attr[i]);
452 462
463 for(i = 0; i < 8; i++) {
464 CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1);
465 CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2);
466 CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3);
467 CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero4);
468 CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero5);
469 CHECK_ZERO(vtsi_mat->vts_mu_audio_attr[i].zero6);
470 }
471
453 return 1; 472 return 1;
454 } 473 }
455 474
456 475
457 static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile, 476 static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile,
468 487
469 B2N_16(cmd_tbl->nr_of_pre); 488 B2N_16(cmd_tbl->nr_of_pre);
470 B2N_16(cmd_tbl->nr_of_post); 489 B2N_16(cmd_tbl->nr_of_post);
471 B2N_16(cmd_tbl->nr_of_cell); 490 B2N_16(cmd_tbl->nr_of_cell);
472 491
473 assert(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell<= 255); 492 CHECK_VALUE(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell<= 255);
474 493
475 if(cmd_tbl->nr_of_pre != 0) { 494 if(cmd_tbl->nr_of_pre != 0) {
476 unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE; 495 unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE;
477 cmd_tbl->pre_cmds = (vm_cmd_t *)malloc(pre_cmds_size); 496 cmd_tbl->pre_cmds = (vm_cmd_t *)malloc(pre_cmds_size);
478 if(!cmd_tbl->pre_cmds) 497 if(!cmd_tbl->pre_cmds)
570 B2N_32(cell_playback[i].first_ilvu_end_sector); 589 B2N_32(cell_playback[i].first_ilvu_end_sector);
571 B2N_32(cell_playback[i].last_vobu_start_sector); 590 B2N_32(cell_playback[i].last_vobu_start_sector);
572 B2N_32(cell_playback[i].last_sector); 591 B2N_32(cell_playback[i].last_sector);
573 592
574 /* Changed < to <= because this was false in the movie 'Pi'. */ 593 /* Changed < to <= because this was false in the movie 'Pi'. */
575 assert(cell_playback[i].last_vobu_start_sector <= 594 CHECK_VALUE(cell_playback[i].last_vobu_start_sector <=
576 cell_playback[i].last_sector); 595 cell_playback[i].last_sector);
577 assert(cell_playback[i].first_sector <= 596 CHECK_VALUE(cell_playback[i].first_sector <=
578 cell_playback[i].last_vobu_start_sector); 597 cell_playback[i].last_vobu_start_sector);
579 } 598 }
580 599
581 return 1; 600 return 1;
582 } 601 }
625 B2N_32(pgc->subp_control[i]); 644 B2N_32(pgc->subp_control[i]);
626 for(i = 0; i < 16; i++) 645 for(i = 0; i < 16; i++)
627 B2N_32(pgc->palette[i]); 646 B2N_32(pgc->palette[i]);
628 647
629 CHECK_ZERO(pgc->zero_1); 648 CHECK_ZERO(pgc->zero_1);
630 assert(pgc->nr_of_programs <= pgc->nr_of_cells); 649 CHECK_VALUE(pgc->nr_of_programs <= pgc->nr_of_cells);
631 650
632 /* verify time (look at print_time) */ 651 /* verify time (look at print_time) */
633 for(i = 0; i < 8; i++) 652 for(i = 0; i < 8; i++)
634 if(!pgc->audio_control[i] & 0x8000) /* The 'is present' bit */ 653 if(!pgc->audio_control[i] & 0x8000) /* The 'is present' bit */
635 CHECK_ZERO(pgc->audio_control[i]); 654 CHECK_ZERO(pgc->audio_control[i]);
639 658
640 /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */ 659 /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */
641 if(pgc->nr_of_programs == 0) { 660 if(pgc->nr_of_programs == 0) {
642 CHECK_ZERO(pgc->still_time); 661 CHECK_ZERO(pgc->still_time);
643 CHECK_ZERO(pgc->pg_playback_mode); // ?? 662 CHECK_ZERO(pgc->pg_playback_mode); // ??
644 assert(pgc->program_map_offset == 0); 663 CHECK_VALUE(pgc->program_map_offset == 0);
645 assert(pgc->cell_playback_offset == 0); 664 CHECK_VALUE(pgc->cell_playback_offset == 0);
646 assert(pgc->cell_position_offset == 0); 665 CHECK_VALUE(pgc->cell_position_offset == 0);
647 } else { 666 } else {
648 assert(pgc->program_map_offset != 0); 667 CHECK_VALUE(pgc->program_map_offset != 0);
649 assert(pgc->cell_playback_offset != 0); 668 CHECK_VALUE(pgc->cell_playback_offset != 0);
650 assert(pgc->cell_position_offset != 0); 669 CHECK_VALUE(pgc->cell_position_offset != 0);
651 } 670 }
652 671
653 if(pgc->command_tbl_offset != 0) { 672 if(pgc->command_tbl_offset != 0) {
654 pgc->command_tbl = malloc(sizeof(pgc_command_tbl_t)); 673 pgc->command_tbl = malloc(sizeof(pgc_command_tbl_t));
655 if(!pgc->command_tbl) 674 if(!pgc->command_tbl)
726 return 0; 745 return 0;
727 746
728 if(!ifofile->vmgi_mat) 747 if(!ifofile->vmgi_mat)
729 return 0; 748 return 0;
730 749
731 /* It seems that first_play_pgc might be optional after all. */ 750 /* It seems that first_play_pgc is optional after all. */
732 if(ifofile->vmgi_mat->first_play_pgc == 0) { /* mandatory */ 751 ifofile->first_play_pgc = 0;
733 ifofile->first_play_pgc = 0; 752 if(ifofile->vmgi_mat->first_play_pgc == 0)
734 return 0; /* change this to a 1 if it's optional. */ 753 return 1;
735 }
736 754
737 ifofile->first_play_pgc = (pgc_t *)malloc(sizeof(pgc_t)); 755 ifofile->first_play_pgc = (pgc_t *)malloc(sizeof(pgc_t));
738 if(!ifofile->first_play_pgc) 756 if(!ifofile->first_play_pgc)
739 return 0; 757 return 0;
740 758
823 B2N_32(tt_srpt->title[i].title_set_sector); 841 B2N_32(tt_srpt->title[i].title_set_sector);
824 } 842 }
825 843
826 844
827 CHECK_ZERO(tt_srpt->zero_1); 845 CHECK_ZERO(tt_srpt->zero_1);
828 assert(tt_srpt->nr_of_srpts != 0); 846 CHECK_VALUE(tt_srpt->nr_of_srpts != 0);
829 assert(tt_srpt->nr_of_srpts < 100); // ?? 847 CHECK_VALUE(tt_srpt->nr_of_srpts < 100); // ??
830 assert((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length); 848 CHECK_VALUE((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length);
831 849
832 for(i = 0; i < tt_srpt->nr_of_srpts; i++) { 850 for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
833 assert(tt_srpt->title[i].pb_ty.zero_1 == 0); 851 CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 == 0);
834 assert(tt_srpt->title[i].nr_of_angles != 0); 852 CHECK_VALUE(tt_srpt->title[i].nr_of_angles != 0);
835 assert(tt_srpt->title[i].nr_of_angles < 10); 853 CHECK_VALUE(tt_srpt->title[i].nr_of_angles < 10);
836 //assert(tt_srpt->title[i].nr_of_ptts != 0); 854 //CHECK_VALUE(tt_srpt->title[i].nr_of_ptts != 0);
837 // XXX: this assertion breaks Ghostbusters: 855 // XXX: this assertion breaks Ghostbusters:
838 assert(tt_srpt->title[i].nr_of_ptts < 1000); // ?? 856 CHECK_VALUE(tt_srpt->title[i].nr_of_ptts < 1000); // ??
839 assert(tt_srpt->title[i].title_set_nr != 0); 857 CHECK_VALUE(tt_srpt->title[i].title_set_nr != 0);
840 assert(tt_srpt->title[i].title_set_nr < 100); // ?? 858 CHECK_VALUE(tt_srpt->title[i].title_set_nr < 100); // ??
841 assert(tt_srpt->title[i].vts_ttn != 0); 859 CHECK_VALUE(tt_srpt->title[i].vts_ttn != 0);
842 assert(tt_srpt->title[i].vts_ttn < 100); // ?? 860 CHECK_VALUE(tt_srpt->title[i].vts_ttn < 100); // ??
843 //assert(tt_srpt->title[i].title_set_sector != 0); 861 //CHECK_VALUE(tt_srpt->title[i].title_set_sector != 0);
844 } 862 }
845 863
846 // Make this a function 864 // Make this a function
847 #if 0 865 #if 0
848 if(memcmp((uint8_t *)tt_srpt->title + 866 if(memcmp((uint8_t *)tt_srpt->title +
904 922
905 B2N_16(vts_ptt_srpt->nr_of_srpts); 923 B2N_16(vts_ptt_srpt->nr_of_srpts);
906 B2N_32(vts_ptt_srpt->last_byte); 924 B2N_32(vts_ptt_srpt->last_byte);
907 925
908 CHECK_ZERO(vts_ptt_srpt->zero_1); 926 CHECK_ZERO(vts_ptt_srpt->zero_1);
909 assert(vts_ptt_srpt->nr_of_srpts != 0); 927 CHECK_VALUE(vts_ptt_srpt->nr_of_srpts != 0);
910 assert(vts_ptt_srpt->nr_of_srpts < 100); // ?? 928 CHECK_VALUE(vts_ptt_srpt->nr_of_srpts < 100); // ??
911 929
912 info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE; 930 info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
913 931
914 data = (uint32_t *)malloc(info_length); 932 data = (uint32_t *)malloc(info_length);
915 if(!data) { 933 if(!data) {
929 B2N_32(data[i]); 947 B2N_32(data[i]);
930 /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1); 948 /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
931 Magic Knight Rayearth Daybreak is mastered very strange and has 949 Magic Knight Rayearth Daybreak is mastered very strange and has
932 Titles with 0 PTTs. They all have a data[i] offsets beyond the end of 950 Titles with 0 PTTs. They all have a data[i] offsets beyond the end of
933 of the vts_ptt_srpt structure. */ 951 of the vts_ptt_srpt structure. */
934 assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4); 952 CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4);
935 } 953 }
954
955 vts_ptt_srpt->ttu_offset = data;
936 956
937 vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t)); 957 vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t));
938 if(!vts_ptt_srpt->title) { 958 if(!vts_ptt_srpt->title) {
939 free(vts_ptt_srpt); 959 free(vts_ptt_srpt);
940 free(data); 960 free(data);
949 n = (vts_ptt_srpt->last_byte + 1 - data[i]); 969 n = (vts_ptt_srpt->last_byte + 1 - data[i]);
950 /* assert(n > 0 && (n % 4) == 0); 970 /* assert(n > 0 && (n % 4) == 0);
951 Magic Knight Rayearth Daybreak is mastered very strange and has 971 Magic Knight Rayearth Daybreak is mastered very strange and has
952 Titles with 0 PTTs. */ 972 Titles with 0 PTTs. */
953 if(n < 0) n = 0; 973 if(n < 0) n = 0;
954 assert(n % 4 == 0); 974 CHECK_VALUE(n % 4 == 0);
955 975
956 vts_ptt_srpt->title[i].nr_of_ptts = n / 4; 976 vts_ptt_srpt->title[i].nr_of_ptts = n / 4;
957 vts_ptt_srpt->title[i].ptt = malloc(n * sizeof(ptt_info_t)); 977 vts_ptt_srpt->title[i].ptt = malloc(n * sizeof(ptt_info_t));
958 if(!vts_ptt_srpt->title[i].ptt) { 978 if(!vts_ptt_srpt->title[i].ptt) {
959 for(n = 0; n < i; n++) 979 for(n = 0; n < i; n++)
963 ifofile->vts_ptt_srpt = 0; 983 ifofile->vts_ptt_srpt = 0;
964 return 0; 984 return 0;
965 } 985 }
966 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { 986 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
967 /* The assert placed here because of Magic Knight Rayearth Daybreak */ 987 /* The assert placed here because of Magic Knight Rayearth Daybreak */
968 assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1); 988 CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
969 vts_ptt_srpt->title[i].ptt[j].pgcn 989 vts_ptt_srpt->title[i].ptt[j].pgcn
970 = *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_SIZE); 990 = *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_SIZE);
971 vts_ptt_srpt->title[i].ptt[j].pgn 991 vts_ptt_srpt->title[i].ptt[j].pgn
972 = *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE); 992 = *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE);
973 } 993 }
974 } 994 }
975 free(data);
976 995
977 for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { 996 for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
978 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { 997 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
979 B2N_16(vts_ptt_srpt->title[i].ptt[j].pgcn); 998 B2N_16(vts_ptt_srpt->title[i].ptt[j].pgcn);
980 B2N_16(vts_ptt_srpt->title[i].ptt[j].pgn); 999 B2N_16(vts_ptt_srpt->title[i].ptt[j].pgn);
981 } 1000 }
982 } 1001 }
983 1002
984 for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { 1003 for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
985 assert(vts_ptt_srpt->title[i].nr_of_ptts < 1000); // ?? 1004 CHECK_VALUE(vts_ptt_srpt->title[i].nr_of_ptts < 1000); // ??
986 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { 1005 for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
987 assert(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 ); 1006 CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 );
988 assert(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); // ?? 1007 CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); // ??
989 assert(vts_ptt_srpt->title[i].ptt[j].pgn != 0); 1008 CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn != 0);
990 assert(vts_ptt_srpt->title[i].ptt[j].pgn < 100); // ?? 1009 CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn < 100); // ??
991 } 1010 }
992 } 1011 }
993 1012
994 return 1; 1013 return 1;
995 } 1014 }
1001 1020
1002 if(ifofile->vts_ptt_srpt) { 1021 if(ifofile->vts_ptt_srpt) {
1003 int i; 1022 int i;
1004 for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++) 1023 for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++)
1005 free(ifofile->vts_ptt_srpt->title[i].ptt); 1024 free(ifofile->vts_ptt_srpt->title[i].ptt);
1025 free(ifofile->vts_ptt_srpt->ttu_offset);
1006 free(ifofile->vts_ptt_srpt->title); 1026 free(ifofile->vts_ptt_srpt->title);
1007 free(ifofile->vts_ptt_srpt); 1027 free(ifofile->vts_ptt_srpt);
1008 ifofile->vts_ptt_srpt = 0; 1028 ifofile->vts_ptt_srpt = 0;
1009 } 1029 }
1010 } 1030 }
1011 1031
1012 1032
1013 int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) { 1033 int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
1014 ptl_mait_t *ptl_mait; 1034 ptl_mait_t *ptl_mait;
1015 int info_length; 1035 int info_length;
1016 unsigned int i; 1036 unsigned int i, j;
1017 1037
1018 if(!ifofile) 1038 if(!ifofile)
1019 return 0; 1039 return 0;
1020 1040
1021 if(!ifofile->vmgi_mat) 1041 if(!ifofile->vmgi_mat)
1022 return 0; 1042 return 0;
1023 1043
1024 if(ifofile->vmgi_mat->ptl_mait == 0) 1044 if(ifofile->vmgi_mat->ptl_mait == 0)
1025 return 1; 1045 return 1;
1026 1046
1027 if(!DVDFileSeek_(ifofile->file, 1047 if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
1028 ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
1029 return 0; 1048 return 0;
1030 1049
1031 ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t)); 1050 ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t));
1032 if(!ptl_mait) 1051 if(!ptl_mait)
1033 return 0; 1052 return 0;
1042 1061
1043 B2N_16(ptl_mait->nr_of_countries); 1062 B2N_16(ptl_mait->nr_of_countries);
1044 B2N_16(ptl_mait->nr_of_vtss); 1063 B2N_16(ptl_mait->nr_of_vtss);
1045 B2N_32(ptl_mait->last_byte); 1064 B2N_32(ptl_mait->last_byte);
1046 1065
1047 info_length = ptl_mait->last_byte + 1 - PTL_MAIT_SIZE; 1066 CHECK_VALUE(ptl_mait->nr_of_countries != 0);
1048 1067 CHECK_VALUE(ptl_mait->nr_of_countries < 100); // ??
1049 assert(ptl_mait->nr_of_countries != 0); 1068 CHECK_VALUE(ptl_mait->nr_of_vtss != 0);
1050 assert(ptl_mait->nr_of_countries < 100); // ?? 1069 CHECK_VALUE(ptl_mait->nr_of_vtss < 100); // ??
1051 assert(ptl_mait->nr_of_vtss != 0); 1070 CHECK_VALUE(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE
1052 assert(ptl_mait->nr_of_vtss < 100); // ?? 1071 <= ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
1053 assert(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE <= info_length); 1072
1054 1073 info_length = ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t);
1055 /* Change this to read and 'translate' the tables too.
1056 I.e don't read so much here */
1057 ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length); 1074 ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length);
1058 if(!ptl_mait->countries) { 1075 if(!ptl_mait->countries) {
1059 free(ptl_mait); 1076 free(ptl_mait);
1060 ifofile->ptl_mait = 0; 1077 ifofile->ptl_mait = 0;
1061 return 0; 1078 return 0;
1062 } 1079 }
1063 if(!(DVDReadBytes(ifofile->file, ptl_mait->countries, info_length))) { 1080
1064 fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n"); 1081 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
1065 ifoFree_PTL_MAIT(ifofile); 1082 if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) {
1066 return 0; 1083 fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
1084 free(ptl_mait->countries);
1085 free(ptl_mait);
1086 ifofile->ptl_mait = 0;
1087 return 0;
1088 }
1067 } 1089 }
1068 1090
1069 for(i = 0; i < ptl_mait->nr_of_countries; i++) { 1091 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
1070 B2N_16(ptl_mait->countries[i].country_code); 1092 B2N_16(ptl_mait->countries[i].country_code);
1071 B2N_16(ptl_mait->countries[i].pf_ptl_mai_start_byte); 1093 B2N_16(ptl_mait->countries[i].pf_ptl_mai_start_byte);
1072 } 1094 }
1073 1095
1074 for(i = 0; i < ptl_mait->nr_of_countries; i++) { 1096 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
1075 CHECK_ZERO(ptl_mait->countries[i].zero_1); 1097 CHECK_ZERO(ptl_mait->countries[i].zero_1);
1076 CHECK_ZERO(ptl_mait->countries[i].zero_2); 1098 CHECK_ZERO(ptl_mait->countries[i].zero_2);
1077 assert(ptl_mait->countries[i].pf_ptl_mai_start_byte + 1099 CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte
1078 8 * (ptl_mait->nr_of_vtss + 1) * 2 <= ptl_mait->last_byte + 1); 1100 + 8*2 * (ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1);
1079 } 1101 }
1080 1102
1081 return 1; 1103 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
1082 } 1104 uint16_t *pf_temp;
1083 1105
1106 if(!DVDFileSeek_(ifofile->file,
1107 ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
1108 + ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
1109 fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
1110 free(ptl_mait->countries);
1111 free(ptl_mait);
1112 return 0;
1113 }
1114 info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
1115 pf_temp = (uint16_t *)malloc(info_length);
1116 if(!pf_temp) {
1117 for(j = 0; j < i ; j++) {
1118 free(ptl_mait->countries[j].pf_ptl_mai);
1119 }
1120 free(ptl_mait->countries);
1121 free(ptl_mait);
1122 return 0;
1123 }
1124 if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
1125 fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
1126 free(pf_temp);
1127 for(j = 0; j < i ; j++) {
1128 free(ptl_mait->countries[j].pf_ptl_mai);
1129 }
1130 free(ptl_mait->countries);
1131 free(ptl_mait);
1132 return 0;
1133 }
1134 for (j = 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
1135 B2N_16(pf_temp[j]);
1136 }
1137 ptl_mait->countries[i].pf_ptl_mai = (pf_level_t *)malloc(info_length);
1138 if(!ptl_mait->countries[i].pf_ptl_mai) {
1139 free(pf_temp);
1140 for(j = 0; j < i ; j++) {
1141 free(ptl_mait->countries[j].pf_ptl_mai);
1142 }
1143 free(ptl_mait->countries);
1144 free(ptl_mait);
1145 return 0;
1146 }
1147 { /* Transpose the array so we can use C indexing. */
1148 int level, vts;
1149 for(level = 0; level < 8; level++) {
1150 for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
1151 ptl_mait->countries[i].pf_ptl_mai[vts][level] =
1152 pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
1153 }
1154 }
1155 free(pf_temp);
1156 }
1157 }
1158 return 1;
1159 }
1084 1160
1085 void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) { 1161 void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) {
1162 unsigned int i;
1163
1086 if(!ifofile) 1164 if(!ifofile)
1087 return; 1165 return;
1088 1166
1089 if(ifofile->ptl_mait) { 1167 if(ifofile->ptl_mait) {
1168 for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
1169 free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
1170 }
1090 free(ifofile->ptl_mait->countries); 1171 free(ifofile->ptl_mait->countries);
1091 free(ifofile->ptl_mait); 1172 free(ifofile->ptl_mait);
1092 ifofile->ptl_mait = 0; 1173 ifofile->ptl_mait = 0;
1093 } 1174 }
1094 } 1175 }
1176
1177 int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) {
1178 vts_tmapt_t *vts_tmapt;
1179 uint32_t *vts_tmap_srp;
1180 unsigned int offset;
1181 int info_length;
1182 unsigned int i, j;
1183
1184 if(!ifofile)
1185 return 0;
1186
1187 if(!ifofile->vtsi_mat)
1188 return 0;
1189
1190 if(ifofile->vtsi_mat->vts_tmapt == 0) { /* optional(?) */
1191 ifofile->vts_tmapt = NULL;
1192 fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n");
1193 return 1;
1194 }
1195
1196 offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN;
1197
1198 if(!DVDFileSeek_(ifofile->file, offset))
1199 return 0;
1200
1201 vts_tmapt = (vts_tmapt_t *)malloc(sizeof(vts_tmapt_t));
1202 if(!vts_tmapt)
1203 return 0;
1204
1205 ifofile->vts_tmapt = vts_tmapt;
1206
1207 if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) {
1208 fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
1209 free(vts_tmapt);
1210 ifofile->vts_tmapt = NULL;
1211 return 0;
1212 }
1213
1214 B2N_16(vts_tmapt->nr_of_tmaps);
1215 B2N_32(vts_tmapt->last_byte);
1216
1217 CHECK_ZERO(vts_tmapt->zero_1);
1218
1219 info_length = vts_tmapt->nr_of_tmaps * 4;
1220
1221 vts_tmap_srp = (uint32_t *)malloc(info_length);
1222 if(!vts_tmap_srp) {
1223 free(vts_tmapt);
1224 ifofile->vts_tmapt = NULL;
1225 return 0;
1226 }
1227
1228 vts_tmapt->tmap_offset = vts_tmap_srp;
1229
1230 if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) {
1231 fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
1232 free(vts_tmap_srp);
1233 free(vts_tmapt);
1234 ifofile->vts_tmapt = NULL;
1235 return 0;
1236 }
1237
1238 for (i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
1239 B2N_32(vts_tmap_srp[i]);
1240 }
1241
1242
1243 info_length = vts_tmapt->nr_of_tmaps * sizeof(vts_tmap_t);
1244
1245 vts_tmapt->tmap = (vts_tmap_t *)malloc(info_length);
1246 if(!vts_tmapt->tmap) {
1247 free(vts_tmap_srp);
1248 free(vts_tmapt);
1249 ifofile->vts_tmapt = NULL;
1250 return 0;
1251 }
1252
1253 memset(vts_tmapt->tmap, 0, info_length); /* So ifoFree_VTS_TMAPT works. */
1254
1255 for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
1256 if(!DVDFileSeek_(ifofile->file, offset + vts_tmap_srp[i])) {
1257 ifoFree_VTS_TMAPT(ifofile);
1258 return 0;
1259 }
1260
1261 if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE))) {
1262 fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n");
1263 ifoFree_VTS_TMAPT(ifofile);
1264 return 0;
1265 }
1266
1267 B2N_16(vts_tmapt->tmap[i].nr_of_entries);
1268 CHECK_ZERO(vts_tmapt->tmap[i].zero_1);
1269
1270 if(vts_tmapt->tmap[i].nr_of_entries == 0) { /* Early out if zero entries */
1271 vts_tmapt->tmap[i].map_ent = NULL;
1272 continue;
1273 }
1274
1275 info_length = vts_tmapt->tmap[i].nr_of_entries * sizeof(map_ent_t);
1276
1277 vts_tmapt->tmap[i].map_ent = (map_ent_t *)malloc(info_length);
1278 if(!vts_tmapt->tmap[i].map_ent) {
1279 ifoFree_VTS_TMAPT(ifofile);
1280 return 0;
1281 }
1282
1283 if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_length))) {
1284 fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
1285 ifoFree_VTS_TMAPT(ifofile);
1286 return 0;
1287 }
1288
1289 for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++)
1290 B2N_32(vts_tmapt->tmap[i].map_ent[j]);
1291 }
1292
1293 return 1;
1294 }
1295
1296 void ifoFree_VTS_TMAPT(ifo_handle_t *ifofile) {
1297 unsigned int i;
1298
1299 if(!ifofile)
1300 return;
1301
1302 if(ifofile->vts_tmapt) {
1303 for(i = 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++)
1304 if(ifofile->vts_tmapt->tmap[i].map_ent)
1305 free(ifofile->vts_tmapt->tmap[i].map_ent);
1306 free(ifofile->vts_tmapt->tmap);
1307 free(ifofile->vts_tmapt->tmap_offset);
1308 free(ifofile->vts_tmapt);
1309 ifofile->vts_tmapt = NULL;
1310 }
1311 }
1312
1095 1313
1096 int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) { 1314 int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) {
1097 1315
1098 if(!ifofile) 1316 if(!ifofile)
1099 return 0; 1317 return 0;
1166 1384
1167 CHECK_ZERO(c_adt->zero_1); 1385 CHECK_ZERO(c_adt->zero_1);
1168 /* assert(c_adt->nr_of_vobs > 0); 1386 /* assert(c_adt->nr_of_vobs > 0);
1169 Magic Knight Rayearth Daybreak is mastered very strange and has 1387 Magic Knight Rayearth Daybreak is mastered very strange and has
1170 Titles with a VOBS that has no cells. */ 1388 Titles with a VOBS that has no cells. */
1171 assert(info_length % sizeof(cell_adr_t) == 0); 1389 CHECK_VALUE(info_length % sizeof(cell_adr_t) == 0);
1172 1390
1173 /* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs); 1391 /* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs);
1174 Enemy of the State region 2 (de) has Titles where nr_of_vobs field 1392 Enemy of the State region 2 (de) has Titles where nr_of_vobs field
1175 is to high, they high ones are never referenced though. */ 1393 is to high, they high ones are never referenced though. */
1176 if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) { 1394 if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) {
1192 B2N_16(c_adt->cell_adr_table[i].vob_id); 1410 B2N_16(c_adt->cell_adr_table[i].vob_id);
1193 B2N_32(c_adt->cell_adr_table[i].start_sector); 1411 B2N_32(c_adt->cell_adr_table[i].start_sector);
1194 B2N_32(c_adt->cell_adr_table[i].last_sector); 1412 B2N_32(c_adt->cell_adr_table[i].last_sector);
1195 1413
1196 CHECK_ZERO(c_adt->cell_adr_table[i].zero_1); 1414 CHECK_ZERO(c_adt->cell_adr_table[i].zero_1);
1197 assert(c_adt->cell_adr_table[i].vob_id > 0); 1415 CHECK_VALUE(c_adt->cell_adr_table[i].vob_id > 0);
1198 assert(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs); 1416 CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs);
1199 assert(c_adt->cell_adr_table[i].cell_id > 0); 1417 CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0);
1200 assert(c_adt->cell_adr_table[i].start_sector < 1418 CHECK_VALUE(c_adt->cell_adr_table[i].start_sector <
1201 c_adt->cell_adr_table[i].last_sector); 1419 c_adt->cell_adr_table[i].last_sector);
1202 } 1420 }
1203 1421
1204 return 1; 1422 return 1;
1205 } 1423 }
1299 1517
1300 info_length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE; 1518 info_length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
1301 /* assert(info_length > 0); 1519 /* assert(info_length > 0);
1302 Magic Knight Rayearth Daybreak is mastered very strange and has 1520 Magic Knight Rayearth Daybreak is mastered very strange and has
1303 Titles with a VOBS that has no VOBUs. */ 1521 Titles with a VOBS that has no VOBUs. */
1304 assert(info_length % sizeof(uint32_t) == 0); 1522 CHECK_VALUE(info_length % sizeof(uint32_t) == 0);
1305 1523
1306 vobu_admap->vobu_start_sectors = (uint32_t *)malloc(info_length); 1524 vobu_admap->vobu_start_sectors = (uint32_t *)malloc(info_length);
1307 if(!vobu_admap->vobu_start_sectors) { 1525 if(!vobu_admap->vobu_start_sectors) {
1308 return 0; 1526 return 0;
1309 } 1527 }
1385 1603
1386 CHECK_ZERO(pgcit->zero_1); 1604 CHECK_ZERO(pgcit->zero_1);
1387 /* assert(pgcit->nr_of_pgci_srp != 0); 1605 /* assert(pgcit->nr_of_pgci_srp != 0);
1388 Magic Knight Rayearth Daybreak is mastered very strange and has 1606 Magic Knight Rayearth Daybreak is mastered very strange and has
1389 Titles with 0 PTTs. */ 1607 Titles with 0 PTTs. */
1390 assert(pgcit->nr_of_pgci_srp < 10000); // ?? seen max of 1338 1608 CHECK_VALUE(pgcit->nr_of_pgci_srp < 10000); // ?? seen max of 1338
1391 1609
1392 info_length = pgcit->nr_of_pgci_srp * PGCI_SRP_SIZE; 1610 info_length = pgcit->nr_of_pgci_srp * PGCI_SRP_SIZE;
1393 data = malloc(info_length); 1611 data = malloc(info_length);
1394 if(!data) 1612 if(!data)
1395 return 0; 1613 return 0;
1408 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { 1626 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
1409 memcpy(&pgcit->pgci_srp[i], ptr, PGCI_LU_SIZE); 1627 memcpy(&pgcit->pgci_srp[i], ptr, PGCI_LU_SIZE);
1410 ptr += PGCI_LU_SIZE; 1628 ptr += PGCI_LU_SIZE;
1411 B2N_16(pgcit->pgci_srp[i].ptl_id_mask); 1629 B2N_16(pgcit->pgci_srp[i].ptl_id_mask);
1412 B2N_32(pgcit->pgci_srp[i].pgc_start_byte); 1630 B2N_32(pgcit->pgci_srp[i].pgc_start_byte);
1413 assert(pgcit->pgci_srp[i].unknown1 == 0); 1631 CHECK_VALUE(pgcit->pgci_srp[i].unknown1 == 0);
1414 } 1632 }
1415 free(data); 1633 free(data);
1416 1634
1417 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) 1635 for(i = 0; i < pgcit->nr_of_pgci_srp; i++)
1418 assert(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1); 1636 CHECK_VALUE(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1);
1419 1637
1420 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { 1638 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
1421 pgcit->pgci_srp[i].pgc = malloc(sizeof(pgc_t)); 1639 pgcit->pgci_srp[i].pgc = malloc(sizeof(pgc_t));
1422 if(!pgcit->pgci_srp[i].pgc) { 1640 if(!pgcit->pgci_srp[i].pgc) {
1423 int j; 1641 int j;
1505 1723
1506 B2N_16(pgci_ut->nr_of_lus); 1724 B2N_16(pgci_ut->nr_of_lus);
1507 B2N_32(pgci_ut->last_byte); 1725 B2N_32(pgci_ut->last_byte);
1508 1726
1509 CHECK_ZERO(pgci_ut->zero_1); 1727 CHECK_ZERO(pgci_ut->zero_1);
1510 assert(pgci_ut->nr_of_lus != 0); 1728 CHECK_VALUE(pgci_ut->nr_of_lus != 0);
1511 assert(pgci_ut->nr_of_lus < 100); // ?? 3-4 ? 1729 CHECK_VALUE(pgci_ut->nr_of_lus < 100); // ?? 3-4 ?
1512 assert((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte); 1730 CHECK_VALUE((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte);
1513 1731
1514 info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE; 1732 info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE;
1515 data = malloc(info_length); 1733 data = malloc(info_length);
1516 if(!data) { 1734 if(!data) {
1517 free(pgci_ut); 1735 free(pgci_ut);
1540 B2N_32(pgci_ut->lu[i].lang_start_byte); 1758 B2N_32(pgci_ut->lu[i].lang_start_byte);
1541 } 1759 }
1542 free(data); 1760 free(data);
1543 1761
1544 for(i = 0; i < pgci_ut->nr_of_lus; i++) { 1762 for(i = 0; i < pgci_ut->nr_of_lus; i++) {
1545 CHECK_ZERO(pgci_ut->lu[i].zero_1);
1546 // Maybe this is only defined for v1.1 and later titles? 1763 // Maybe this is only defined for v1.1 and later titles?
1547 /* If the bits in 'lu[i].exists' are enumerated abcd efgh then: 1764 /* If the bits in 'lu[i].exists' are enumerated abcd efgh then:
1548 VTS_x_yy.IFO VIDEO_TS.IFO 1765 VTS_x_yy.IFO VIDEO_TS.IFO
1549 a == 0x83 "Root" 0x82 "Title" 1766 a == 0x83 "Root" 0x82 "Title"
1550 b == 0x84 "Subpicture" 1767 b == 0x84 "Subpicture"
1551 c == 0x85 "Audio" 1768 c == 0x85 "Audio"
1552 d == 0x86 "Angle" 1769 d == 0x86 "Angle"
1553 e == 0x87 "PTT" 1770 e == 0x87 "PTT"
1554 */ 1771 */
1555 assert((pgci_ut->lu[i].exists & 0x07) == 0); 1772 CHECK_VALUE((pgci_ut->lu[i].exists & 0x07) == 0);
1556 } 1773 }
1557 1774
1558 for(i = 0; i < pgci_ut->nr_of_lus; i++) { 1775 for(i = 0; i < pgci_ut->nr_of_lus; i++) {
1559 pgci_ut->lu[i].pgcit = malloc(sizeof(pgcit_t)); 1776 pgci_ut->lu[i].pgcit = malloc(sizeof(pgcit_t));
1560 if(!pgci_ut->lu[i].pgcit) { 1777 if(!pgci_ut->lu[i].pgcit) {
1632 CHECK_ZERO(vts_attributes->zero_3); 1849 CHECK_ZERO(vts_attributes->zero_3);
1633 CHECK_ZERO(vts_attributes->zero_4); 1850 CHECK_ZERO(vts_attributes->zero_4);
1634 CHECK_ZERO(vts_attributes->zero_5); 1851 CHECK_ZERO(vts_attributes->zero_5);
1635 CHECK_ZERO(vts_attributes->zero_6); 1852 CHECK_ZERO(vts_attributes->zero_6);
1636 CHECK_ZERO(vts_attributes->zero_7); 1853 CHECK_ZERO(vts_attributes->zero_7);
1637 assert(vts_attributes->nr_of_vtsm_audio_streams <= 1); 1854 CHECK_VALUE(vts_attributes->nr_of_vtsm_audio_streams <= 1);
1638 assert(vts_attributes->nr_of_vtsm_subp_streams <= 1); 1855 CHECK_VALUE(vts_attributes->nr_of_vtsm_subp_streams <= 1);
1639 assert(vts_attributes->nr_of_vtstt_audio_streams <= 8); 1856 CHECK_VALUE(vts_attributes->nr_of_vtstt_audio_streams <= 8);
1640 for(i = vts_attributes->nr_of_vtstt_audio_streams; i < 8; i++) 1857 for(i = vts_attributes->nr_of_vtstt_audio_streams; i < 8; i++)
1641 CHECK_ZERO(vts_attributes->vtstt_audio_attr[i]); 1858 CHECK_ZERO(vts_attributes->vtstt_audio_attr[i]);
1642 assert(vts_attributes->nr_of_vtstt_subp_streams <= 32); 1859 CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= 32);
1643 { 1860 {
1644 unsigned int nr_coded; 1861 unsigned int nr_coded;
1645 assert(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE); 1862 CHECK_VALUE(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE);
1646 nr_coded = (vts_attributes->last_byte + 1 - VTS_ATTRIBUTES_MIN_SIZE)/6; 1863 nr_coded = (vts_attributes->last_byte + 1 - VTS_ATTRIBUTES_MIN_SIZE)/6;
1647 // This is often nr_coded = 70, how do you know how many there really are? 1864 // This is often nr_coded = 70, how do you know how many there really are?
1648 if(nr_coded > 32) { // We haven't read more from disk/file anyway 1865 if(nr_coded > 32) { // We haven't read more from disk/file anyway
1649 nr_coded = 32; 1866 nr_coded = 32;
1650 } 1867 }
1651 assert(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded); 1868 CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded);
1652 for(i = vts_attributes->nr_of_vtstt_subp_streams; i < nr_coded; i++) 1869 for(i = vts_attributes->nr_of_vtstt_subp_streams; i < nr_coded; i++)
1653 CHECK_ZERO(vts_attributes->vtstt_subp_attr[i]); 1870 CHECK_ZERO(vts_attributes->vtstt_subp_attr[i]);
1654 } 1871 }
1655 1872
1656 return 1; 1873 return 1;
1690 1907
1691 B2N_16(vts_atrt->nr_of_vtss); 1908 B2N_16(vts_atrt->nr_of_vtss);
1692 B2N_32(vts_atrt->last_byte); 1909 B2N_32(vts_atrt->last_byte);
1693 1910
1694 CHECK_ZERO(vts_atrt->zero_1); 1911 CHECK_ZERO(vts_atrt->zero_1);
1695 assert(vts_atrt->nr_of_vtss != 0); 1912 CHECK_VALUE(vts_atrt->nr_of_vtss != 0);
1696 assert(vts_atrt->nr_of_vtss < 100); //?? 1913 CHECK_VALUE(vts_atrt->nr_of_vtss < 100); //??
1697 assert((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) + 1914 CHECK_VALUE((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) +
1698 VTS_ATRT_SIZE < vts_atrt->last_byte + 1); 1915 VTS_ATRT_SIZE < vts_atrt->last_byte + 1);
1699 1916
1700 info_length = vts_atrt->nr_of_vtss * sizeof(uint32_t); 1917 info_length = vts_atrt->nr_of_vtss * sizeof(uint32_t);
1701 data = (uint32_t *)malloc(info_length); 1918 data = (uint32_t *)malloc(info_length);
1702 if(!data) { 1919 if(!data) {
1703 free(vts_atrt); 1920 free(vts_atrt);
1704 ifofile->vts_atrt = 0; 1921 ifofile->vts_atrt = 0;
1705 return 0; 1922 return 0;
1706 } 1923 }
1924
1925 vts_atrt->vts_atrt_offsets = data;
1926
1707 if(!(DVDReadBytes(ifofile->file, data, info_length))) { 1927 if(!(DVDReadBytes(ifofile->file, data, info_length))) {
1708 free(data); 1928 free(data);
1709 free(vts_atrt); 1929 free(vts_atrt);
1710 ifofile->vts_atrt = 0; 1930 ifofile->vts_atrt = 0;
1711 return 0; 1931 return 0;
1712 } 1932 }
1713 1933
1714 for(i = 0; i < vts_atrt->nr_of_vtss; i++) { 1934 for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
1715 B2N_32(data[i]); 1935 B2N_32(data[i]);
1716 assert(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1); 1936 CHECK_VALUE(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1);
1717 } 1937 }
1718 1938
1719 info_length = vts_atrt->nr_of_vtss * sizeof(vts_attributes_t); 1939 info_length = vts_atrt->nr_of_vtss * sizeof(vts_attributes_t);
1720 vts_atrt->vts = (vts_attributes_t *)malloc(info_length); 1940 vts_atrt->vts = (vts_attributes_t *)malloc(info_length);
1721 if(!vts_atrt->vts) { 1941 if(!vts_atrt->vts) {
1733 ifofile->vts_atrt = 0; 1953 ifofile->vts_atrt = 0;
1734 return 0; 1954 return 0;
1735 } 1955 }
1736 1956
1737 // This assert cant be in ifoRead_VTS_ATTRIBUTES 1957 // This assert cant be in ifoRead_VTS_ATTRIBUTES
1738 assert(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1); 1958 CHECK_VALUE(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1);
1739 // Is this check correct? 1959 // Is this check correct?
1740 } 1960 }
1741 free(data);
1742 1961
1743 return 1; 1962 return 1;
1744 } 1963 }
1745 1964
1746 1965
1748 if(!ifofile) 1967 if(!ifofile)
1749 return; 1968 return;
1750 1969
1751 if(ifofile->vts_atrt) { 1970 if(ifofile->vts_atrt) {
1752 free(ifofile->vts_atrt->vts); 1971 free(ifofile->vts_atrt->vts);
1972 free(ifofile->vts_atrt->vts_atrt_offsets);
1753 free(ifofile->vts_atrt); 1973 free(ifofile->vts_atrt);
1754 ifofile->vts_atrt = 0; 1974 ifofile->vts_atrt = 0;
1755 } 1975 }
1756 } 1976 }
1757 1977