diff -ruib ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_reader.c ./dvd_reader.c --- ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_reader.c 2008-10-10 15:44:30.000000000 +0900 +++ ./dvd_reader.c 2008-10-10 17:20:20.000000000 +0900 @@ -912,6 +912,187 @@ } } +static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title, + int menu, dvd_stat_t *statbuf) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + uint64_t size; + off_t tot_size; + off_t parts_size[9]; + int nr_parts = 0; + int n; + UDF_FILE udf_file; + + if( title == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); + } + if(!(udf_file = UDFFindFile( dvd, filename, &size ))) { + return -1; + } + UDFFreeFile(dvd, udf_file); + + tot_size = size; + nr_parts = 1; + parts_size[0] = size; + + if( !menu ) { + int cur; + + for( cur = 2; cur < 10; cur++ ) { + sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur ); + if( !(udf_file = UDFFindFile( dvd, filename, &size ) )) { + break; + } + UDFFreeFile(dvd, udf_file); + + parts_size[nr_parts] = size; + tot_size += size; + nr_parts++; + } + } + + statbuf->size = tot_size; + statbuf->nr_parts = nr_parts; + for(n = 0; n < nr_parts; n++) { + statbuf->parts_size[n] = parts_size[n]; + } + return 0; +} + +static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title, + int menu, dvd_stat_t *statbuf ) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + char full_path[ PATH_MAX + 1 ]; + struct stat fileinfo; + off_t tot_size; + off_t parts_size[9]; + int nr_parts = 0; + int n; + + if( title == 0 ) { + sprintf( filename, "VIDEO_TS.VOB" ); + } else { + sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); + } + if( !findDVDFile( dvd, filename, full_path ) ) { + return -1; + } + + if( stat( full_path, &fileinfo ) < 0 ) { + return -1; + } + + tot_size = fileinfo.st_size; + nr_parts = 1; + parts_size[0] = fileinfo.st_size; + + if( !menu ) { + int cur; + + for( cur = 2; cur < 10; cur++ ) { + + sprintf( filename, "VTS_%02d_%d.VOB", title, cur ); + if( !findDVDFile( dvd, filename, full_path ) ) { + break; + } + + if( stat( full_path, &fileinfo ) < 0 ) { + break; + } + + parts_size[nr_parts] = fileinfo.st_size; + tot_size += parts_size[nr_parts]; + nr_parts++; + } + } + + statbuf->size = tot_size; + statbuf->nr_parts = nr_parts; + for(n = 0; n < nr_parts; n++) { + statbuf->parts_size[n] = parts_size[n]; + } + return 0; +} + + +int DVDFileStat(dvd_reader_t *dvd, int titlenum, + dvd_read_domain_t domain, dvd_stat_t *statbuf) +{ + char filename[ MAX_UDF_FILE_NAME_LEN ]; + char full_path[ PATH_MAX + 1 ]; + struct stat fileinfo; + uint64_t size; + UDF_FILE udf_file; + + /* Check arguments. */ + if( dvd == NULL || titlenum < 0 ) { + errno = EINVAL; + return -1; + } + + switch( domain ) { + case DVD_READ_INFO_FILE: + if( titlenum == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum ); + } + break; + case DVD_READ_INFO_BACKUP_FILE: + if( titlenum == 0 ) { + sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" ); + } else { + sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum ); + } + break; + case DVD_READ_MENU_VOBS: + if( dvd->isImageFile ) { + return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf ); + } else { + return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf ); + } + break; + case DVD_READ_TITLE_VOBS: + if( titlenum == 0 ) { + return -1; + } + if( dvd->isImageFile ) { + return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf ); + } else { + return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf ); + } + break; + default: + errno = EINVAL; + return -1; + } + + if( dvd->isImageFile ) { + if( (udf_file = UDFFindFile( dvd, filename, &size )) ) { + statbuf->size = size; + statbuf->nr_parts = 1; + statbuf->parts_size[0] = size; + UDFFreeFile(dvd, udf_file); + return 0; + } + } else { + if( findDVDFile( dvd, filename, full_path ) ) { + if( stat( full_path, &fileinfo ) < 0 ) { + ; + } else { + statbuf->size = fileinfo.st_size; + statbuf->nr_parts = 1; + statbuf->parts_size[0] = statbuf->size; + return 0; + } + } + } + return -1; +} + /* Internal, but used from dvd_udf.c */ int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, diff -ruib ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_reader.h ./dvd_reader.h --- ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_reader.h 2008-10-10 15:36:13.000000000 +0900 +++ ./dvd_reader.h 2008-10-10 17:19:36.000000000 +0900 @@ -116,6 +116,42 @@ single file. */ } dvd_read_domain_t; +/* + * DVD stat structure for getting VOB sizes + */ +typedef struct { + off_t size; /**< Total size of file in bytes */ + int nr_parts; /**< Number of file parts */ + off_t parts_size[9]; /**< Size of each part in bytes */ +} dvd_stat_t; + +/** + * Stats a file on the DVD given the title number and domain. + * The information about the file is stored in a dvd_stat_t + * which contains information about the size of the file and + * the number of parts in case of a multipart file and the respective + * sizes of the parts. + * A multipart file is for instance VTS_02_1.VOB, VTS_02_2.VOB, VTS_02_3.VOB + * The size of VTS_02_1.VOB will be stored in stat->parts_size[0], + * VTS_02_2.VOB in stat->parts_size[1], ... + * The total size (sum of all parts) is stored in stat->size and + * stat->nr_parts will hold the number of parts. + * Only DVD_READ_TITLE_VOBS (VTS_??_[1-9].VOB) can be multipart files. + * + * This function is only of use if you want to get the size of each file + * in the filesystem. These sizes are not needed to use any other + * functions in libdvdread. + * + * @param dvd A dvd read handle. + * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0. + * @param domain Which domain. + * @param stat Pointer to where the result is stored. + * @return If successful 0, otherwise -1. + * + * int DVDFileStat(dvd, titlenum, domain, stat); + */ +int DVDFileStat(dvd_reader_t *, int, dvd_read_domain_t, dvd_stat_t *); + /** * Opens a file on the DVD given the title number and domain. * diff -ruib ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_udf.c ./dvd_udf.c --- ../../../../versions/libdvdread_patch2/libdvdread/src/dvd_udf.c 2008-10-10 16:20:12.000000000 +0900 +++ ./dvd_udf.c 2008-10-10 17:16:50.000000000 +0900 @@ -482,7 +482,7 @@ UDFICB( &data[ 16 ], FileType, &flags ); /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ - fad->Length = GETN4( 56 ); /* Was 4 bytes at 60, changed to 64-bit. */ + fad->Length = GETN8( 56 ); /* Was 4 bytes at 60, changed to 64-bit. */ L_EA = GETN4( 168 ); L_AD = GETN4( 172 );