📄 dvd_reader.c
字号:
break; default: fprintf( stderr, "libdvdread: Invalid domain for file open.\n" ); return NULL; } if( dvd->isImageFile ) { return DVDOpenFileUDF( dvd, filename ); } else { return DVDOpenFilePath( dvd, filename ); }}void DVDCloseFile( dvd_file_t *dvd_file ){ int i; if( dvd_file ) { if( dvd_file->dvd->isImageFile ) { ; } else { for( i = 0; i < 9; ++i ) { if( dvd_file->title_devs[ i ] ) { dvdinput_close( dvd_file->title_devs[i] ); } } } free( dvd_file ); dvd_file = 0; }}/* Internal, but used from dvd_udf.c */int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted ){ int ret; if( !device->dev ) { fprintf( stderr, "libdvdread: Fatal error in block read.\n" ); return 0; } ret = dvdinput_seek( device->dev, (int) lb_number ); if( ret != (int) lb_number ) { fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number ); return 0; } return dvdinput_read( device->dev, (char *) data, (int) block_count, encrypted );}/* This is using a single input and starting from 'dvd_file->lb_start' offset. * * Reads 'block_count' blocks from 'dvd_file' at block offset 'offset' * into the buffer located at 'data' and if 'encrypted' is set * descramble the data if it's encrypted. Returning either an * negative error or the number of blocks read. */static int DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset, size_t block_count, unsigned char *data, int encrypted ){ return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset, block_count, data, encrypted );}/* This is using possibly several inputs and starting from an offset of '0'. * * Reads 'block_count' blocks from 'dvd_file' at block offset 'offset' * into the buffer located at 'data' and if 'encrypted' is set * descramble the data if it's encrypted. Returning either an * negative error or the number of blocks read. */static int DVDReadBlocksPath( dvd_file_t *dvd_file, unsigned int offset, size_t block_count, unsigned char *data, int encrypted ){ int i; int ret, ret2, off; ret = 0; ret2 = 0; for( i = 0; i < 9; ++i ) { if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */ if( offset < dvd_file->title_sizes[ i ] ) { if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) { off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset ); if( off < 0 || off != (int)offset ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", offset ); return off < 0 ? off : 0; } ret = dvdinput_read( dvd_file->title_devs[ i ], data, (int)block_count, encrypted ); break; } else { size_t part1_size = dvd_file->title_sizes[ i ] - offset; /* FIXME: Really needs to be a while loop. * (This is only true if you try and read >1GB at a time) */ /* Read part 1 */ off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset ); if( off < 0 || off != (int)offset ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", offset ); return off < 0 ? off : 0; } ret = dvdinput_read( dvd_file->title_devs[ i ], data, (int)part1_size, encrypted ); if( ret < 0 ) return ret; /* FIXME: This is wrong if i is the last file in the set. * also error from this read will not show in ret. */ /* Does the next part exist? If not then return now. */ if( !dvd_file->title_devs[ i + 1 ] ) return ret; /* Read part 2 */ off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 ); if( off < 0 || off != 0 ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", 0 ); return off < 0 ? off : 0; } ret2 = dvdinput_read( dvd_file->title_devs[ i + 1 ], data + ( part1_size * (int64_t)DVD_VIDEO_LB_LEN ), (int)(block_count - part1_size), encrypted ); if( ret2 < 0 ) return ret2; break; } } else { offset -= dvd_file->title_sizes[ i ]; } } return ret + ret2;}/* This is broken reading more than 2Gb at a time is ssize_t is 32-bit. */ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset, size_t block_count, unsigned char *data ){ int ret; /* Check arguments. */ if( dvd_file == NULL || offset < 0 || data == NULL ) return -1; /* Hack, and it will still fail for multiple opens in a threaded app ! */ if( dvd_file->dvd->css_title != dvd_file->css_title ) { dvd_file->dvd->css_title = dvd_file->css_title; if( dvd_file->dvd->isImageFile ) { dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start ); } /* Here each vobu has it's own dvdcss handle, so no need to update else { dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start ); }*/ } if( dvd_file->dvd->isImageFile ) { ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset, block_count, data, DVDINPUT_READ_DECRYPT ); } else { ret = DVDReadBlocksPath( dvd_file, (unsigned int)offset, block_count, data, DVDINPUT_READ_DECRYPT ); } return (ssize_t)ret;}int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset ){ /* Check arguments. */ if( dvd_file == NULL || offset < 0 ) return -1; if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) { return -1; } dvd_file->seek_pos = (uint32_t) offset; return offset;}ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size ){ unsigned char *secbuf; unsigned int numsec, seek_sector, seek_byte; int ret; /* Check arguments. */ if( dvd_file == NULL || data == NULL ) return -1; seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN; seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN; numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 ); secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN ); if( !secbuf ) { fprintf( stderr, "libdvdread: Can't allocate memory " "for file read!\n" ); return 0; } if( dvd_file->dvd->isImageFile ) { ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector, (size_t) numsec, secbuf, DVDINPUT_NOFLAGS ); } else { ret = DVDReadBlocksPath( dvd_file, seek_sector, (size_t) numsec, secbuf, DVDINPUT_NOFLAGS ); } if( ret != (int) numsec ) { free( secbuf ); return ret < 0 ? ret : 0; } memcpy( data, &(secbuf[ seek_byte ]), byte_size ); free( secbuf ); dvd_file->seek_pos += byte_size; return byte_size;}ssize_t DVDFileSize( dvd_file_t *dvd_file ){ /* Check arguments. */ if( dvd_file == NULL ) return -1; return dvd_file->filesize;}int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid ){ struct md5_ctx ctx; int title; /* Check arguments. */ if( dvd == NULL || discid == NULL ) return 0; /* Go through the first 10 IFO:s, in order, * and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */ md5_init_ctx( &ctx ); for( title = 0; title < 10; title++ ) { dvd_file_t *dvd_file = DVDOpenFile( dvd, title, DVD_READ_INFO_FILE ); if( dvd_file != NULL ) { ssize_t bytes_read; size_t file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN; char *buffer = malloc( file_size ); if( buffer == NULL ) { fprintf( stderr, "libdvdread: DVDDiscId, failed to " "allocate memory for file read!\n" ); return -1; } bytes_read = DVDReadBytes( dvd_file, buffer, file_size ); if( bytes_read != file_size ) { fprintf( stderr, "libdvdread: DVDDiscId read returned %d bytes" ", wanted %d\n", bytes_read, file_size ); DVDCloseFile( dvd_file ); return -1; } md5_process_bytes( buffer, file_size, &ctx ); DVDCloseFile( dvd_file ); free( buffer ); } } md5_finish_ctx( &ctx, discid ); return 0;}int DVDISOVolumeInfo( dvd_reader_t *dvd, char *volid, unsigned int volid_size, unsigned char *volsetid, unsigned int volsetid_size ){ unsigned char *buffer; int ret; /* Check arguments. */ if( dvd == NULL ) return 0; if( dvd->dev == NULL ) { /* No block access, so no ISO... */ return -1; } buffer = malloc( DVD_VIDEO_LB_LEN ); if( buffer == NULL ) { fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to " "allocate memory for file read!\n" ); return -1; } ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 ); if( ret != 1 ) { fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to " "read ISO9660 Primary Volume Descriptor!\n" ); return -1; } if( (volid != NULL) && (volid_size > 0) ) { unsigned int n; for(n = 0; n < 32; n++) { if(buffer[40+n] == 0x20) { break; } } if(volid_size > n+1) { volid_size = n+1; } memcpy(volid, &buffer[40], volid_size-1); volid[volid_size-1] = '\0'; } if( (volsetid != NULL) && (volsetid_size > 0) ) { if(volsetid_size > 128) { volsetid_size = 128; } memcpy(volsetid, &buffer[190], volsetid_size); } return 0;}int DVDUDFVolumeInfo( dvd_reader_t *dvd, char *volid, unsigned int volid_size, unsigned char *volsetid, unsigned int volsetid_size ){ int ret; /* Check arguments. */ if( dvd == NULL ) return -1; if( dvd->dev == NULL ) { /* No block access, so no UDF VolumeSet Identifier */ return -1; } if( (volid != NULL) && (volid_size > 0) ) { ret = UDFGetVolumeIdentifier(dvd, volid, volid_size); if(!ret) { return -1; } } if( (volsetid != NULL) && (volsetid_size > 0) ) { ret = UDFGetVolumeSetIdentifier(dvd, volsetid, volsetid_size); if(!ret) { return -1; } } return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -