Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
dvd_file.c
Package: dvd-munitions.tar.gz [view]
Upload User: aoeyumen
Upload Date: 2007-01-06
Package Size: 3329k
Code Size: 8k
Category:
DVD
Development Platform:
Unix_Linux
- /*
- * dvdfile: access to the content of a DVD Video via mounted filesystem
- * Copyright (C) 1999 Christian Wolff for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- * The author can be reached at scarabaeus@convergence.de,
- * the project's page is at http://linuxtv.org/dvd/
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <dirent.h>
- #include <limits.h>
- #include <string.h>
- #include "dvd_file.h"
- // hmm what would be the best place to put these def's?
- #define INFOFILE ".IFO" // File Extension of Info Files
- #define INFOBACKUP ".BUP" // File Extension of Info File Backups
- #define VIDEOOBJECT ".VOB" // File Extension of Video Objects
- #define VIDEOPATH "VIDEO_TS" // /dvd/VIDEO_TS
- #define DISCINDEX "VIDEO_TS" // /dvd/VIDEO_TS/VIDEO_TS.VOB or VIDEO_TS.IFO
- #define TITLEFORMAT "VTS_%02d_%d" // e.g. /dvd/VIDEO_TS/VTS_01_1.VOB or VTS_01_0.IFO
- // information for read_LB
- int currentvtsn;
- int currentsegment;
- long int segmentlength[10];
- FILE* movie;
- FILE* menumovie;
- char Videopath[PATH_MAX]=""; // Path to the DVD Video
- int LB_Len=2048; // length of one logical block
- // searches for <file> in directory <path>, ignoring case
- // returns 0 and full filename in <filename>
- // or -1 on file not found
- // or -2 on path not found
- int find_file(const char *path, const char *file, char *filename) {
- DIR *dir;
- struct dirent *ent;
- if ((dir=opendir(path))==NULL) return -2;
- while ((ent=readdir(dir))!=NULL) {
- if (!strcasecmp(ent->d_name,file)) {
- sprintf(filename,"%s%s%s",path,((path[strlen(path)-1]=='/')?"":"/"),ent->d_name);
- return 0;
- }
- }
- return -1;
- }
- // Reads IFO File or IFO Backup File
- // vtsn is 0 for VIDEO_TS.IFO, or 1 thru 99 for VTS_xx_0.IFO (where xx is vtsn)
- // if backup is zero, first the IFO and then, on failure, the BUP will be read.
- // if backup is not zero, only the backup file will be read (.BUP)
- // *infodata will be allocated to size of file
- // returns 0 on error, number of blocks read on success
- int FileReadIFO(int vtsn, int backup, unsigned char **infodata) {
- char filename[PATH_MAX];
- char filename_ifo[PATH_MAX];
- char filename_bup[PATH_MAX];
- long int infolength;
- int blocks;
- FILE* info;
- *infodata=NULL;
- if (strlen(Videopath)==0) return 0; // No dvd root set
- if ((vtsn<0) || (vtsn>99)) return 0; // illegal title number
- if (vtsn) {
- sprintf(filename_ifo,TITLEFORMAT,vtsn,0);
- } else {
- strcpy(filename_ifo,DISCINDEX);
- }
- strcpy(filename_bup,filename_ifo);
- strcat(filename_ifo,INFOFILE);
- strcat(filename_bup,INFOBACKUP);
- while (1) {
- if (backup) strcpy(filename_ifo,filename_bup);
- if (find_file(Videopath,filename_ifo,filename)) {
- if (backup++) return 0;
- continue;
- }
- if ((info=fopen(filename,"r"))==NULL) {
- if (backup++) return 0;
- continue;
- }
- fseek(info,0L,SEEK_END); // go to end
- infolength=ftell(info);
- fseek(info,0L,SEEK_SET); // go to start
- blocks=(infolength-1)/LB_Len;
- if ((*infodata=(char *)malloc((blocks+1)*LB_Len))==NULL) return 0;
- if (!fread(*infodata,(blocks+1)*LB_Len,1,info)) {
- free(*infodata);
- *infodata=NULL;
- if (backup++) return 0;
- continue;
- } else return blocks;
- }
- }
- // opens the vob file of the video manager
- // returns 0 on success, 1 on error
- int open_menumovie(void) {
- char filename[PATH_MAX];
- if (find_file(Videopath,DISCINDEX VIDEOOBJECT,filename)) return 1; // file not existing
- if ((menumovie=fopen(filename,"r"))==NULL) return 1; // file not readable
- return 0;
- }
- // reads Logical Block of a vmg menu (VIDEO_TS.VOB)
- // return 0 on success, >0 on error
- int FileReadVMGM(long int lbnum, unsigned char *data) {
- if (strlen(Videopath)==0) return 1; // No dvd root set
- if (menumovie==NULL) open_menumovie();
- if (fseek(menumovie,lbnum*LB_Len,SEEK_SET)<0) return 1; // position not found
- return (!fread(data,LB_Len,1,menumovie));
- }
- // updates the segment length table of a video title set
- // stores the length of VTS_xx_0.VOB thru VTS_xx_9.VOB into an array
- // returns 0 on success, >0 on error
- int update_segments(int vtsn) {
- char file[PATH_MAX];
- char filename[PATH_MAX];
- int segment;
- if ((vtsn<1) || (vtsn>99)) return 1; // wrong VTS number
- currentvtsn=vtsn;
- if (currentsegment>=0) fclose(movie);
- currentsegment=-1;
- for (segment=0; segment<10; segment++) {
- sprintf(file,TITLEFORMAT VIDEOOBJECT,vtsn,segment);
- if (find_file(Videopath,file,filename)) segmentlength[segment]=0; // file not existing
- else if ((movie=fopen(filename,"r"))==NULL) segmentlength[segment]=0; // file not readable
- else {
- fseek(movie,0L,SEEK_END);
- segmentlength[segment]=ftell(movie);
- fclose(movie);
- }
- }
- return 0;
- }
- // opens one sement of a VTS
- // returns 0 on success, >0 on error
- int open_segment(int vtsn, int segment) {
- char file[PATH_MAX];
- char filename[PATH_MAX];
- if (currentsegment>=0) fclose(movie);
- currentsegment=-1;
- sprintf(file,TITLEFORMAT VIDEOOBJECT,vtsn,segment);
- if (find_file(Videopath,file,filename)) return 1; // file not existing
- if ((movie=fopen(filename,"r"))==NULL) return 1; // file not readable
- currentsegment=segment;
- return 0;
- }
- // reads Logical Block of a vts menu
- // vtsn is 1 thru 99 for VTS_xx_0.VOB (where xx is vtsn)
- // return 0 on success, >0 on error
- int FileReadVTSM(int vtsn, long int lbnum, unsigned char *data) {
- long int offset;
- if (strlen(Videopath)==0) return 1; // No dvd root set
- if ((vtsn<1) || (vtsn>99)) return 1; // wrong vts number
- offset=lbnum*LB_Len;
- if (currentvtsn!=vtsn) { // have to update segment table?
- update_segments(vtsn);
- }
- if (offset>=segmentlength[0]) return 1; // seek beyond EOF
- if (currentsegment!=0)
- if (open_segment(vtsn,0)) return 1; // open failed
- if (fseek(movie,offset,SEEK_SET)<0) return 1; // position not found
- return (!fread(data,LB_Len,1,movie));
- }
- // reads Logical Block of a video title set
- // vtsn is 1 thru 99 for VTS_xx_y.VOB (where xx is vtsn and y is 1 thru 9)
- // return 0 on success, 1 on error
- int FileReadVTS(int vtsn, long int lbnum, unsigned char *data) {
- long int offset;
- int segment;
- if (strlen(Videopath)==0) return 1; // No dvd root set
- if ((vtsn<1) || (vtsn>99)) return 1; // wrong vts number
- offset=lbnum*LB_Len;
- if (currentvtsn!=vtsn) { // have to update segment table?
- update_segments(vtsn);
- }
- segment=1;
- while (segment<10) {
- if (segmentlength[segment]<=offset) { // that's not our segment yet
- offset-=segmentlength[segment]; // skip to next segment
- segment++;
- } else { // our segment
- if (currentsegment!=segment)
- if (open_segment(vtsn,segment)) return 1;
- if (fseek(movie,offset,SEEK_SET)<0) break; // position not found
- return (!fread(data,LB_Len,1,movie));
- }
- }
- return 1; // seek beyond EOF
- }
- // Set the path to the UDF mounted DVD disc
- // Or the Path to the VIDEO_TS directory
- // returns 0 on success, -1 on 'dvd not found', -2 on 'path not found'
- int FileSetVideoPath(char *Path, int LB_Length) {
- int err;
- LB_Len=LB_Length; // the Block Length we use
- currentvtsn=-1; // no VTS open yet
- currentsegment=-1; // no segment open yet
- if ((err=find_file(Path,VIDEOPATH,Videopath))) { // dvd inserted?
- if (find_file(Path,DISCINDEX INFOFILE,Videopath)) { // does path already point
- if (find_file(Path,DISCINDEX INFOBACKUP,Videopath)) { // into VIDEO_TS dir?
- return err;
- } else strcpy(Videopath,Path);
- } else strcpy(Videopath,Path);
- }
- return 0;
- }