⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvd_reader.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
      fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );    }    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 ) {        if(dvd->verbose >= 1) {          fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );        }        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;  uint32_t size;  /* 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:    if(dvd->verbose >= 1) {      fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );    }    errno = EINVAL;    return -1;  }    if( dvd->isImageFile ) {    if( UDFFindFile( dvd, filename, &size ) ) {      statbuf->size = size;      statbuf->nr_parts = 1;      statbuf->parts_size[0] = size;      return 0;    }  } else {    if( findDVDFile( dvd, filename, full_path ) )  {      if( stat( full_path, &fileinfo ) < 0 ) {        if(dvd->verbose >= 1) {          fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );        }      } 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  * * @param device A read handle. * @param lb_number Logical block number to start read from. * @param block_count Number of logical blocks to read. * @param data Pointer to buffer where read data should be stored. *             This buffer must be large enough to hold lb_number*2048 bytes. *             The pointer must be aligned to the logical block size when *             reading from a raw/O_DIRECT device. * @param encrypted 0 if no decryption shall be performed, *                  1 if decryption shall be performed * @param return Returns number of blocks read on success, negative on error */int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,                      size_t block_count, unsigned char *data,                       int encrypted ){  int ret;  if( !device->dev ) {    if(device->verbose >= 1) {      fprintf( stderr, "libdvdread: Fatal error in block read.\n" );    }    return 0;  }  ret = dvdinput_seek( device->dev, (int) lb_number );  if( ret != (int) lb_number ) {    if(device->verbose >= 1) {      fprintf( stderr,               "libdvdread: UDFReadBlocksRaw: 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. * * @param data Pointer to buffer where read data should be placed. *             This buffer must be large enough to hold block_count*2048 bytes. *             The pointer must be aligned to 2048 bytes when reading from *             a raw/O_DIRECT device. * @return Returns the number of blocks read on success or a negative error. */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'. * data must be aligned to logical block size (2048 bytes) of the device * for raw/O_DIRECT devices to work * 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. * * @param dvd_file A file read handle. * @param offset Block offset from start of file. * @return Returns number of blocks read on success, negative on error. */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 ) {          if(dvd_file->dvd->verbose >= 1) {            fprintf( stderr, "libdvdread: DVDReadBlocksPath1: 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 ) {          if(dvd_file->dvd->verbose >= 1) {            fprintf( stderr, "libdvdread: DVDReadBlocksPath2: 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 ) {          if(dvd_file->dvd->verbose >= 1) {            fprintf( stderr, "libdvdread: DVDReadBlocksPath3: 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 if 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;}int DVDFileSeek( dvd_file_t *dvd_file, int 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;}#ifndef HAVE_UINTPTR_T#warning "Assuming that (unsigned long) can hold (void *)"typedef unsigned long uintptr_t;#endif#define DVD_ALIGN(ptr) (void *)((((uintptr_t)(ptr)) + (DVD_VIDEO_LB_LEN-1)) \                                / DVD_VIDEO_LB_LEN * DVD_VIDEO_LB_LEN)ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size ){  unsigned char *secbuf_start;  unsigned char *secbuf; //must be aligned to 2048-bytes for raw/O_DIRECT  unsigned int numsec, seek_sector, seek_byte;  int ret;      /* Check arguments. */  if( dvd_file == NULL || data == NULL ) {    errno = EINVAL;    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 );  /* must align to 2048 bytes if we are reading from raw/O_DIRECT */  secbuf_start = (unsigned char *) malloc( (numsec+1) * DVD_VIDEO_LB_LEN );  if( !secbuf_start ) {    /* errno will be set to ENOMEM by malloc */    return -1;  }  secbuf = DVD_ALIGN(secbuf_start);  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_start );    return ret < 0 ? ret : 0;  }  memcpy( data, &(secbuf[ seek_byte ]), byte_size );  free( secbuf_start );  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;  int nr_of_files = 0;  int tmp_errno;  int nofiles_errno = ENOENT;  /* Check arguments. */  if( dvd == NULL || discid == NULL ) {    errno = EINVAL;    return -1;  }  /* 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 );      nr_of_files++;      if( buffer == NULL ) {        /* errno will be set to ENOMEM by malloc */        return -1;      }      bytes_read = DVDReadBytes( dvd_file, buffer, file_size );      if( bytes_read != file_size ) {        tmp_errno = errno;        if(dvd->verbose >= 1) {          fprintf( stderr, "libdvdread: DVDDiscId read returned %d bytes"                   ", wanted %d\n", (int)bytes_read, (int)file_size );        }        free(buffer);        DVDCloseFile( dvd_file );        errno = tmp_errno;        return -1;      }                  md5_process_bytes( buffer, file_size,  &ctx );                  DVDCloseFile( dvd_file );      free( buffer );    } else {      if(errno != ENOENT) {        nofiles_errno = errno;      }    }  }  md5_finish_ctx( &ctx, discid );  if(nr_of_files == 0) {    errno = nofiles_errno;    return -1;  }  return 0;}int DVDISOVolumeInfo( dvd_reader_t *dvd,                      char *volid, unsigned int volid_size,                      unsigned char *volsetid, unsigned int volsetid_size ){  unsigned char *buffer; /* must be aligned to 2048 for raw/O_DIRECT */  unsigned char *buffer_start;   int ret;  /* Check arguments. */  if( dvd == NULL ) {    errno = EINVAL;    return -1;  }    if( dvd->dev == NULL ) {    /* No block access, so no ISO... */    errno = EINVAL;    return -1;  }    buffer_start = malloc( 2 * DVD_VIDEO_LB_LEN );  if( buffer_start == NULL ) {    return -1;  }  buffer = DVD_ALIGN(buffer_start);    ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );  if( ret != 1 ) {    if(dvd->verbose >= 1) {      fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "               "read ISO9660 Primary Volume Descriptor!\n" );    }    free(buffer_start);    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);  }  free(buffer_start);  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 + -