summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-12-24 16:27:35 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-12-24 16:27:35 -0600
commitb21d0b9415f69d5306a9106fdf4562114cc37df6 (patch)
tree5237afd714c996179cb73c2c9452243e2615cc0f
parent2fd0830c705f839c25377644ce188c9fdfefae55 (diff)
downloadk9copy-b21d0b94.tar.gz
k9copy-b21d0b94.zip
Finish removing internal libdvdread copy
This completes the task started in GIT hash 71c6fa
-rw-r--r--dvdread/Makefile.am8
-rw-r--r--dvdread/bswap.h126
-rw-r--r--dvdread/dvd_input.c414
-rw-r--r--dvdread/dvd_input.h55
-rw-r--r--dvdread/dvd_reader.c1614
-rw-r--r--dvdread/dvd_reader.h344
-rw-r--r--dvdread/dvd_udf.c1216
-rw-r--r--dvdread/dvd_udf.h66
-rw-r--r--dvdread/dvdread_internal.h18
-rw-r--r--dvdread/ifo_read.c2181
-rw-r--r--dvdread/ifo_read.h228
-rw-r--r--dvdread/ifo_types.h893
-rw-r--r--dvdread/md5.c407
-rw-r--r--dvdread/md5.h162
-rw-r--r--dvdread/nav_read.c209
-rw-r--r--dvdread/nav_read.h52
-rw-r--r--dvdread/nav_types.h307
17 files changed, 0 insertions, 8300 deletions
diff --git a/dvdread/Makefile.am b/dvdread/Makefile.am
deleted file mode 100644
index 5c9fddf..0000000
--- a/dvdread/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libdvdread.la
-libdvdread_la_LDFLAGS = $(all_libraries)
-libdvdread_la_SOURCES = dvd_input.c dvd_reader.c dvd_udf.c ifo_read.c md5.c \
- nav_read.c
-noinst_HEADERS = bswap.h dvd_input.h dvd_reader.h dvd_udf.h dvdread_internal.h \
- ifo_read.h ifo_types.h md5.h nav_read.h nav_types.h
diff --git a/dvdread/bswap.h b/dvdread/bswap.h
deleted file mode 100644
index 11c9774..0000000
--- a/dvdread/bswap.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef BSWAP_H_INCLUDED
-#define BSWAP_H_INCLUDED
-
-/*
- * Copyright (C) 2000, 2001 Billy Biggs <vektor@dumbterm.net>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if defined(WORDS_BIGENDIAN)
-/* All bigendian systems are fine, just ignore the swaps. */
-#define B2N_16(x) (void)(x)
-#define B2N_32(x) (void)(x)
-#define B2N_64(x) (void)(x)
-
-#else
-
-/* For __FreeBSD_version */
-#if defined(HAVE_SYS_PARAM_H)
-#include <sys/param.h>
-#endif
-
-#if defined(__linux__)
-#include <byteswap.h>
-#define B2N_16(x) x = bswap_16(x)
-#define B2N_32(x) x = bswap_32(x)
-#define B2N_64(x) x = bswap_64(x)
-
-#elif defined(__NetBSD__)
-#include <sys/endian.h>
-#define B2N_16(x) BE16TOH(x)
-#define B2N_32(x) BE32TOH(x)
-#define B2N_64(x) BE64TOH(x)
-
-#elif defined(__OpenBSD__)
-#include <sys/endian.h>
-#define B2N_16(x) x = swap16(x)
-#define B2N_32(x) x = swap32(x)
-#define B2N_64(x) x = swap64(x)
-
-#elif defined(__FreeBSD__) && __FreeBSD_version >= 470000
-#include <sys/endian.h>
-#define B2N_16(x) x = be16toh(x)
-#define B2N_32(x) x = be32toh(x)
-#if __FreeBSD_version >= 500000
-#define B2N_64(x) x = be64toh(x)
-#else
-#define B2N_64(x) \
- x = ((((x) & 0xff00000000000000) >> 56) | \
- (((x) & 0x00ff000000000000) >> 40) | \
- (((x) & 0x0000ff0000000000) >> 24) | \
- (((x) & 0x000000ff00000000) >> 8) | \
- (((x) & 0x00000000ff000000) << 8) | \
- (((x) & 0x0000000000ff0000) << 24) | \
- (((x) & 0x000000000000ff00) << 40) | \
- (((x) & 0x00000000000000ff) << 56))
-#endif /* _FreeBSD_version >= 500000 */
-
-#elif defined(__DragonFly__)
-#include <sys/endian.h>
-#define B2N_16(x) x = be16toh(x)
-#define B2N_32(x) x = be32toh(x)
-#define B2N_64(x) x = be64toh(x)
-
-
-#elif defined(__APPLE__) || defined(__DARWIN__)
-#include <libkern/OSByteOrder.h>
-#define B2N_16(x) x = OSSwapBigToHostConstInt16(x)
-#define B2N_32(x) x = OSSwapBigToHostConstInt32(x)
-#define B2N_64(x) x = OSSwapBigToHostConstInt64(x)
-
-#else
-#if defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(WIN32) || defined(__BEOS__) || defined(__INTERIX)
-/* These systems don't have swap macros */
-#else
-/* If there isn't a header provided with your system with this functionality
- * add the relevant || define( ) to the list above.
- */
-#warning "You should add endian swap macros for your system"
-#endif
-
-/* This is a slow but portable implementation, it has multiple evaluation
- * problems so beware.
- * Old FreeBSD's and Solaris don't have <byteswap.h> or any other such
- * functionality!
- */
-
-#define B2N_16(x) \
- x = ((((x) & 0xff00) >> 8) | \
- (((x) & 0x00ff) << 8))
-#define B2N_32(x) \
- x = ((((x) & 0xff000000) >> 24) | \
- (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | \
- (((x) & 0x000000ff) << 24))
-#define B2N_64(x) \
- x = ((((x) & 0xff00000000000000) >> 56) | \
- (((x) & 0x00ff000000000000) >> 40) | \
- (((x) & 0x0000ff0000000000) >> 24) | \
- (((x) & 0x000000ff00000000) >> 8) | \
- (((x) & 0x00000000ff000000) << 8) | \
- (((x) & 0x0000000000ff0000) << 24) | \
- (((x) & 0x000000000000ff00) << 40) | \
- (((x) & 0x00000000000000ff) << 56))
-
-
-
-#endif
-
-#endif /* WORDS_BIGENDIAN */
-
-#endif /* BSWAP_H_INCLUDED */
diff --git a/dvdread/dvd_input.c b/dvdread/dvd_input.c
deleted file mode 100644
index 99ddd2d..0000000
--- a/dvdread/dvd_input.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 2002 Samuel Hocevar <sam@zoy.org>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#define __USE_GNU /* to get O_DIRECT in linux */
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "dvd_reader.h"
-#include "dvd_input.h"
-
-#include "dvdread_internal.h"
-
-/* The function pointers that is the exported interface of this file. */
-dvd_input_t (*dvdinput_open) (const char *);
-int (*dvdinput_close) (dvd_input_t);
-int (*dvdinput_seek) (dvd_input_t, int);
-int (*dvdinput_title) (dvd_input_t, int);
-/**
- * pointer must be aligned to 2048 bytes
- * if reading from a raw/O_DIRECT file
- */
-int (*dvdinput_read) (dvd_input_t, void *, int, int);
-
-char * (*dvdinput_error) (dvd_input_t);
-
-#ifdef HAVE_DVDCSS_DVDCSS_H
-/* linking to libdvdcss */
-#include <dvdcss/dvdcss.h>
-#define DVDcss_open(a) dvdcss_open((char*)(a))
-#define DVDcss_close dvdcss_close
-#define DVDcss_seek dvdcss_seek
-#define DVDcss_title dvdcss_title
-#define DVDcss_read dvdcss_read
-#define DVDcss_error dvdcss_error
-#else
-/* dlopening libdvdcss */
-#include <dlfcn.h>
-typedef struct dvdcss_s *dvdcss_handle;
-static dvdcss_handle (*DVDcss_open) (const char *);
-static int (*DVDcss_close) (dvdcss_handle);
-static int (*DVDcss_seek) (dvdcss_handle, int, int);
-static int (*DVDcss_title) (dvdcss_handle, int);
-static int (*DVDcss_read) (dvdcss_handle, void *, int, int);
-static char * (*DVDcss_error) (dvdcss_handle);
-#endif
-
-/* The DVDinput handle, add stuff here for new input methods. */
-struct dvd_input_s {
- /* libdvdcss handle */
- dvdcss_handle dvdcss;
-
- /* dummy file input */
- int fd;
-};
-
-
-/**
- * initialize and open a DVD device or file.
- */
-static dvd_input_t css_open(const char *target)
-{
- dvd_input_t dev;
-
- /* Allocate the handle structure */
- dev = (dvd_input_t) malloc(sizeof(struct dvd_input_s));
- if(dev == NULL) {
- /* malloc has set errno to ENOMEM */
- return NULL;
- }
-
- /* Really open it with libdvdcss */
- dev->dvdcss = DVDcss_open(target);
- if(dev->dvdcss == 0) {
- free(dev);
- dev = NULL;
- }
-
- return dev;
-}
-
-/**
- * return the last error message
- */
-static char *css_error(dvd_input_t dev)
-{
- return DVDcss_error(dev->dvdcss);
-}
-
-/**
- * seek into the device.
- */
-static int css_seek(dvd_input_t dev, int blocks)
-{
- /* DVDINPUT_NOFLAGS should match the DVDCSS_NOFLAGS value. */
- return DVDcss_seek(dev->dvdcss, blocks, DVDINPUT_NOFLAGS);
-}
-
-/**
- * set the block for the begining of a new title (key).
- */
-static int css_title(dvd_input_t dev, int block)
-{
- return DVDcss_title(dev->dvdcss, block);
-}
-
-/**
- * read data from the device.
- */
-static int css_read(dvd_input_t dev, void *buffer, int blocks, int flags)
-{
- return DVDcss_read(dev->dvdcss, buffer, blocks, flags);
-}
-
-/**
- * close the DVD device and clean up the library.
- */
-static int css_close(dvd_input_t dev)
-{
- int ret;
-
- ret = DVDcss_close(dev->dvdcss);
-
- if(ret < 0)
- return ret;
-
- free(dev);
-
- return 0;
-}
-
-/* Need to use O_BINARY for WIN32 */
-#ifndef O_BINARY
-#ifdef _O_BINARY
-#define O_BINARY _O_BINARY
-#else
-#define O_BINARY 0
-#endif
-#endif
-
-/**
- * initialize and open a DVD device or file.
- */
-static dvd_input_t file_open(const char *target)
-{
- dvd_input_t dev;
- char *use_odirect;
- int oflags;
-
- oflags = O_RDONLY | O_BINARY;
- use_odirect = getenv("DVDREAD_USE_DIRECT");
- if(use_odirect) {
-#ifndef O_DIRECT
-#define O_DIRECT 0
-#endif
- oflags |= O_DIRECT;
- }
- /* Allocate the library structure */
- dev = (dvd_input_t) malloc(sizeof(struct dvd_input_s));
- if(dev == NULL) {
- return NULL;
- }
-
- /* Open the device */
- dev->fd = open(target, oflags);
- if(dev->fd < 0) {
- free(dev);
- return NULL;
- }
-
- return dev;
-}
-
-/**
- * return the last error message
- */
-static char *file_error(dvd_input_t dev)
-{
- /* use strerror(errno)? */
- return (char *)"unknown error";
-}
-
-/**
- * seek into the device.
- */
-static int file_seek(dvd_input_t dev, int blocks)
-{
- off_t pos = (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN;
-
- pos = lseek(dev->fd, pos, SEEK_SET);
- if(pos < 0) {
- return pos;
- }
- /* assert pos % DVD_VIDEO_LB_LEN == 0 */
- return (int) (pos / DVD_VIDEO_LB_LEN);
-}
-
-/**
- * set the block for the begining of a new title (key).
- */
-static int file_title(dvd_input_t dev, int block)
-{
- return -1;
-}
-
-/**
- * read data from the device.
- */
-static int file_read(dvd_input_t dev, void *buffer, int blocks, int flags)
-{
- size_t len;
- ssize_t ret;
- unsigned char *buf = buffer;
-
- len = (size_t)blocks * DVD_VIDEO_LB_LEN;
-
- while(len > 0) {
-
- ret = read(dev->fd, buf, len);
-
- if(ret < 0) {
- /* One of the reads failed, too bad. We won't even bother
- * returning the reads that went ok, and as in the posix spec
- * the file postition is left unspecified after a failure. */
- return ret;
- }
-
- if(ret == 0) {
- /* Nothing more to read. Return the whole blocks, if any, that we got.
- and adjust the file possition back to the previous block boundary. */
- size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len;
- off_t over_read = -(bytes % DVD_VIDEO_LB_LEN);
- /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR);
- /* should have pos % 2048 == 0 */
- return (int) (bytes / DVD_VIDEO_LB_LEN);
- }
-
- buf+=ret;
- len -= ret;
- }
-
- return blocks;
-}
-
-/**
- * close the DVD device and clean up.
- */
-static int file_close(dvd_input_t dev)
-{
- int ret;
-
- ret = close(dev->fd);
-
- if(ret < 0)
- return ret;
-
- free(dev);
-
- return 0;
-}
-
-
-static void *dvdcss_library = NULL;
-static int dvdcss_library_init = 0;
-
-/**
- * Free any objects allocated by dvdinput_setup.
- * Should only be called when libdvdread is not to be used any more.
- * Closes dlopened libraries.
- */
-void dvdinput_free(void)
-{
-#ifdef HAVE_DVDCSS_DVDCSS_H
- /* linked statically, nothing to free */
- return;
-#else
- if(dvdcss_library) {
- dlclose(dvdcss_library);
- dvdcss_library = NULL;
- }
- dvdcss_library_init = 0;
- return;
-#endif
-}
-
-
-/**
- * Setup read functions with either libdvdcss or minimal DVD access.
- */
-int dvdinput_setup(void)
-{
- char **dvdcss_version = NULL;
- int verbose;
-
- /* dlopening libdvdcss */
- if(dvdcss_library_init) {
- /* libdvdcss is already dlopened, function ptrs set */
- if(dvdcss_library) {
- return 1; /* css available */
- } else {
- return 0; /* css not available */
- }
- }
-
- verbose = get_verbose();
-
-#ifdef HAVE_DVDCSS_DVDCSS_H
- /* linking to libdvdcss */
- dvdcss_library = &dvdcss_library; /* Give it some value != NULL */
- /* the DVDcss_* functions have been #defined at the top */
- dvdcss_version = &dvdcss_interface_2;
-
-#else
-
- dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY);
-
- if(dvdcss_library != NULL) {
-#if defined(__OpenBSD__) && !defined(__ELF__)
-#define U_S "_"
-#else
-#define U_S
-#endif
- DVDcss_open = (dvdcss_handle (*)(const char*))
- dlsym(dvdcss_library, U_S "dvdcss_open");
- DVDcss_close = (int (*)(dvdcss_handle))
- dlsym(dvdcss_library, U_S "dvdcss_close");
- DVDcss_title = (int (*)(dvdcss_handle, int))
- dlsym(dvdcss_library, U_S "dvdcss_title");
- DVDcss_seek = (int (*)(dvdcss_handle, int, int))
- dlsym(dvdcss_library, U_S "dvdcss_seek");
- DVDcss_read = (int (*)(dvdcss_handle, void*, int, int))
- dlsym(dvdcss_library, U_S "dvdcss_read");
- DVDcss_error = (char* (*)(dvdcss_handle))
- dlsym(dvdcss_library, U_S "dvdcss_error");
-
- dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2");
-
- if(dlsym(dvdcss_library, U_S "dvdcss_crack")) {
- if(verbose >= 0) {
- fprintf(stderr,
- "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n"
- "libdvdread: You should get the latest version from "
- "http://www.videolan.org/\n" );
- }
- dlclose(dvdcss_library);
- dvdcss_library = NULL;
- } else if(!DVDcss_open || !DVDcss_close || !DVDcss_title || !DVDcss_seek
- || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
- if(verbose >= 0) {
- fprintf(stderr, "libdvdread: Missing symbols in libdvdcss.so.2, "
- "this shouldn't happen !\n");
- }
- dlclose(dvdcss_library);
- dvdcss_library = NULL;
- }
- }
-#endif /* HAVE_DVDCSS_DVDCSS_H */
-
- dvdcss_library_init = 1;
-
- if(dvdcss_library) {
- /*
- char *psz_method = getenv( "DVDCSS_METHOD" );
- char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
- fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method);
- fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
- */
- if(verbose >= 1) {
- fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
- *dvdcss_version);
- }
- /* libdvdcss wrapper functions */
- dvdinput_open = css_open;
- dvdinput_close = css_close;
- dvdinput_seek = css_seek;
- dvdinput_title = css_title;
- dvdinput_read = css_read;
- dvdinput_error = css_error;
- return 1;
-
- } else {
- if(verbose >= 1) {
- fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n");
- }
- /* libdvdcss replacement functions */
- dvdinput_open = file_open;
- dvdinput_close = file_close;
- dvdinput_seek = file_seek;
- dvdinput_title = file_title;
- dvdinput_read = file_read;
- dvdinput_error = file_error;
- return 0;
- }
-}
diff --git a/dvdread/dvd_input.h b/dvdread/dvd_input.h
deleted file mode 100644
index bc9544d..0000000
--- a/dvdread/dvd_input.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef DVD_INPUT_H_INCLUDED
-#define DVD_INPUT_H_INCLUDED
-
-/*
- * Copyright (C) 2001, 2002 Samuel Hocevar <sam@zoy.org>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
- */
-
-/**
- * Defines and flags. Make sure they fit the libdvdcss API!
- */
-#define DVDINPUT_NOFLAGS 0
-
-#define DVDINPUT_READ_DECRYPT (1 << 0)
-
-typedef struct dvd_input_s *dvd_input_t;
-
-/**
- * Pointers which will be filled either the input methods functions.
- */
-extern dvd_input_t (*dvdinput_open) (const char *);
-extern int (*dvdinput_close) (dvd_input_t);
-extern int (*dvdinput_seek) (dvd_input_t, int);
-extern int (*dvdinput_title) (dvd_input_t, int);
-extern int (*dvdinput_read) (dvd_input_t, void *, int, int);
-extern char * (*dvdinput_error) (dvd_input_t);
-
-/**
- * Free any objects allocated by dvdinput_setup.
- * Should only be called when libdvdread is not to be used any more.
- * Closes dlopened libraries.
- */
-void dvdinput_free(void);
-
-/**
- * Setup function accessed by dvd_reader.c. Returns 1 if there is CSS support.
- */
-int dvdinput_setup(void);
-
-#endif /* DVD_INPUT_H_INCLUDED */
diff --git a/dvdread/dvd_reader.c b/dvdread/dvd_reader.c
deleted file mode 100644
index e07b757..0000000
--- a/dvdread/dvd_reader.c
+++ /dev/null
@@ -1,1614 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>,
- * Björn Englund <d4bjorn@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h> /* For the timing of dvdcss_title crack. */
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-#include <dirent.h>
-
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__DARWIN__) || defined(__DragonFly__)
-#define SYS_BSD 1
-#endif
-
-#if defined(__sun)
-#include <sys/mnttab.h>
-#elif defined(SYS_BSD)
-#include <fstab.h>
-#elif defined(__linux__)
-#include <mntent.h>
-#endif
-
-#include "dvd_reader.h"
-#include "dvd_input.h"
-#include "dvd_udf.h"
-#include "md5.h"
-
-#include "dvdread_internal.h"
-
-#define DEFAULT_UDF_CACHE_LEVEL 1
-
-struct dvd_reader_s {
- /* Basic information. */
- int isImageFile;
-
- /* Hack for keeping track of the css status.
- * 0: no css, 1: perhaps (need init of keys), 2: have done init */
- int css_state;
- int css_title; /* Last title that we have called dvdinpute_title for. */
-
- /* Information required for an image file. */
- dvd_input_t dev;
-
- /* Information required for a directory path drive. */
- char *path_root;
-
- /* Filesystem cache */
- int udfcache_level; /* 0 - turned off, 1 - on */
- void *udfcache;
-
- /* block aligned malloc */
- void *align;
-
- /* error message verbosity level */
- int verbose;
-};
-
-struct dvd_file_s {
- /* Basic information. */
- dvd_reader_t *dvd;
-
- /* Hack for selecting the right css title. */
- int css_title;
-
- /* Information required for an image file. */
- uint32_t lb_start;
- uint32_t seek_pos;
-
- /* Information required for a directory path drive. */
- size_t title_sizes[ 9 ];
- dvd_input_t title_devs[ 9 ];
-
- /* Calculated at open-time, size in blocks. */
- ssize_t filesize;
-};
-
-
-#define DVDREAD_VERBOSE_DEFAULT 0
-
-int get_verbose(void)
-{
- char *dvdread_verbose;
- int verbose;
-
- dvdread_verbose = getenv("DVDREAD_VERBOSE");
- if(dvdread_verbose) {
- verbose = (int)strtol(dvdread_verbose, NULL, 0);
- } else {
- verbose = DVDREAD_VERBOSE_DEFAULT;
- }
- return verbose;
-}
-
-int dvdread_verbose(dvd_reader_t *dvd)
-{
- return dvd->verbose;
-}
-
-dvd_reader_t *device_of_file(dvd_file_t *file)
-{
- return file->dvd;
-}
-
-/**
- * Returns the compiled version. (DVDREAD_VERSION as an int)
- */
-int DVDVersion(void)
-{
- return DVDREAD_VERSION;
-}
-
-
-/**
- * Set the level of caching on udf
- * level = 0 (no caching)
- * level = 1 (caching filesystem info)
- */
-int DVDUDFCacheLevel(dvd_reader_t *device, int level)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- if(level > 0) {
- level = 1;
- } else if(level < 0) {
- return dev->udfcache_level;
- }
-
- dev->udfcache_level = level;
-
- return level;
-}
-
-void *GetUDFCacheHandle(dvd_reader_t *device)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- return dev->udfcache;
-}
-
-void SetUDFCacheHandle(dvd_reader_t *device, void *cache)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- dev->udfcache = cache;
-}
-
-void *GetAlignHandle(dvd_reader_t *device)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- return dev->align;
-}
-
-void SetAlignHandle(dvd_reader_t *device, void *align)
-{
- struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
-
- dev->align = align;
-}
-
-#ifdef WIN32 /* replacement gettimeofday implementation */
-#include <sys/timeb.h>
-static int gettimeofday( struct timeval *tv, void *tz )
-{
- struct timeb t;
- ftime( &t );
- tv->tv_sec = t.time;
- tv->tv_usec = t.millitm * 1000;
- return 0;
-}
-#endif
-
-
-/* Loop over all titles and call dvdcss_title to crack the keys. */
-static int initAllCSSKeys( dvd_reader_t *dvd )
-{
- struct timeval all_s, all_e;
- struct timeval t_s, t_e;
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- int title;
-
- char *nokeys_str = getenv("DVDREAD_NOKEYS");
- if(nokeys_str != NULL)
- return 0;
-
- if(dvd->verbose >= 1) {
- fprintf( stderr, "\n" );
- fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" );
- fprintf( stderr, "libdvdread: This can take a _long_ time, "
- "please be patient\n\n" );
- }
- gettimeofday(&all_s, NULL);
-
- for( title = 0; title < 100; title++ ) {
- gettimeofday( &t_s, NULL );
- if( title == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
- }
- start = UDFFindFile( dvd, filename, &len );
- if( start != 0 && len != 0 ) {
- /* Perform CSS key cracking for this title. */
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
- filename, start );
- }
- if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
- if(dvd->verbose >= 0) {
- fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start);
- }
- }
- gettimeofday( &t_e, NULL );
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Elapsed time %ld\n",
- (long int) t_e.tv_sec - t_s.tv_sec );
- }
- }
-
- if( title == 0 ) continue;
-
- gettimeofday( &t_s, NULL );
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
- start = UDFFindFile( dvd, filename, &len );
- if( start == 0 || len == 0 ) break;
-
- /* Perform CSS key cracking for this title. */
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
- filename, start );
- }
- if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
- if(dvd->verbose >= 0) {
- fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start);
- }
- }
- gettimeofday( &t_e, NULL );
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Elapsed time %ld\n",
- (long int) t_e.tv_sec - t_s.tv_sec );
- }
- }
- title--;
-
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Found %d VTS's\n", title );
- }
- gettimeofday(&all_e, NULL);
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Elapsed time %ld\n",
- (long int) all_e.tv_sec - all_s.tv_sec );
- }
- return 0;
-}
-
-
-
-/**
- * Open a DVD image or block device file.
- * Checks if the root directory in the udf image file can be found.
- * If not it assumes this isn't a valid udf image and returns NULL
- */
-static dvd_reader_t *DVDOpenImageFile( const char *location, int have_css )
-{
- dvd_reader_t *dvd;
- dvd_input_t dev;
- int verbose;
-
- verbose = get_verbose();
-
- dev = dvdinput_open( location );
- if( !dev ) {
- if(verbose >= 1) {
- fprintf( stderr, "libdvdread: Can't open '%s' for reading: %s\n",
- location, strerror(errno));
- }
- return NULL;
- }
-
- dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
- if( !dvd ) {
- int tmp_errno = errno;
- dvdinput_close(dev);
- errno = tmp_errno;
- return NULL;
- }
- dvd->verbose = verbose;
- dvd->isImageFile = 1;
- dvd->dev = dev;
- dvd->path_root = NULL;
-
- dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
- dvd->udfcache = NULL;
-
- dvd->align = NULL;
-
- if( have_css ) {
- /* Only if DVDCSS_METHOD = title, a bit if it's disc or if
- * DVDCSS_METHOD = key but region missmatch. Unfortunaly we
- * don't have that information. */
-
- dvd->css_state = 1; /* Need key init. */
- }
- dvd->css_title = 0;
-
- /* sanity check, is it a valid UDF image, can we find the root dir */
- if(!UDFFindFile(dvd, "/", NULL)) {
- dvdinput_close(dvd->dev);
- if(dvd->udfcache) {
- FreeUDFCache(dvd, dvd->udfcache);
- }
- if(dvd->align) {
- if(dvd->verbose >= 0) {
- fprintf(stderr, "libdvdread: DVDOpenImageFile(): Memory leak in align functions 1\n");
- }
- }
- free(dvd);
- return NULL;
- }
- return dvd;
-}
-
-static dvd_reader_t *DVDOpenPath( const char *path_root )
-{
- dvd_reader_t *dvd;
-
- dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
- if( !dvd ) {
- return NULL;
- }
- dvd->verbose = get_verbose();
- dvd->isImageFile = 0;
- dvd->dev = 0;
- dvd->path_root = strdup( path_root );
- if(!dvd->path_root) {
- free(dvd);
- return 0;
- }
- dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
- dvd->udfcache = NULL;
-
- dvd->align = NULL;
-
- dvd->css_state = 0; /* Only used in the UDF path */
- dvd->css_title = 0; /* Only matters in the UDF path */
-
- return dvd;
-}
-
-#if defined(__sun)
-/* /dev/rdsk/c0t6d0s0 (link to /devices/...)
- /vol/dev/rdsk/c0t6d0/??
- /vol/rdsk/<name> */
-static char *sun_block2char( const char *path )
-{
- char *new_path;
-
- /* Must contain "/dsk/" */
- if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path );
-
- /* Replace "/dsk/" with "/rdsk/" */
- new_path = malloc( strlen(path) + 2 );
- strcpy( new_path, path );
- strcpy( strstr( new_path, "/dsk/" ), "" );
- strcat( new_path, "/rdsk/" );
- strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) );
-
- return new_path;
-}
-#endif
-
-#if defined(SYS_BSD)
-/* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r
- update: FreeBSD and DragonFly no longer uses the prefix so don't add it.
-
- OpenBSD /dev/rcd0c, it needs to be the raw device
- NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others
- Darwin /dev/rdisk0, it needs to be the raw device
- BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do)
-
- returns a string allocated with strdup which should be free()'d when
- no longer used.
-*/
-static char *bsd_block2char( const char *path )
-{
-#if defined(__FreeBSD__) || defined(__DragonFly__)
- return (char *) strdup( path );
-#else
- char *new_path;
-
- /* If it doesn't start with "/dev/" or does start with "/dev/r" exit */
- if( strncmp( path, "/dev/", 5 ) || !strncmp( path, "/dev/r", 6 ) )
- return (char *) strdup( path );
-
- /* Replace "/dev/" with "/dev/r" */
- new_path = malloc( strlen(path) + 2 );
- strcpy( new_path, "/dev/r" );
- strcat( new_path, path + strlen( "/dev/" ) );
-
- return new_path;
-#endif /* __FreeBSD__ || __DragonFly__ */
-}
-#endif
-
-
-dvd_reader_t *DVDOpen( const char *path )
-{
- struct stat fileinfo;
- int ret, have_css;
- char *dev_name = NULL;
- int internal_errno = 0;
- int verbose;
-
- if( path == NULL ) {
- errno = EINVAL;
- return NULL;
- }
-
- verbose = get_verbose();
-
-#ifdef WIN32
- /* Stat doesn't work on devices under mingwin/cygwin. */
- if( path[0] && path[1] == ':' && path[2] == '\0' )
- {
- /* Don't try to stat the file */
- fileinfo.st_mode = S_IFBLK;
- }
- else
-#endif
- {
- ret = stat( path, &fileinfo );
- if( ret < 0 ) {
- int tmp_errno = errno;
- /* If we can't stat the file, give up */
- if(verbose >= 1) {
- fprintf( stderr, "libdvdread: Can't stat '%s': %s\n",
- path, strerror(errno));
- }
- errno = tmp_errno;
- return NULL;
- }
- }
-
- /* Try to open libdvdcss or fall back to standard functions */
- have_css = dvdinput_setup();
-
- /* First check if this is a block/char device or a file*/
- if( S_ISBLK( fileinfo.st_mode ) ||
- S_ISCHR( fileinfo.st_mode ) ||
- S_ISREG( fileinfo.st_mode ) ) {
- /**
- * Block devices and regular files are assumed to be DVD-Video images.
- */
- dvd_reader_t *dvd = NULL;
-#if defined(__sun)
- dev_name = sun_block2char( path );
-#elif defined(SYS_BSD)
- dev_name = bsd_block2char( path );
-#else
- dev_name = strdup( path );
-#endif
- dvd = DVDOpenImageFile( dev_name, have_css );
- free( dev_name );
-
- return dvd;
- } else if( S_ISDIR( fileinfo.st_mode ) ) {
- dvd_reader_t *auth_drive = 0;
- char *path_copy;
-#if defined(SYS_BSD)
- struct fstab* fe;
-#elif defined(__sun) || defined(__linux__)
- FILE *mntfile;
-#endif
-
- /* XXX: We should scream real loud here. */
- if( !(path_copy = strdup( path ) ) ) return 0;
-
-#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */
- /* Resolve any symlinks and get the absolut dir name. */
- {
- char *new_path;
- char *current_path;
-
- current_path = malloc(PATH_MAX);
- if(current_path) {
- if(!getcwd(current_path, PATH_MAX)) {
- free(current_path);
- current_path = NULL;
- }
- }
- if(current_path) {
- chdir( path_copy );
- new_path = malloc(PATH_MAX);
- if(new_path) {
- if(!getcwd(new_path, PATH_MAX )) {
- free(new_path);
- new_path = NULL;
- }
- }
-
- chdir(current_path);
- free(current_path);
- if( new_path ) {
- free( path_copy );
- path_copy = new_path;
- }
- }
- }
-#endif
-
- /**
- * If we're being asked to open a directory, check if that directory
- * is the mountpoint for a DVD-ROM which we can use instead.
- */
-
- if( strlen( path_copy ) > 1 ) {
- if( path_copy[ strlen( path_copy ) - 1 ] == '/' ) {
- path_copy[ strlen( path_copy ) - 1 ] = '\0';
- }
- }
-
- if( strlen( path_copy ) >= 9 ) {
- if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]),
- "/video_ts" ) ) {
- path_copy[ strlen( path_copy ) - 9 ] = '\0';
- if(path_copy[0] == '\0') {
- path_copy[0] = '/';
- path_copy[1] = '\0';
- }
- }
- }
-
-#if defined(SYS_BSD)
- if( ( fe = getfsfile( path_copy ) ) ) {
- dev_name = bsd_block2char( fe->fs_spec );
- if(verbose >= 1) {
- fprintf( stderr,
- "libdvdread: Attempting to use device %s"
- " mounted on %s%s\n",
- dev_name,
- fe->fs_file,
- have_css ? " for CSS authentication" : "");
- }
- auth_drive = DVDOpenImageFile( dev_name, have_css );
- if(!auth_drive) {
- internal_errno = errno;
- }
- }
-#elif defined(__sun)
- mntfile = fopen( MNTTAB, "r" );
- if( mntfile ) {
- struct mnttab mp;
- int res;
-
- while( ( res = getmntent( mntfile, &mp ) ) != -1 ) {
- if( res == 0 && !strcmp( mp.mnt_mountp, path_copy ) ) {
- dev_name = sun_block2char( mp.mnt_special );
- if(verbose >= 1) {
- fprintf( stderr,
- "libdvdread: Attempting to use device %s"
- " mounted on %s%s\n",
- dev_name,
- mp.mnt_mountp,
- have_css ? " for CSS authentication" : "");
- }
- auth_drive = DVDOpenImageFile( dev_name, have_css );
- if(!auth_drive) {
- internal_errno = errno;
- }
- break;
- }
- }
- fclose( mntfile );
- }
-#elif defined(__linux__)
- mntfile = fopen( MOUNTED, "r" );
- if( mntfile ) {
- struct mntent *me;
-
- while( ( me = getmntent( mntfile ) ) ) {
- if( !strcmp( me->mnt_dir, path_copy ) ) {
- if(verbose >= 1) {
- fprintf( stderr,
- "libdvdread: Attempting to use device %s"
- " mounted on %s%s\n",
- me->mnt_fsname,
- me->mnt_dir,
- have_css ? " for CSS authentication" : "");
- }
- auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css );
- if(!auth_drive) {
- internal_errno = errno;
- }
- dev_name = strdup(me->mnt_fsname);
- break;
- }
- }
- fclose( mntfile );
- }
-#endif
- if( !dev_name ) {
- if(verbose >= 1) {
- fprintf( stderr, "libdvdread: Couldn't find device name.\n" );
- }
- } else if( !auth_drive ) {
- if(verbose >= 1) {
- fprintf( stderr, "libdvdread: Device %s inaccessible%s: %s\n",
- dev_name,
- have_css ? ", CSS authentication not available" : "",
- strerror(internal_errno));
- }
- }
-
- free( dev_name );
- free( path_copy );
-
- /**
- * If we've opened a drive, just use that.
- */
- if( auth_drive ) {
- return auth_drive;
- }
- /**
- * Otherwise, we now try to open the directory tree instead.
- */
- return DVDOpenPath( path );
- }
-
- /* If it's none of the above, screw it. */
- if(verbose >= 1) {
- fprintf( stderr, "libdvdread: Could not open %s\n", path );
- }
- return 0;
-}
-
-void DVDClose( dvd_reader_t *dvd )
-{
- if( dvd ) {
- if( dvd->dev ) dvdinput_close( dvd->dev );
- if( dvd->path_root ) free( dvd->path_root );
- if( dvd->udfcache ) FreeUDFCache( dvd, dvd->udfcache );
- if(dvd->align) {
- if(dvd->verbose >= 0) {
- fprintf(stderr, "libdvdread: DVDClose(): Memory leak in align functions\n");
- }
- }
-
- free( dvd );
- }
-}
-
-void DVDInit(void)
-{
- dvdinput_setup();
-}
-
-void DVDFinish(void)
-{
- dvdinput_free();
-}
-
-/**
- * Open an unencrypted file on a DVD image file.
- */
-static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
-{
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- start = UDFFindFile( dvd, filename, &len );
- if( !start ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- return dvd_file;
-}
-
-/**
- * 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.
- */
-static int findDirFile( const char *path, const char *file, char *filename )
-{
- DIR *dir;
- struct dirent *ent;
-
- dir = opendir( path );
- if( !dir ) 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 );
- closedir(dir);
- return 0;
- }
- }
- closedir(dir);
- return -1;
-}
-
-static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename )
-{
- char video_path[ PATH_MAX + 1 ];
- const char *nodirfile;
- int ret;
-
- /* Strip off the directory for our search */
- if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) {
- nodirfile = &(file[ 10 ]);
- } else {
- nodirfile = file;
- }
-
- ret = findDirFile( dvd->path_root, nodirfile, filename );
- if( ret < 0 ) {
- /* Try also with adding the path, just in case. */
- sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- /* Try with the path, but in lower case. */
- sprintf( video_path, "%s/video_ts/", dvd->path_root );
- ret = findDirFile( video_path, nodirfile, filename );
- if( ret < 0 ) {
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-/**
- * Open an unencrypted file from a DVD directory tree.
- */
-static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename )
-{
- char full_path[ PATH_MAX + 1 ];
- dvd_file_t *dvd_file;
- struct stat fileinfo;
- dvd_input_t dev;
-
- /* Get the full path of the file. */
- if( !findDVDFile( dvd, filename, full_path ) ) return 0;
-
- dev = dvdinput_open( full_path );
- if( !dev ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize = 0;
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- }
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_devs[ 0 ] = dev;
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t start, len;
- dvd_file_t *dvd_file;
-
- if( title == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
- }
- start = UDFFindFile( dvd, filename, &len );
- if( start == 0 ) return 0;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- /*Hack*/ dvd_file->css_title = title << 1 | menu;
- dvd_file->lb_start = start;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
-
- /* Calculate the complete file size for every file in the VOBS */
- if( !menu ) {
- int cur;
-
- for( cur = 2; cur < 10; cur++ ) {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
- if( !UDFFindFile( dvd, filename, &len ) ) break;
- dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
- }
- }
-
- if( dvd->css_state == 1 /* Need key init */ ) {
- initAllCSSKeys( dvd );
- dvd->css_state = 2;
- }
- /*
- if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
- fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
- filename );
- }
- */
-
- return dvd_file;
-}
-
-static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- char full_path[ PATH_MAX + 1 ];
- struct stat fileinfo;
- dvd_file_t *dvd_file;
- int i;
-
- dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
- if( !dvd_file ) return 0;
- dvd_file->dvd = dvd;
- /*Hack*/ dvd_file->css_title = title << 1 | menu;
- dvd_file->lb_start = 0;
- dvd_file->seek_pos = 0;
- memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
- memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
- dvd_file->filesize = 0;
-
- if( menu ) {
- dvd_input_t dev;
-
- if( title == 0 ) {
- sprintf( filename, "VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "VTS_%02i_0.VOB", title );
- }
- if( !findDVDFile( dvd, filename, full_path ) ) {
- free( dvd_file );
- return 0;
- }
-
- dev = dvdinput_open( full_path );
- if( dev == NULL ) {
- free( dvd_file );
- return 0;
- }
-
- if( stat( full_path, &fileinfo ) < 0 ) {
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
- }
- free( dvd_file );
- return 0;
- }
- dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_devs[ 0 ] = dev;
- dvdinput_title( dvd_file->title_devs[0], 0);
- dvd_file->filesize = dvd_file->title_sizes[ 0 ];
-
- } else {
- for( i = 0; i < 9; ++i ) {
-
- sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
- 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;
- }
-
- dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_devs[ i ] = dvdinput_open( full_path );
- dvdinput_title( dvd_file->title_devs[ i ], 0 );
- dvd_file->filesize += dvd_file->title_sizes[ i ];
- }
- if( !dvd_file->title_devs[ 0 ] ) {
- free( dvd_file );
- return 0;
- }
- }
-
- return dvd_file;
-}
-
-dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum,
- dvd_read_domain_t domain )
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
-
- /* Check arguments. */
- if( dvd == NULL || titlenum < 0 ) {
- errno = EINVAL;
- return NULL;
- }
-
- 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 DVDOpenVOBUDF( dvd, titlenum, 1 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 1 );
- }
- break;
- case DVD_READ_TITLE_VOBS:
- if( titlenum == 0 ) return 0;
- if( dvd->isImageFile ) {
- return DVDOpenVOBUDF( dvd, titlenum, 0 );
- } else {
- return DVDOpenVOBPath( dvd, titlenum, 0 );
- }
- break;
- default:
- if(dvd->verbose >= 1) {
- fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
- }
- errno = EINVAL;
- 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;
- }
-}
-
-static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title,
- int menu, dvd_stat_t *statbuf)
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint32_t size;
- off_t tot_size;
- off_t parts_size[9];
- int nr_parts = 0;
- int n;
-
- if( title == 0 ) {
- sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
- } else {
- sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
- }
- if(!UDFFindFile( dvd, filename, &size )) {
- return -1;
- }
- 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( !UDFFindFile( dvd, filename, &size ) ) {
- break;
- }
- 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 ) {
- if(dvd->verbose >= 1) {
- 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;
-}
diff --git a/dvdread/dvd_reader.h b/dvdread/dvd_reader.h
deleted file mode 100644
index d666e8a..0000000
--- a/dvdread/dvd_reader.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef DVD_READER_H_INCLUDED
-#define DVD_READER_H_INCLUDED
-
-/*
- * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>,
- * Björn Englund <d4bjorn@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <sys/types.h>
-
-/**
- * The DVD access interface.
- *
- * This file contains the functions that form the interface to to
- * reading files located on a DVD.
- */
-
-/**
- * The current version. (0.9.4 => 904, 1.2.3 => 10203)
- */
-#define DVDREAD_VERSION 907
-
-
-/**
- * The length of one Logical Block of a DVD.
- */
-#define DVD_VIDEO_LB_LEN 2048
-
-/**
- * Maximum length of filenames allowed in UDF.
- */
-#define MAX_UDF_FILE_NAME_LEN 2048
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Opaque type that is used as a handle for one instance of an opened DVD.
- */
-typedef struct dvd_reader_s dvd_reader_t;
-
-/**
- * Opaque type for a file read handle, much like a normal fd or FILE *.
- */
-typedef struct dvd_file_s dvd_file_t;
-
-/**
- * Returns the compiled version. (DVDREAD_VERSION as an int)
- */
-int DVDVersion(void);
-
-
-/**
- * Opens a block device of a DVD-ROM file, or an image file, or a directory
- * name for a mounted DVD or HD copy of a DVD.
- *
- * If the given file is a block device, or is the mountpoint for a block
- * device, then that device is used for CSS authentication using libdvdcss.
- * If no device is available, then no CSS authentication is performed,
- * and we hope that the image is decrypted.
- *
- * If the path given is a directory, then the files in that directory may be
- * in any one of these formats:
- *
- * path/VIDEO_TS/VTS_01_1.VOB
- * path/video_ts/vts_01_1.vob
- * path/VTS_01_1.VOB
- * path/vts_01_1.vob
- *
- * @param path Specifies the the device, file or directory to be used.
- * @return If successful a a read handle is returned. Otherwise 0 is returned.
- *
- * dvd = DVDOpen(path);
- *
- * Threads: this function uses chdir() and getcwd().
- * The current working directory is global to all threads,
- * so using chdir/getcwd in another thread could give unexpected results.
- */
-dvd_reader_t *DVDOpen( const char * );
-
-/**
- * Closes and cleans up the DVD reader object.
- *
- * You must close all open files before calling this function.
- *
- * @param dvd A read handle that should be closed.
- *
- * DVDClose(dvd);
- */
-void DVDClose( dvd_reader_t * );
-
-/**
- * Initializes libdvdread to be used with multithreading apps.
- *
- * You must call this function before using any other functions of libdvdread
- * if you are going to use libdvdread in multiple threads in your program.
- * If you are not using threads, or using libdvdread from just one thread,
- * you do not need to call this, but you are allowed to do so anyway.
- *
- * There are several restrictions on how you can use libdvdread in
- * multithreading apps, see further documentation.
- *
- * If you have called DVDFinish() you need to call DVDInit again to use
- * libdvdread in multiple threads.
- *
- * DVDInit(void);
- */
-void DVDInit(void);
-
-/**
- * frees any dlopened objects.
- *
- * You must DVDClose all handles opened with DVDOpen before calling this.
- * Use this function if you need to close the dlopened libs and any other
- * objects that have been dynamically allocated by libdvdread.
- *
- * DVDFinish(void);
- */
-void DVDFinish(void);
-
-/**
- *
- */
-typedef enum {
- DVD_READ_INFO_FILE, /**< VIDEO_TS.IFO or VTS_XX_0.IFO (title) */
- DVD_READ_INFO_BACKUP_FILE, /**< VIDEO_TS.BUP or VTS_XX_0.BUP (title) */
- DVD_READ_MENU_VOBS, /**< VIDEO_TS.VOB or VTS_XX_0.VOB (title) */
- DVD_READ_TITLE_VOBS /**< VTS_XX_[1-9].VOB (title). All files in
- the title set are opened and read as a
- single file. */
-} dvd_read_domain_t;
-
-/**
- *
- */
-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.
- *
- * If the title number is 0, the video manager information is opened
- * (VIDEO_TS.[IFO,BUP,VOB]). Returns a file structure which may be
- * used for reads, or 0 if the file was not found.
- *
- * @param dvd A dvd read handle.
- * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0.
- * @param domain Which domain.
- * @return If successful a a file read handle is returned, otherwise 0.
- *
- * dvd_file = DVDOpenFile(dvd, titlenum, domain); */
-dvd_file_t *DVDOpenFile( dvd_reader_t *, int, dvd_read_domain_t );
-
-/**
- * Closes a file and frees the associated structure.
- *
- * @param dvd_file The file read handle to be closed.
- *
- * DVDCloseFile(dvd_file);
- */
-void DVDCloseFile( dvd_file_t * );
-
-/**
- * Reads block_count number of blocks from the file at the given block offset.
- * Returns number of blocks read on success, -1 on error. This call is only
- * for reading VOB data, and should not be used when reading the IFO files.
- * When reading from an encrypted drive, blocks are decrypted using libdvdcss
- * where required.
- *
- * @param dvd_file A file read handle.
- * @param offset Block offset from the start of the file to start reading at.
- * @param block_count Number of block to read.
- * @param data Pointer to a buffer to write the data into.
- * It must be aligned to the logical block size of the device when
- * reading from a raw/O_DIRECT device (2048 bytes for DVD)
- * @return Returns number of blocks read on success, -1 on error.
- *
- * blocks_read = DVDReadBlocks(dvd_file, offset, block_count, data);
- */
-ssize_t DVDReadBlocks( dvd_file_t *, int, size_t, unsigned char * );
-
-/**
- * Seek to the given position in the file. Returns the resulting position in
- * bytes from the beginning of the file. The seek position is only used for
- * byte reads from the file, the block read call always reads from the given
- * offset.
- *
- * @param dvd_file A file read handle.
- * @param seek_offset Byte offset from the start of the file to seek to.
- * @return The resulting position in bytes from the beginning of the file.
- *
- * offset_set = DVDFileSeek(dvd_file, seek_offset);
- */
-int DVDFileSeek( dvd_file_t *, int );
-
-/**
- * Reads the given number of bytes from the file. This call can only be used
- * on the information files, and may not be used for reading from a VOB. This
- * reads from and increments the currrent seek position for the file.
- *
- * @param dvd_file A file read handle.
- * @param data Pointer to a buffer to write the data into.
- * @param bytes Number of bytes to read.
- * @return Returns number of bytes read on success, -1 on error.
- *
- * bytes_read = DVDReadBytes(dvd_file, data, bytes);
- */
-ssize_t DVDReadBytes( dvd_file_t *, void *, size_t );
-
-/**
- * Returns the file size in blocks.
- *
- * @param dvd_file A file read handle.
- * @return The size of the file in blocks, -1 on error.
- *
- * blocks = DVDFileSize(dvd_file);
- */
-ssize_t DVDFileSize( dvd_file_t * );
-
-/**
- * Get a unique 128 bit disc ID.
- * This is the MD5 sum of VIDEO_TS.IFO and the VTS_0?_0.IFO files
- * in title order (those that exist).
- * If you need a 'text' representation of the id, print it as a
- * hexadecimal number, using lowercase letters, discid[0] first.
- * I.e. the same format as the command-line 'md5sum' program uses.
- *
- * @param dvd A read handle to get the disc ID from
- * @param discid The buffer to put the disc ID into. The buffer must
- * have room for 128 bits (16 chars).
- * @return 0 on success, -1 on error.
- */
-int DVDDiscID( dvd_reader_t *, unsigned char * );
-
-/**
- * Get the UDF VolumeIdentifier and VolumeSetIdentifier
- * from the PrimaryVolumeDescriptor.
- *
- * @param dvd A read handle to get the disc ID from
- * @param volid The buffer to put the VolumeIdentifier into.
- * The VolumeIdentifier is latin-1 encoded (8bit unicode)
- * null terminated and max 32 bytes (including '\0')
- * @param volid_size No more than volid_size bytes will be copied to volid.
- * If the VolumeIdentifier is truncated because of this
- * it will still be null terminated.
- * @param volsetid The buffer to put the VolumeSetIdentifier into.
- * The VolumeIdentifier is 128 bytes as
- * stored in the UDF PrimaryVolumeDescriptor.
- * Note that this is not a null terminated string.
- * @param volsetid_size At most volsetid_size bytes will be copied to volsetid.
- * @return 0 on success, -1 on error.
- */
-int DVDUDFVolumeInfo( dvd_reader_t *, char *, unsigned int,
- unsigned char *, unsigned int );
-
-/**
- * Get the ISO9660 VolumeIdentifier and VolumeSetIdentifier
- *
- * * Only use this function as fallback if DVDUDFVolumeInfo returns 0 *
- * * this will happen on a disc mastered only with a iso9660 filesystem *
- * * All video DVD discs have UDF filesystem *
- *
- * @param dvd A read handle to get the disc ID from
- * @param volid The buffer to put the VolumeIdentifier into.
- * The VolumeIdentifier is coded with '0-9','A-Z','_'
- * null terminated and max 33 bytes (including '\0')
- * @param volid_size No more than volid_size bytes will be copied to volid.
- * If the VolumeIdentifier is truncated because of this
- * it will still be null terminated.
- * @param volsetid The buffer to put the VolumeSetIdentifier into.
- * The VolumeIdentifier is 128 bytes as
- * stored in the ISO9660 PrimaryVolumeDescriptor.
- * Note that this is not a null terminated string.
- * @param volsetid_size At most volsetid_size bytes will be copied to volsetid.
- * @return 0 on success, -1 on error.
- */
-int DVDISOVolumeInfo( dvd_reader_t *, char *, unsigned int,
- unsigned char *, unsigned int );
-
-/**
- * Sets the level of caching that is done when reading from a device
- *
- * @param dvd A read handle to get the disc ID from
- * @param level The level of caching wanted.
- * -1 - returns the current setting.
- * 0 - UDF Cache turned off.
- * 1 - (default level) Pointers to IFO files and some data from
- * PrimaryVolumeDescriptor are cached.
- *
- * @return The level of caching.
- */
-int DVDUDFCacheLevel( dvd_reader_t *, int );
-
-#ifdef __cplusplus
-};
-#endif
-#endif /* DVD_READER_H_INCLUDED */
diff --git a/dvdread/dvd_udf.c b/dvdread/dvd_udf.c
deleted file mode 100644
index cfd4f10..0000000
--- a/dvdread/dvd_udf.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- * This code is based on dvdudf by:
- * Christian Wolff <scarabaeus@convergence.de>.
- *
- * Modifications by:
- * Billy Biggs <vektor@dumbterm.net>.
- * Björn Englund <d4bjorn@dtek.chalmers.se>.
- *
- * dvdudf: parse and read the UDF volume information of a DVD Video
- * Copyright (C) 1999 Christian Wolff for convergence integrated media
- * GmbH The author can be reached at scarabaeus@convergence.de, the
- * project's page is at http://linuxtv.org/dvd/
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA. Or, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#if defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#elif defined(HAVE_STDINT_H)
-#include <stdint.h>
-#endif
-
-#include "dvd_reader.h"
-#include "dvd_udf.h"
-#include "dvdread_internal.h"
-
-#ifndef EMEDIUMTYPE
-#define EMEDIUMTYPE ENOENT
-#endif
-
-#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)
-
-typedef struct {
- void *start;
- void *aligned;
-} dvdalign_ptrs_t;
-
-typedef struct {
- dvdalign_ptrs_t *ptrs;
- uint32_t ptrs_in_use;
- uint32_t ptrs_max;
-} dvdalign_t;
-
-extern void *GetAlignHandle(dvd_reader_t *device);
-extern void SetAlignHandle(dvd_reader_t *device, void *align);
-
-/**
- * Allocates aligned memory (for use with reads from raw/O_DIRECT devices).
- * This memory must be freed with dvdalign_free()
- * The size of the memory that is allocate is num_lbs*2048 bytes.
- * The memory will be suitably aligned for use with
- * block reads from raw/O_DIRECT device.
- * @param num_lbs Number of logical blocks (2048 bytes) to allocate.
- * @return Returns pointer to allocated memory, or NULL on failure
- * This isn't supposed to be fast/efficient, if that is needed
- * this function should be rewritten to use posix_memalign or similar.
- * It's just needed for aligning memory for small block reads from
- * raw/O_DIRECT devices.
- * We assume that 2048 is enough alignment for all systems at the moment.
- * Not thread safe. Only use this from one thread.
- * Depends on sizeof(unsigned long) being at least as large as sizeof(void *)
- */
-static void *dvdalign_lbmalloc(dvd_reader_t *device, uint32_t num_lbs)
-{
- void *m;
- int n;
- dvdalign_t *a;
-
- m = malloc((num_lbs+1)*DVD_VIDEO_LB_LEN);
- if(m == NULL) {
- return m;
- }
- a = (dvdalign_t *)GetAlignHandle(device);
- if(a == NULL) {
- a = malloc(sizeof(dvdalign_t));
- if(a == NULL) {
- return a;
- }
- a->ptrs = NULL;
- a->ptrs_in_use = 0;
- a->ptrs_max = 0;
- SetAlignHandle(device, (void *)a);
- }
-
- if(a->ptrs_in_use >= a->ptrs_max) {
- a->ptrs = realloc(a->ptrs, (a->ptrs_max+10)*sizeof(dvdalign_ptrs_t));
- if(a->ptrs == NULL) {
- free(m);
- return NULL;
- }
- a->ptrs_max+=10;
- for(n = a->ptrs_in_use; n < a->ptrs_max; n++) {
- a->ptrs[n].start = NULL;
- a->ptrs[n].aligned = NULL;
- }
- n = a->ptrs_in_use;
- } else {
- for(n = 0; n < a->ptrs_max; n++) {
- if(a->ptrs[n].start == NULL) {
- break;
- }
- }
- }
-
- a->ptrs[n].start = m;
- a->ptrs[n].aligned = DVD_ALIGN(m);
-
- a->ptrs_in_use++;
-
- /* If this function starts to be used too much print a warning.
- Either there is a memory leak somewhere or we need to rewrite this to
- a more efficient version.
- */
- if(a->ptrs_in_use > 50) {
- if(dvdread_verbose(device) >= 0) {
- fprintf(stderr, "libdvdread: dvdalign_lbmalloc(), more allocs than supposed: %u\n", a->ptrs_in_use);
- }
- }
-
- return a->ptrs[n].aligned;
-}
-
-/**
- * Frees memory allocated with dvdalign_lbmemory()
- * @param ptr Pointer to memory space to free
- * Not thread safe.
- */
-static void dvdalign_lbfree(dvd_reader_t *device, void *ptr)
-{
- int n;
- dvdalign_t *a;
-
- a = (dvdalign_t *)GetAlignHandle(device);
- if(a && a->ptrs) {
- for(n = 0; n < a->ptrs_max; n++) {
- if(a->ptrs[n].aligned == ptr) {
- free(a->ptrs[n].start);
- a->ptrs[n].start = NULL;
- a->ptrs[n].aligned = NULL;
- a->ptrs_in_use--;
- if(a->ptrs_in_use == 0) {
- free(a->ptrs);
- a->ptrs = NULL;
- a->ptrs_max = 0;
- free(a);
- a = NULL;
- SetAlignHandle(device, (void *)a);
- }
- return;
- }
- }
- }
- if(dvdread_verbose(device) >= 0) {
- fprintf(stderr, "libdvdread: dvdalign_lbfree(), error trying to free mem: %08lx (%u)\n", (unsigned long)ptr, a ? a->ptrs_in_use : 0);
- }
-}
-
-
-/* Private but located in/shared with dvd_reader.c */
-extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,
- int encrypted );
-
-/** @internal
- * Its required to either fail or deliver all the blocks asked for.
- *
- * @param data Pointer to a buffer where data is returned. This must be large
- * enough to hold lb_number*2048 bytes.
- * It must be aligned to system specific (2048) logical blocks size when
- * reading from raw/O_DIRECT device.
- */
-static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
- size_t block_count, unsigned char *data,
- int encrypted )
-{
- int ret;
- size_t count = block_count;
-
- while(count > 0) {
-
- ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted);
-
- if(ret <= 0) {
- /* One of the reads failed or nothing more to read, too bad.
- * We won't even bother returning the reads that went ok. */
- return ret;
- }
-
- count -= (size_t)ret;
- lb_number += (uint32_t)ret;
- }
-
- return block_count;
-}
-
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-struct Partition {
- int valid;
- char VolumeDesc[128];
- uint16_t Flags;
- uint16_t Number;
- char Contents[32];
- uint32_t AccessType;
- uint32_t Start;
- uint32_t Length;
-};
-
-struct AD {
- uint32_t Location;
- uint32_t Length;
- uint8_t Flags;
- uint16_t Partition;
-};
-
-struct extent_ad {
- uint32_t location;
- uint32_t length;
-};
-
-struct avdp_t {
- struct extent_ad mvds;
- struct extent_ad rvds;
-};
-
-struct pvd_t {
- uint8_t VolumeIdentifier[32];
- uint8_t VolumeSetIdentifier[128];
-};
-
-struct lbudf {
- uint32_t lb;
- uint8_t *data;
-};
-
-struct icbmap {
- uint32_t lbn;
- struct AD file;
- uint8_t filetype;
-};
-
-struct udf_cache {
- int avdp_valid;
- struct avdp_t avdp;
- int pvd_valid;
- struct pvd_t pvd;
- int partition_valid;
- struct Partition partition;
- int rooticb_valid;
- struct AD rooticb;
- int lb_num;
- struct lbudf *lbs;
- int map_num;
- struct icbmap *maps;
-};
-
-typedef enum {
- PartitionCache, RootICBCache, LBUDFCache, MapCache, AVDPCache, PVDCache
-} UDFCacheType;
-
-extern void *GetUDFCacheHandle(dvd_reader_t *device);
-extern void SetUDFCacheHandle(dvd_reader_t *device, void *cache);
-
-
-void FreeUDFCache(dvd_reader_t *device, void *cache)
-{
- int n;
-
- struct udf_cache *c = (struct udf_cache *)cache;
- if(c == NULL) {
- return;
- }
-
- for(n = 0; n < c->lb_num; n++) {
- if(c->lbs[n].data) {
- /* free data */
- dvdalign_lbfree(device, c->lbs[n].data);
- }
- }
- c->lb_num = 0;
-
- if(c->lbs) {
- free(c->lbs);
- }
- if(c->maps) {
- free(c->maps);
- }
- free(c);
-}
-
-
-static int GetUDFCache(dvd_reader_t *device, UDFCacheType type,
- uint32_t nr, void *data)
-{
- int n;
- struct udf_cache *c;
-
- if(DVDUDFCacheLevel(device, -1) <= 0) {
- return 0;
- }
-
- c = (struct udf_cache *)GetUDFCacheHandle(device);
-
- if(c == NULL) {
- return 0;
- }
-
- switch(type) {
- case AVDPCache:
- if(c->avdp_valid) {
- *(struct avdp_t *)data = c->avdp;
- return 1;
- }
- break;
- case PVDCache:
- if(c->pvd_valid) {
- *(struct pvd_t *)data = c->pvd;
- return 1;
- }
- break;
- case PartitionCache:
- if(c->partition_valid) {
- *(struct Partition *)data = c->partition;
- return 1;
- }
- break;
- case RootICBCache:
- if(c->rooticb_valid) {
- *(struct AD *)data = c->rooticb;
- return 1;
- }
- break;
- case LBUDFCache:
- for(n = 0; n < c->lb_num; n++) {
- if(c->lbs[n].lb == nr) {
- *(uint8_t **)data = c->lbs[n].data;
- return 1;
- }
- }
- break;
- case MapCache:
- for(n = 0; n < c->map_num; n++) {
- if(c->maps[n].lbn == nr) {
- *(struct icbmap *)data = c->maps[n];
- return 1;
- }
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int SetUDFCache(dvd_reader_t *device, UDFCacheType type,
- uint32_t nr, void *data)
-{
- int n;
- struct udf_cache *c;
-
- if(DVDUDFCacheLevel(device, -1) <= 0) {
- return 0;
- }
-
- c = (struct udf_cache *)GetUDFCacheHandle(device);
-
- if(c == NULL) {
- c = calloc(1, sizeof(struct udf_cache));
- /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */
- if(c == NULL) {
- return 0;
- }
- SetUDFCacheHandle(device, c);
- }
-
-
- switch(type) {
- case AVDPCache:
- c->avdp = *(struct avdp_t *)data;
- c->avdp_valid = 1;
- break;
- case PVDCache:
- c->pvd = *(struct pvd_t *)data;
- c->pvd_valid = 1;
- break;
- case PartitionCache:
- c->partition = *(struct Partition *)data;
- c->partition_valid = 1;
- break;
- case RootICBCache:
- c->rooticb = *(struct AD *)data;
- c->rooticb_valid = 1;
- break;
- case LBUDFCache:
- for(n = 0; n < c->lb_num; n++) {
- if(c->lbs[n].lb == nr) {
- /* replace with new data */
- c->lbs[n].data = *(uint8_t **)data;
- c->lbs[n].lb = nr;
- return 1;
- }
- }
- c->lb_num++;
- c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf));
- /*
- fprintf(stderr, "realloc lb: %d * %d = %d\n",
- c->lb_num, sizeof(struct lbudf),
- c->lb_num * sizeof(struct lbudf));
- */
- if(c->lbs == NULL) {
- c->lb_num = 0;
- return 0;
- }
- c->lbs[n].data = *(uint8_t **)data;
- c->lbs[n].lb = nr;
- break;
- case MapCache:
- for(n = 0; n < c->map_num; n++) {
- if(c->maps[n].lbn == nr) {
- /* replace with new data */
- c->maps[n] = *(struct icbmap *)data;
- c->maps[n].lbn = nr;
- return 1;
- }
- }
- c->map_num++;
- c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap));
- /*
- fprintf(stderr, "realloc maps: %d * %d = %d\n",
- c->map_num, sizeof(struct icbmap),
- c->map_num * sizeof(struct icbmap));
- */
- if(c->maps == NULL) {
- c->map_num = 0;
- return 0;
- }
- c->maps[n] = *(struct icbmap *)data;
- c->maps[n].lbn = nr;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-
-/* For direct data access, LSB first */
-#define GETN1(p) ((uint8_t)data[p])
-#define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
-#define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) \
- | ((uint32_t)data[(p) + 2] << 16))
-#define GETN4(p) ((uint32_t)data[p] \
- | ((uint32_t)data[(p) + 1] << 8) \
- | ((uint32_t)data[(p) + 2] << 16) \
- | ((uint32_t)data[(p) + 3] << 24))
-/* This is wrong with regard to endianess */
-#define GETN(p, n, target) memcpy(target, &data[p], n)
-
-static int Unicodedecode( uint8_t *data, int len, char *target )
-{
- int p = 1, i = 0;
-
- if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do {
- if( data[ 0 ] == 16 ) p++; /* Ignore MSB of unicode16 */
- if( p < len ) {
- target[ i++ ] = data[ p++ ];
- }
- } while( p < len );
-
- target[ i ] = '\0';
- return 0;
-}
-
-static int UDFDescriptor( uint8_t *data, uint16_t *TagID )
-{
- *TagID = GETN2(0);
- return 0;
-}
-
-static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location )
-{
- *Length = GETN4(0);
- *Location = GETN4(4);
- return 0;
-}
-
-static int UDFShortAD( uint8_t *data, struct AD *ad,
- struct Partition *partition )
-{
- ad->Length = GETN4(0);
- ad->Flags = ad->Length >> 30;
- ad->Length &= 0x3FFFFFFF;
- ad->Location = GETN4(4);
- ad->Partition = partition->Number; /* use number of current partition*/
- return 0;
-}
-
-static int UDFLongAD( uint8_t *data, struct AD *ad )
-{
- ad->Length = GETN4(0);
- ad->Flags = ad->Length >> 30;
- ad->Length &= 0x3FFFFFFF;
- ad->Location = GETN4(4);
- ad->Partition = GETN2(8);
- /*GETN(10, 6, Use);*/
- return 0;
-}
-
-static int UDFExtAD( uint8_t *data, struct AD *ad )
-{
- ad->Length = GETN4(0);
- ad->Flags = ad->Length >> 30;
- ad->Length &= 0x3FFFFFFF;
- ad->Location = GETN4(12);
- ad->Partition = GETN2(16);
- /*GETN(10, 6, Use);*/
- return 0;
-}
-
-static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags )
-{
- *FileType = GETN1(11);
- *Flags = GETN2(18);
- return 0;
-}
-
-
-static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number,
- char *Contents, uint32_t *Start, uint32_t *Length )
-{
- *Flags = GETN2(20);
- *Number = GETN2(22);
- GETN(24, 32, Contents);
- *Start = GETN4(188);
- *Length = GETN4(192);
- return 0;
-}
-
-/**
- * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1
- * on error.
- */
-static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor )
-{
- uint32_t lbsize, MT_L, N_PM;
- Unicodedecode(&data[84], 128, VolumeDescriptor);
- lbsize = GETN4(212); /* should be 2048*/
- MT_L = GETN4(264); /* should be 6 */
- N_PM = GETN4(268); /* should be 1 */
- if (lbsize != DVD_VIDEO_LB_LEN) return 1;
- return 0;
-}
-
-static int UDFFileEntry( uint8_t *data, uint8_t *FileType,
- struct Partition *partition, struct AD *ad )
-{
- uint16_t flags;
- uint32_t L_EA, L_AD;
- unsigned int p;
-
- UDFICB( &data[ 16 ], FileType, &flags );
-
- /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */
- ad->Length = GETN4( 60 ); /* Really 8 bytes a 56*/
- ad->Flags = 0;
- ad->Location = 0; /* what should we put here? */
- ad->Partition = partition->Number; /* use number of current partition*/
-
- L_EA = GETN4( 168 );
- L_AD = GETN4( 172 );
- p = 176 + L_EA;
- while( p < 176 + L_EA + L_AD ) {
- switch( flags & 0x0007 ) {
- case 0: UDFShortAD( &data[ p ], ad, partition ); p += 8; break;
- case 1: UDFLongAD( &data[ p ], ad ); p += 16; break;
- case 2: UDFExtAD( &data[ p ], ad ); p += 20; break;
- case 3:
- switch( L_AD ) {
- case 8: UDFShortAD( &data[ p ], ad, partition ); break;
- case 16: UDFLongAD( &data[ p ], ad ); break;
- case 20: UDFExtAD( &data[ p ], ad ); break;
- }
- p += L_AD;
- break;
- default:
- p += L_AD; break;
- }
- }
- return 0;
-}
-
-static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics,
- char *FileName, struct AD *FileICB )
-{
- uint8_t L_FI;
- uint16_t L_IU;
-
- *FileCharacteristics = GETN1(18);
- L_FI = GETN1(19);
- UDFLongAD(&data[20], FileICB);
- L_IU = GETN2(36);
- if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
- else FileName[0] = '\0';
- return 4 * ((38 + L_FI + L_IU + 3) / 4);
-}
-
-/**
- * Maps ICB to FileAD
- * ICB: Location of ICB of directory to scan
- * FileType: Type of the file
- * File: Location of file the ICB is pointing to
- * return 1 on success, 0 on error;
- */
-static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
- struct Partition *partition, struct AD *File )
-{
- uint8_t *LogBlock;
- uint32_t lbnum;
- uint16_t TagID;
- struct icbmap tmpmap;
-
- lbnum = partition->Start + ICB.Location;
- tmpmap.lbn = lbnum;
- if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
- *FileType = tmpmap.filetype;
- *File = tmpmap.file;
- return 1;
- }
-
- LogBlock = dvdalign_lbmalloc(device, 1);
- if(!LogBlock) {
- return 0;
- }
-
- do {
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
- TagID = 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
-
- if( TagID == 261 ) {
- UDFFileEntry( LogBlock, FileType, partition, File );
- tmpmap.file = *File;
- tmpmap.filetype = *FileType;
- SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
- dvdalign_lbfree(device, LogBlock);
- return 1;
- };
- } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 )
- / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) );
-
- dvdalign_lbfree(device, LogBlock);
- return 0;
-}
-
-/**
- * Dir: Location of directory to scan
- * FileName: Name of file to look for
- * FileICB: Location of ICB of the found file
- * return 1 on success, 0 on error;
- */
-static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
- struct Partition *partition, struct AD *FileICB,
- int cache_file_info)
-{
- char filename[ MAX_UDF_FILE_NAME_LEN ];
- uint8_t *directory;
- uint32_t lbnum;
- uint16_t TagID;
- uint8_t filechar;
- unsigned int p;
- uint8_t *cached_dir = NULL;
- uint32_t dir_lba;
- struct AD tmpICB;
- int found = 0;
- int in_cache = 0;
-
- /* Scan dir for ICB of file */
- lbnum = partition->Start + Dir.Location;
-
- if(DVDUDFCacheLevel(device, -1) > 0) {
- /* caching */
-
- if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
- dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
- if((cached_dir = dvdalign_lbmalloc(device, dir_lba)) == NULL) {
- return 0;
- }
- if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) {
- dvdalign_lbfree(device, cached_dir);
- cached_dir = NULL;
- }
- SetUDFCache(device, LBUDFCache, lbnum, &cached_dir);
- } else {
- in_cache = 1;
- }
-
- if(cached_dir == NULL) {
- return 0;
- }
-
- p = 0;
-
- while( p < Dir.Length ) {
- UDFDescriptor( &cached_dir[ p ], &TagID );
- if( TagID == 257 ) {
- p += UDFFileIdentifier( &cached_dir[ p ], &filechar,
- filename, &tmpICB );
- if(cache_file_info && !in_cache) {
- uint8_t tmpFiletype;
- struct AD tmpFile;
-
- if( !strcasecmp( FileName, filename ) ) {
- *FileICB = tmpICB;
- found = 1;
-
- }
- UDFMapICB(device, tmpICB, &tmpFiletype,
- partition, &tmpFile);
- } else {
- if( !strcasecmp( FileName, filename ) ) {
- *FileICB = tmpICB;
- return 1;
- }
- }
- } else {
- if(cache_file_info && (!in_cache) && found) {
- return 1;
- }
- return 0;
- }
- }
- if(cache_file_info && (!in_cache) && found) {
- return 1;
- }
- return 0;
- }
-
- directory = dvdalign_lbmalloc(device, 2);
- if(!directory) {
- return 0;
- }
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
- dvdalign_lbfree(device, directory);
- return 0;
- }
-
- p = 0;
- while( p < Dir.Length ) {
- if( p > DVD_VIDEO_LB_LEN ) {
- ++lbnum;
- p -= DVD_VIDEO_LB_LEN;
- Dir.Length -= DVD_VIDEO_LB_LEN;
- if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
- dvdalign_lbfree(device, directory);
- return 0;
- }
- }
- UDFDescriptor( &directory[ p ], &TagID );
- if( TagID == 257 ) {
- p += UDFFileIdentifier( &directory[ p ], &filechar,
- filename, FileICB );
- if( !strcasecmp( FileName, filename ) ) {
- dvdalign_lbfree(device, directory);
- return 1;
- }
- } else {
- dvdalign_lbfree(device, directory);
- return 0;
- }
- }
-
- dvdalign_lbfree(device, directory);
- return 0;
-}
-
-
-static int UDFGetAVDP( dvd_reader_t *device,
- struct avdp_t *avdp)
-{
- uint8_t *Anchor;
- uint32_t lbnum, MVDS_location, MVDS_length;
- uint16_t TagID;
- uint32_t lastsector;
- int terminate;
- struct avdp_t;
-
- if(GetUDFCache(device, AVDPCache, 0, avdp)) {
- return 1;
- }
-
- /* Find Anchor */
- lastsector = 0;
- lbnum = 256; /* Try #1, prime anchor */
- terminate = 0;
-
- Anchor = dvdalign_lbmalloc(device, 1);
- if(!Anchor) {
- return 0;
- }
- for(;;) {
- if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
- UDFDescriptor( Anchor, &TagID );
- } else {
- TagID = 0;
- }
- if (TagID != 2) {
- /* Not an anchor */
- if( terminate ) {
- dvdalign_lbfree(device, Anchor);
- errno = EMEDIUMTYPE;
- return 0; /* Final try failed */
- }
-
- if( lastsector ) {
- /* We already found the last sector. Try #3, alternative
- * backup anchor. If that fails, don't try again.
- */
- lbnum = lastsector;
- terminate = 1;
- } else {
- /* TODO: Find last sector of the disc (this is optional). */
- if( lastsector ) {
- /* Try #2, backup anchor */
- lbnum = lastsector - 256;
- } else {
- /* Unable to find last sector */
- dvdalign_lbfree(device, Anchor);
- errno = EMEDIUMTYPE;
- return 0;
- }
- }
- } else {
- /* It's an anchor! We can leave */
- break;
- }
- }
- /* Main volume descriptor */
- UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
- avdp->mvds.location = MVDS_location;
- avdp->mvds.length = MVDS_length;
-
- /* Backup volume descriptor */
- UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
- avdp->rvds.location = MVDS_location;
- avdp->rvds.length = MVDS_length;
-
- SetUDFCache(device, AVDPCache, 0, avdp);
-
- dvdalign_lbfree(device, Anchor);
- return 1;
-}
-
-/**
- * Looks for partition on the disc. Returns 1 if partition found, 0 on error.
- * partnum: Number of the partition, starting at 0.
- * part: structure to fill with the partition information
- */
-static int UDFFindPartition( dvd_reader_t *device, int partnum,
- struct Partition *part )
-{
- uint8_t *LogBlock;
- uint32_t lbnum, MVDS_location, MVDS_length;
- uint16_t TagID;
- int i, volvalid;
- struct avdp_t avdp;
-
-
- if(!UDFGetAVDP(device, &avdp)) {
- return 0;
- }
-
- LogBlock = dvdalign_lbmalloc(device, 1);
- if(!LogBlock) {
- return 0;
- }
- /* Main volume descriptor */
- MVDS_location = avdp.mvds.location;
- MVDS_length = avdp.mvds.length;
-
- part->valid = 0;
- volvalid = 0;
- part->VolumeDesc[ 0 ] = '\0';
- i = 1;
- do {
- /* Find Volume Descriptor */
- lbnum = MVDS_location;
- do {
-
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
- TagID = 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
-
- if( ( TagID == 5 ) && ( !part->valid ) ) {
- /* Partition Descriptor */
- UDFPartition( LogBlock, &part->Flags, &part->Number,
- part->Contents, &part->Start, &part->Length );
- part->valid = ( partnum == part->Number );
- } else if( ( TagID == 6 ) && ( !volvalid ) ) {
- /* Logical Volume Descriptor */
- if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) {
- /* TODO: sector size wrong! */
- } else {
- volvalid = 1;
- }
- }
-
- } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
- / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
- && ( ( !part->valid ) || ( !volvalid ) ) );
-
- if( ( !part->valid) || ( !volvalid ) ) {
- /* Backup volume descriptor */
- MVDS_location = avdp.mvds.location;
- MVDS_length = avdp.mvds.length;
- }
- } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
-
- dvdalign_lbfree(device, LogBlock);
- /* We only care for the partition, not the volume */
- return part->valid;
-}
-
-uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
- uint32_t *filesize )
-{
- uint8_t *LogBlock;
- uint32_t lbnum;
- uint16_t TagID;
- struct Partition partition;
- struct AD RootICB, File, ICB;
- char tokenline[ MAX_UDF_FILE_NAME_LEN ];
- char *token;
- uint8_t filetype;
-
- if(filesize) {
- *filesize = 0;
- }
- tokenline[0] = '\0';
- strcat( tokenline, filename );
-
-
- if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
- GetUDFCache(device, RootICBCache, 0, &RootICB))) {
- /* Find partition, 0 is the standard location for DVD Video.*/
- if( !UDFFindPartition( device, 0, &partition ) ) {
- return 0;
- }
- SetUDFCache(device, PartitionCache, 0, &partition);
-
- LogBlock = dvdalign_lbmalloc(device, 1);
- if(!LogBlock) {
- return 0;
- }
- /* Find root dir ICB */
- lbnum = partition.Start;
- do {
- if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
- TagID = 0;
- } else {
- UDFDescriptor( LogBlock, &TagID );
- }
-
- /* File Set Descriptor */
- if( TagID == 256 ) { /* File Set Descriptor*/
- UDFLongAD( &LogBlock[ 400 ], &RootICB );
- }
- } while( ( lbnum < partition.Start + partition.Length )
- && ( TagID != 8 ) && ( TagID != 256 ) );
-
- dvdalign_lbfree(device, LogBlock);
-
- /* Sanity checks. */
- if( TagID != 256 ) {
- return 0;
- }
- if( RootICB.Partition != 0 ) {
- return 0;
- }
- SetUDFCache(device, RootICBCache, 0, &RootICB);
- }
-
- /* Find root dir */
- if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) {
- return 0;
- }
- if( filetype != 4 ) {
- return 0; /* Root dir should be dir */
- }
- {
- int cache_file_info = 0;
- /* Tokenize filepath */
- token = strtok(tokenline, "/");
-
- while( token != NULL ) {
-
- if( !UDFScanDir( device, File, token, &partition, &ICB,
- cache_file_info)) {
- return 0;
- }
- if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
- return 0;
- }
- if(!strcmp(token, "VIDEO_TS")) {
- cache_file_info = 1;
- }
- token = strtok( NULL, "/" );
- }
- }
-
- /* Sanity check. */
- if( File.Partition != 0 ) {
- return 0;
- }
-
- if(filesize) {
- *filesize = File.Length;
- }
- /* Hack to not return partition.Start for empty files. */
- if( !File.Location ) {
- return 0;
- } else {
- return partition.Start + File.Location;
- }
-}
-
-
-
-/**
- * Gets a Descriptor .
- * Returns 1 if descriptor found, 0 on error.
- * id, tagid of descriptor
- * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN)
- * and aligned for raw/O_DIRECT read.
- */
-static int UDFGetDescriptor( dvd_reader_t *device, int id,
- uint8_t *descriptor, int bufsize)
-{
- uint32_t lbnum, MVDS_location, MVDS_length;
- struct avdp_t avdp;
- uint16_t TagID;
- uint32_t lastsector;
- int i, terminate;
- int desc_found = 0;
- /* Find Anchor */
- lastsector = 0;
- lbnum = 256; /* Try #1, prime anchor */
- terminate = 0;
- if(bufsize < DVD_VIDEO_LB_LEN) {
- return 0;
- }
-
- if(!UDFGetAVDP(device, &avdp)) {
- return 0;
- }
-
- /* Main volume descriptor */
- MVDS_location = avdp.mvds.location;
- MVDS_length = avdp.mvds.length;
-
- i = 1;
- do {
- /* Find Descriptor */
- lbnum = MVDS_location;
- do {
-
- if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) {
- TagID = 0;
- } else {
- UDFDescriptor( descriptor, &TagID );
- }
-
- if( (TagID == id) && ( !desc_found ) ) {
- /* Descriptor */
- desc_found = 1;
- }
- } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
- / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
- && ( !desc_found) );
-
- if( !desc_found ) {
- /* Backup volume descriptor */
- MVDS_location = avdp.rvds.location;
- MVDS_length = avdp.rvds.length;
- }
- } while( i-- && ( !desc_found ) );
-
-
- return desc_found;
-}
-
-
-static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
-{
- uint8_t *pvd_buf;
-
- if(GetUDFCache(device, PVDCache, 0, pvd)) {
- return 1;
- }
-
- pvd_buf = dvdalign_lbmalloc(device, 1);
- if(!pvd_buf) {
- return 0;
- }
- if(!UDFGetDescriptor( device, 1, pvd_buf, 1*DVD_VIDEO_LB_LEN)) {
- dvdalign_lbfree(device, pvd_buf);
- return 0;
- }
-
- memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
- memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
- SetUDFCache(device, PVDCache, 0, pvd);
-
- dvdalign_lbfree(device, pvd_buf);
-
- return 1;
-}
-
-/**
- * Gets the Volume Identifier string, in 8bit unicode (latin-1)
- * volid, place to put the string
- * volid_size, size of the buffer volid points to
- * returns the size of buffer needed for all data
- */
-int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,
- unsigned int volid_size)
-{
- struct pvd_t pvd;
- unsigned int volid_len;
-
- /* get primary volume descriptor */
- if(!UDFGetPVD(device, &pvd)) {
- return 0;
- }
-
- volid_len = pvd.VolumeIdentifier[31];
- if(volid_len > 31) {
- /* this field is only 32 bytes something is wrong */
- volid_len = 31;
- }
- if(volid_size > volid_len) {
- volid_size = volid_len;
- }
- Unicodedecode(pvd.VolumeIdentifier, volid_size, volid);
-
- return volid_len;
-}
-
-/**
- * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded)
- * WARNING This is not a null terminated string
- * volsetid, place to put the data
- * volsetid_size, size of the buffer volsetid points to
- * the buffer should be >=128 bytes to store the whole volumesetidentifier
- * returns the size of the available volsetid information (128)
- * or 0 on error
- */
-int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid,
- unsigned int volsetid_size)
-{
- struct pvd_t pvd;
-
- /* get primary volume descriptor */
- if(!UDFGetPVD(device, &pvd)) {
- return 0;
- }
-
-
- if(volsetid_size > 128) {
- volsetid_size = 128;
- }
-
- memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size);
-
- return 128;
-}
diff --git a/dvdread/dvd_udf.h b/dvdread/dvd_udf.h
deleted file mode 100644
index cf66ce4..0000000
--- a/dvdread/dvd_udf.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef DVD_UDF_H_INCLUDED
-#define DVD_UDF_H_INCLUDED
-
-/*
- * This code is based on dvdudf by:
- * Christian Wolff <scarabaeus@convergence.de>.
- *
- * Modifications by:
- * Billy Biggs <vektor@dumbterm.net>.
- * Björn Englund <d4bjorn@dtek.chalmers.se>.
- *
- * dvdudf: parse and read the UDF volume information of a DVD Video
- * Copyright (C) 1999 Christian Wolff for convergence integrated media
- * GmbH The author can be reached at scarabaeus@convergence.de, the
- * project's page is at http://linuxtv.org/dvd/
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA. Or, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#if defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#elif defined(HAVE_STDINT_H)
-#include <stdint.h>
-#endif
-
-#include "dvd_reader.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Looks for a file on the UDF disc/imagefile and returns the block number
- * where it begins, or 0 if it is not found. The filename should be an
- * absolute pathname on the UDF filesystem, starting with '/'. For example,
- * '/VIDEO_TS/VTS_01_1.IFO'. On success, filesize will be set to the size of
- * the file in bytes.
- * This implementation relies on that the file size is less than 2^32
- * A DVD file can at most be 2^30 (-2048 ?).
- */
-uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *size );
-
-void FreeUDFCache(dvd_reader_t *device, void *cache);
-int UDFGetVolumeIdentifier(dvd_reader_t *device,
- char *volid, unsigned int volid_size);
-int UDFGetVolumeSetIdentifier(dvd_reader_t *device,
- uint8_t *volsetid, unsigned int volsetid_size);
-#ifdef __cplusplus
-};
-#endif
-#endif /* DVD_UDF_H_INCLUDED */
diff --git a/dvdread/dvdread_internal.h b/dvdread/dvdread_internal.h
deleted file mode 100644
index 995d491..0000000
--- a/dvdread/dvdread_internal.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef DVDREAD_INTERNAL_H
-#define DVDREAD_INTERNAL_H
-
-
-#define CHECK_VALUE(arg) \
- if(!(arg)) { \
- fprintf(stderr, "\n*** libdvdread: CHECK_VALUE failed in %s:%i ***" \
- "\n*** for %s ***\n\n", \
- __FILE__, __LINE__, # arg ); \
- }
-
-
-int get_verbose(void);
-int dvdread_verbose(dvd_reader_t *dvd);
-dvd_reader_t *device_of_file(dvd_file_t *file);
-
-#endif /* DVDREAD_INTERNAL_H */
diff --git a/dvdread/ifo_read.c b/dvdread/ifo_read.c
deleted file mode 100644
index ff2d78c..0000000
--- a/dvdread/ifo_read.c
+++ /dev/null
@@ -1,2181 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 2000, 2001, 2002, 2003
- * Björn Englund <d4bjorn@dtek.chalmers.se>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#if defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#elif defined(HAVE_STDINT_H)
-#include <stdint.h>
-#endif
-
-#include <string.h>
-#include <errno.h>
-
-#include "bswap.h"
-#include "ifo_types.h"
-#include "ifo_read.h"
-#include "dvd_reader.h"
-#include "dvdread_internal.h"
-
-#ifndef DVD_BLOCK_LEN
-#define DVD_BLOCK_LEN 2048
-#endif
-
-#ifndef NDEBUG
-#define CHECK_ZERO0(arg) \
- if(arg != 0) { \
- fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x%x\n", \
- __FILE__, __LINE__, # arg, arg); \
- }
-#define CHECK_ZERO(arg) \
- if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \
- unsigned int i_CZ; \
- fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x", \
- __FILE__, __LINE__, # arg ); \
- for(i_CZ = 0; i_CZ < sizeof(arg); i_CZ++) \
- fprintf(stderr, "%02x", *((uint8_t *)&arg + i_CZ)); \
- fprintf(stderr, "\n"); \
- }
-static const uint8_t my_friendly_zeros[2048];
-#else
-#define CHECK_ZERO0(arg) (void)(arg)
-#define CHECK_ZERO(arg) (void)(arg)
-#endif
-
-
-/* Prototypes for internal functions */
-static int ifoRead_VMG(ifo_handle_t *ifofile);
-static int ifoRead_VTS(ifo_handle_t *ifofile);
-static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int offset);
-static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile,
- pgc_command_tbl_t *cmd_tbl,
- unsigned int offset);
-static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile,
- pgc_program_map_t *program_map,
- unsigned int nr, unsigned int offset);
-static int ifoRead_CELL_PLAYBACK_TBL(ifo_handle_t *ifofile,
- cell_playback_t *cell_playback,
- unsigned int nr, unsigned int offset);
-static int ifoRead_CELL_POSITION_TBL(ifo_handle_t *ifofile,
- cell_position_t *cell_position,
- unsigned int nr, unsigned int offset);
-static int ifoRead_VTS_ATTRIBUTES(ifo_handle_t *ifofile,
- vts_attributes_t *vts_attributes,
- unsigned int offset);
-static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile, c_adt_t *c_adt,
- unsigned int sector);
-static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,
- vobu_admap_t *vobu_admap,
- unsigned int sector);
-static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit,
- unsigned int offset);
-
-static void ifoFree_PGC(pgc_t *pgc);
-static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl);
-static void ifoFree_PGCIT_internal(pgcit_t *pgcit);
-
-static ifo_handle_t *ifoOpen_File(ifo_handle_t *ifofile, int title,
- char *suffix);
-static ifo_handle_t *ifoOpenVMGI_File(ifo_handle_t *ifofile, char *suffix);
-static ifo_handle_t *ifoOpenVTSI_File(ifo_handle_t *ifofile, int title,
- char *suffix);
-
-static int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
- return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
-}
-
-
-ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
- ifo_handle_t *ifofile;
-
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifoOpen_File(ifofile, title, "IFO")) {
- if(title) {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n",
- title, "IFO");
- }
- } else {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.%s.\n", "IFO");
- }
- }
- /* lower functions free the pointer, reallocate */
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
- if(!ifoOpen_File(ifofile, title, "BUP")) {
- if(title) {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n",
- title, "BUP");
- }
- } else {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.%s.\n", "BUP");
- }
- }
- return NULL;
- }
- }
- return ifofile;
-}
-
-static ifo_handle_t *ifoOpen_File(ifo_handle_t *ifofile, int title,
- char *suffix) {
- if(!ifofile->file) {
- free(ifofile);
- return NULL;
- }
-
- /* First check if this is a VMGI file. */
- if(ifoRead_VMG(ifofile)) {
-
- /* These are both mandatory. */
- if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s).\n",
- suffix);
- }
- ifoClose(ifofile);
- return NULL;
- }
-
- ifoRead_PGCI_UT(ifofile);
- ifoRead_PTL_MAIT(ifofile);
-
- /* This is also mandatory. */
- if(!ifoRead_VTS_ATRT(ifofile)) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s).\n",
- suffix);
- }
- ifoClose(ifofile);
- return NULL;
- }
-
- ifoRead_TXTDT_MGI(ifofile);
- ifoRead_C_ADT(ifofile);
- ifoRead_VOBU_ADMAP(ifofile);
-
- return ifofile;
- }
-
- if(ifoRead_VTS(ifofile)) {
-
- if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.%s).\n",
- title, suffix);
- }
- ifoClose(ifofile);
- return NULL;
- }
-
- ifoRead_PGCI_UT(ifofile);
- ifoRead_VTS_TMAPT(ifofile);
- ifoRead_C_ADT(ifofile);
- ifoRead_VOBU_ADMAP(ifofile);
-
- if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.%s).\n",
- title, suffix);
- }
- ifoClose(ifofile);
- return NULL;
- }
-
- return ifofile;
- }
-
- if(title) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.%s).\n",
- title, title, suffix);
- }
- } else {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.%s).\n",
- suffix);
- }
- }
- ifoClose(ifofile);
- return NULL;
-}
-
-
-ifo_handle_t *ifoOpenVMGI(dvd_reader_t *dvd) {
- ifo_handle_t *ifofile;
-
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE);
- if(!ifoOpenVMGI_File(ifofile, "IFO")) {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO: %s\n",
- strerror(errno));
- }
-
- /* lower functions free the pointer, reallocate */
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
- if(!ifoOpenVMGI_File(ifofile, "BUP"))
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.BUP: %s\n",
- strerror(errno));
- }
- return NULL;
- }
- return ifofile;
-}
-
-static ifo_handle_t *ifoOpenVMGI_File(ifo_handle_t *ifofile, char *suffix) {
- if(!ifofile->file) {
- free(ifofile);
- return NULL;
- }
-
- if(ifoRead_VMG(ifofile))
- return ifofile;
-
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.%s).\n",
- suffix);
- }
- ifoClose(ifofile);
- return NULL;
-}
-
-
-ifo_handle_t *ifoOpenVTSI(dvd_reader_t *dvd, int title) {
- ifo_handle_t *ifofile;
-
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- if(title <= 0 || title > 99) {
- if(dvdread_verbose(dvd) >= 0) {
- fprintf(stderr, "libdvdread: ifoOpenVTSI invalid title (%d).\n", title);
- }
- free(ifofile);
- errno = EINVAL;
- return NULL;
- }
-
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
- if(!ifoOpenVTSI_File(ifofile, title, "IFO")) {
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n", title, "IFO");
- }
- /* lower functions free the pointer, reallocate */
- ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
- if(!ifofile)
- return NULL;
-
- memset(ifofile, 0, sizeof(ifo_handle_t));
-
- ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
- if(!ifoOpenVTSI_File(ifofile, title, "BUP"))
- if(dvdread_verbose(dvd) >= 1) {
- fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.%s.\n", title, "BUP");
- }
- return NULL;
- }
- return ifofile;
-}
-
-static ifo_handle_t *ifoOpenVTSI_File(ifo_handle_t* ifofile, int title, char *suffix) {
- if(!ifofile->file) {
- free(ifofile);
- return NULL;
- }
-
- ifoRead_VTS(ifofile);
- if(ifofile->vtsi_mat)
- return ifofile;
-
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 0) {
- fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.%s).\n",
- title, title, suffix);
- }
- ifoClose(ifofile);
- return NULL;
-}
-
-
-void ifoClose(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- ifoFree_VOBU_ADMAP(ifofile);
- ifoFree_TITLE_VOBU_ADMAP(ifofile);
- ifoFree_C_ADT(ifofile);
- ifoFree_TITLE_C_ADT(ifofile);
- ifoFree_TXTDT_MGI(ifofile);
- ifoFree_VTS_ATRT(ifofile);
- ifoFree_PTL_MAIT(ifofile);
- ifoFree_PGCI_UT(ifofile);
- ifoFree_TT_SRPT(ifofile);
- ifoFree_FP_PGC(ifofile);
- ifoFree_PGCIT(ifofile);
- ifoFree_VTS_PTT_SRPT(ifofile);
- ifoFree_VTS_TMAPT(ifofile);
-
- if(ifofile->vmgi_mat)
- free(ifofile->vmgi_mat);
-
- if(ifofile->vtsi_mat)
- free(ifofile->vtsi_mat);
-
- DVDCloseFile(ifofile->file);
- ifofile->file = 0;
- free(ifofile);
- ifofile = 0;
-}
-
-
-static int ifoRead_VMG(ifo_handle_t *ifofile) {
- vmgi_mat_t *vmgi_mat;
-
- vmgi_mat = (vmgi_mat_t *)malloc(sizeof(vmgi_mat_t));
- if(!vmgi_mat)
- return 0;
-
- ifofile->vmgi_mat = vmgi_mat;
-
- if(!DVDFileSeek_(ifofile->file, 0)) {
- free(ifofile->vmgi_mat);
- ifofile->vmgi_mat = 0;
- return 0;
- }
-
- if(!DVDReadBytes(ifofile->file, vmgi_mat, sizeof(vmgi_mat_t))) {
- free(ifofile->vmgi_mat);
- ifofile->vmgi_mat = 0;
- return 0;
- }
-
- if(strncmp("DVDVIDEO-VMG", vmgi_mat->vmg_identifier, 12) != 0) {
- free(ifofile->vmgi_mat);
- ifofile->vmgi_mat = 0;
- return 0;
- }
-
- B2N_32(vmgi_mat->vmg_last_sector);
- B2N_32(vmgi_mat->vmgi_last_sector);
- B2N_32(vmgi_mat->vmg_category);
- B2N_16(vmgi_mat->vmg_nr_of_volumes);
- B2N_16(vmgi_mat->vmg_this_volume_nr);
- B2N_16(vmgi_mat->vmg_nr_of_title_sets);
- B2N_64(vmgi_mat->vmg_pos_code);
- B2N_32(vmgi_mat->vmgi_last_byte);
- B2N_32(vmgi_mat->first_play_pgc);
- B2N_32(vmgi_mat->vmgm_vobs);
- B2N_32(vmgi_mat->tt_srpt);
- B2N_32(vmgi_mat->vmgm_pgci_ut);
- B2N_32(vmgi_mat->ptl_mait);
- B2N_32(vmgi_mat->vts_atrt);
- B2N_32(vmgi_mat->txtdt_mgi);
- B2N_32(vmgi_mat->vmgm_c_adt);
- B2N_32(vmgi_mat->vmgm_vobu_admap);
- B2N_16(vmgi_mat->vmgm_audio_attr.lang_code);
- B2N_16(vmgi_mat->vmgm_subp_attr.lang_code);
-
-
- CHECK_ZERO(vmgi_mat->zero_1);
- CHECK_ZERO(vmgi_mat->zero_2);
- CHECK_ZERO(vmgi_mat->zero_3);
- CHECK_ZERO(vmgi_mat->zero_4);
- CHECK_ZERO(vmgi_mat->zero_5);
- CHECK_ZERO(vmgi_mat->zero_6);
- CHECK_ZERO(vmgi_mat->zero_7);
- CHECK_ZERO(vmgi_mat->zero_8);
- CHECK_ZERO(vmgi_mat->zero_9);
- CHECK_ZERO(vmgi_mat->zero_10);
- CHECK_VALUE(vmgi_mat->vmg_last_sector != 0);
- CHECK_VALUE(vmgi_mat->vmgi_last_sector != 0);
- CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
- CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
- CHECK_VALUE(vmgi_mat->vmg_nr_of_volumes != 0);
- CHECK_VALUE(vmgi_mat->vmg_this_volume_nr != 0);
- CHECK_VALUE(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes);
- CHECK_VALUE(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2);
- CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets != 0);
- CHECK_VALUE(vmgi_mat->vmgi_last_byte >= 341);
- CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <=
- vmgi_mat->vmgi_last_sector);
- /* It seems that first_play_pgc is optional. */
- CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte);
- CHECK_VALUE(vmgi_mat->vmgm_vobs == 0 ||
- (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector &&
- vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector));
- CHECK_VALUE(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector);
- CHECK_VALUE(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector);
-
- CHECK_VALUE(vmgi_mat->nr_of_vmgm_audio_streams <= 1);
- CHECK_VALUE(vmgi_mat->nr_of_vmgm_subp_streams <= 1);
-
- return 1;
-}
-
-
-static int ifoRead_VTS(ifo_handle_t *ifofile) {
- vtsi_mat_t *vtsi_mat;
- int i;
-
- vtsi_mat = (vtsi_mat_t *)malloc(sizeof(vtsi_mat_t));
- if(!vtsi_mat)
- return 0;
-
- ifofile->vtsi_mat = vtsi_mat;
-
- if(!DVDFileSeek_(ifofile->file, 0)) {
- free(ifofile->vtsi_mat);
- ifofile->vtsi_mat = 0;
- return 0;
- }
-
- if(!(DVDReadBytes(ifofile->file, vtsi_mat, sizeof(vtsi_mat_t)))) {
- free(ifofile->vtsi_mat);
- ifofile->vtsi_mat = 0;
- return 0;
- }
-
- if(strncmp("DVDVIDEO-VTS", vtsi_mat->vts_identifier, 12) != 0) {
- free(ifofile->vtsi_mat);
- ifofile->vtsi_mat = 0;
- return 0;
- }
-
- B2N_32(vtsi_mat->vts_last_sector);
- B2N_32(vtsi_mat->vtsi_last_sector);
- B2N_32(vtsi_mat->vts_category);
- B2N_32(vtsi_mat->vtsi_last_byte);
- B2N_32(vtsi_mat->vtsm_vobs);
- B2N_32(vtsi_mat->vtstt_vobs);
- B2N_32(vtsi_mat->vts_ptt_srpt);
- B2N_32(vtsi_mat->vts_pgcit);
- B2N_32(vtsi_mat->vtsm_pgci_ut);
- B2N_32(vtsi_mat->vts_tmapt);
- B2N_32(vtsi_mat->vtsm_c_adt);
- B2N_32(vtsi_mat->vtsm_vobu_admap);
- B2N_32(vtsi_mat->vts_c_adt);
- B2N_32(vtsi_mat->vts_vobu_admap);
- B2N_16(vtsi_mat->vtsm_audio_attr.lang_code);
- B2N_16(vtsi_mat->vtsm_subp_attr.lang_code);
- for(i = 0; i < 8; i++)
- B2N_16(vtsi_mat->vts_audio_attr[i].lang_code);
- for(i = 0; i < 32; i++)
- B2N_16(vtsi_mat->vts_subp_attr[i].lang_code);
-
-
- CHECK_ZERO(vtsi_mat->zero_1);
- CHECK_ZERO(vtsi_mat->zero_2);
- CHECK_ZERO(vtsi_mat->zero_3);
- CHECK_ZERO(vtsi_mat->zero_4);
- CHECK_ZERO(vtsi_mat->zero_5);
- CHECK_ZERO(vtsi_mat->zero_6);
- CHECK_ZERO(vtsi_mat->zero_7);
- CHECK_ZERO(vtsi_mat->zero_8);
- CHECK_ZERO(vtsi_mat->zero_9);
- CHECK_ZERO(vtsi_mat->zero_10);
- CHECK_ZERO(vtsi_mat->zero_11);
- CHECK_ZERO(vtsi_mat->zero_12);
- CHECK_ZERO(vtsi_mat->zero_13);
- CHECK_ZERO(vtsi_mat->zero_14);
- CHECK_ZERO(vtsi_mat->zero_15);
- CHECK_ZERO(vtsi_mat->zero_16);
- CHECK_ZERO(vtsi_mat->zero_17);
- CHECK_ZERO(vtsi_mat->zero_18);
- CHECK_ZERO(vtsi_mat->zero_19);
- CHECK_ZERO(vtsi_mat->zero_20);
- CHECK_ZERO(vtsi_mat->zero_21);
- CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector);
- CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vtsm_vobs == 0 ||
- (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
- vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector));
- CHECK_VALUE(vtsi_mat->vtstt_vobs == 0 ||
- (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector &&
- vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector));
- CHECK_VALUE(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector);
- CHECK_VALUE(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector);
-
- CHECK_VALUE(vtsi_mat->nr_of_vtsm_audio_streams <= 1);
- CHECK_VALUE(vtsi_mat->nr_of_vtsm_subp_streams <= 1);
-
- CHECK_VALUE(vtsi_mat->nr_of_vts_audio_streams <= 8);
- for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++)
- CHECK_ZERO(vtsi_mat->vts_audio_attr[i]);
-
- CHECK_VALUE(vtsi_mat->nr_of_vts_subp_streams <= 32);
- for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++)
- CHECK_ZERO(vtsi_mat->vts_subp_attr[i]);
-
- for(i = 0; i < 8; i++) {
- CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1);
- CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2);
- CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3);
- CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero4);
- CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero5);
- CHECK_ZERO(vtsi_mat->vts_mu_audio_attr[i].zero6);
- }
-
- return 1;
-}
-
-
-static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile,
- pgc_command_tbl_t *cmd_tbl,
- unsigned int offset) {
- unsigned int total;
-
- memset(cmd_tbl, 0, sizeof(pgc_command_tbl_t));
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, cmd_tbl, PGC_COMMAND_TBL_SIZE)))
- return 0;
-
- B2N_16(cmd_tbl->nr_of_pre);
- B2N_16(cmd_tbl->nr_of_post);
- B2N_16(cmd_tbl->nr_of_cell);
- B2N_16(cmd_tbl->last_byte);
-
- total = cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell;
- CHECK_VALUE(PGC_COMMAND_TBL_SIZE + total * COMMAND_DATA_SIZE
- <= cmd_tbl->last_byte + 1U);
- CHECK_VALUE(total <= 255);
-
- if(cmd_tbl->nr_of_pre != 0) {
- unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE;
- cmd_tbl->pre_cmds = (vm_cmd_t *)malloc(pre_cmds_size);
- if(!cmd_tbl->pre_cmds)
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, cmd_tbl->pre_cmds, pre_cmds_size))) {
- free(cmd_tbl->pre_cmds);
- return 0;
- }
- }
-
- if(cmd_tbl->nr_of_post != 0) {
- unsigned int post_cmds_size = cmd_tbl->nr_of_post * COMMAND_DATA_SIZE;
- cmd_tbl->post_cmds = (vm_cmd_t *)malloc(post_cmds_size);
- if(!cmd_tbl->post_cmds) {
- if(cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, cmd_tbl->post_cmds, post_cmds_size))) {
- if(cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
- free(cmd_tbl->post_cmds);
- return 0;
- }
- }
-
- if(cmd_tbl->nr_of_cell != 0) {
- unsigned int cell_cmds_size = cmd_tbl->nr_of_cell * COMMAND_DATA_SIZE;
- cmd_tbl->cell_cmds = (vm_cmd_t *)malloc(cell_cmds_size);
- if(!cmd_tbl->cell_cmds) {
- if(cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
- if(cmd_tbl->post_cmds)
- free(cmd_tbl->post_cmds);
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, cmd_tbl->cell_cmds, cell_cmds_size))) {
- if(cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
- if(cmd_tbl->post_cmds)
- free(cmd_tbl->post_cmds);
- free(cmd_tbl->cell_cmds);
- return 0;
- }
- }
-
- /*
- * Make a run over all the commands and see that we can interpret them all?
- */
- return 1;
-}
-
-
-static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) {
- if(cmd_tbl) {
- if(cmd_tbl->nr_of_pre && cmd_tbl->pre_cmds)
- free(cmd_tbl->pre_cmds);
- if(cmd_tbl->nr_of_post && cmd_tbl->post_cmds)
- free(cmd_tbl->post_cmds);
- if(cmd_tbl->nr_of_cell && cmd_tbl->cell_cmds)
- free(cmd_tbl->cell_cmds);
- free(cmd_tbl);
- }
-}
-
-static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile,
- pgc_program_map_t *program_map,
- unsigned int nr, unsigned int offset) {
- unsigned int size = nr * sizeof(pgc_program_map_t);
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, program_map, size)))
- return 0;
-
- return 1;
-}
-
-static int ifoRead_CELL_PLAYBACK_TBL(ifo_handle_t *ifofile,
- cell_playback_t *cell_playback,
- unsigned int nr, unsigned int offset) {
- unsigned int i;
- unsigned int size = nr * sizeof(cell_playback_t);
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, cell_playback, size)))
- return 0;
-
- for(i = 0; i < nr; i++) {
- B2N_32(cell_playback[i].first_sector);
- B2N_32(cell_playback[i].first_ilvu_end_sector);
- B2N_32(cell_playback[i].last_vobu_start_sector);
- B2N_32(cell_playback[i].last_sector);
-
- /* Changed < to <= because this was false in the movie 'Pi'. */
- CHECK_VALUE(cell_playback[i].last_vobu_start_sector <=
- cell_playback[i].last_sector);
- CHECK_VALUE(cell_playback[i].first_sector <=
- cell_playback[i].last_vobu_start_sector);
- }
-
- return 1;
-}
-
-
-static int ifoRead_CELL_POSITION_TBL(ifo_handle_t *ifofile,
- cell_position_t *cell_position,
- unsigned int nr, unsigned int offset) {
- unsigned int i;
- unsigned int size = nr * sizeof(cell_position_t);
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, cell_position, size)))
- return 0;
-
- for(i = 0; i < nr; i++) {
- B2N_16(cell_position[i].vob_id_nr);
- CHECK_ZERO(cell_position[i].zero_1);
- }
-
- return 1;
-}
-
-static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int offset) {
- unsigned int i;
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, pgc, PGC_SIZE)))
- return 0;
-
- B2N_16(pgc->next_pgc_nr);
- B2N_16(pgc->prev_pgc_nr);
- B2N_16(pgc->goup_pgc_nr);
- B2N_16(pgc->command_tbl_offset);
- B2N_16(pgc->program_map_offset);
- B2N_16(pgc->cell_playback_offset);
- B2N_16(pgc->cell_position_offset);
-
- for(i = 0; i < 8; i++)
- B2N_16(pgc->audio_control[i]);
- for(i = 0; i < 32; i++)
- B2N_32(pgc->subp_control[i]);
- for(i = 0; i < 16; i++)
- B2N_32(pgc->palette[i]);
-
- CHECK_ZERO(pgc->zero_1);
- CHECK_VALUE(pgc->nr_of_programs <= pgc->nr_of_cells);
-
- /* verify time (look at print_time) */
- for(i = 0; i < 8; i++)
- if(!pgc->audio_control[i] & 0x8000) /* The 'is present' bit */
- CHECK_ZERO(pgc->audio_control[i]);
- for(i = 0; i < 32; i++)
- if(!pgc->subp_control[i] & 0x80000000) /* The 'is present' bit */
- CHECK_ZERO(pgc->subp_control[i]);
-
- /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */
- if(pgc->nr_of_programs == 0) {
- CHECK_ZERO(pgc->still_time);
- CHECK_ZERO(pgc->pg_playback_mode); /* ??*/
- CHECK_VALUE(pgc->program_map_offset == 0);
- CHECK_VALUE(pgc->cell_playback_offset == 0);
- CHECK_VALUE(pgc->cell_position_offset == 0);
- } else {
- CHECK_VALUE(pgc->program_map_offset != 0);
- CHECK_VALUE(pgc->cell_playback_offset != 0);
- CHECK_VALUE(pgc->cell_position_offset != 0);
- }
-
- if(pgc->command_tbl_offset != 0) {
- pgc->command_tbl = malloc(sizeof(pgc_command_tbl_t));
- if(!pgc->command_tbl)
- return 0;
-
- if(!ifoRead_PGC_COMMAND_TBL(ifofile, pgc->command_tbl,
- offset + pgc->command_tbl_offset)) {
- free(pgc->command_tbl);
- return 0;
- }
- } else {
- pgc->command_tbl = NULL;
- }
-
- if(pgc->program_map_offset != 0) {
- if(pgc->nr_of_programs != 0) {
-
- pgc->program_map = malloc(pgc->nr_of_programs * sizeof(pgc_program_map_t));
- if(!pgc->program_map) {
- ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
- return 0;
- }
- if(!ifoRead_PGC_PROGRAM_MAP(ifofile, pgc->program_map,pgc->nr_of_programs,
- offset + pgc->program_map_offset)) {
- ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
- free(pgc->program_map);
- return 0;
- }
- } else {
- pgc->program_map = NULL;
- }
- } else {
- pgc->program_map = NULL;
- }
-
- if(pgc->cell_playback_offset != 0) {
- if(pgc->nr_of_cells != 0) {
-
- pgc->cell_playback = malloc(pgc->nr_of_cells * sizeof(cell_playback_t));
- if(!pgc->cell_playback) {
- ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
- if(pgc->program_map)
- free(pgc->program_map);
- return 0;
- }
- if(!ifoRead_CELL_PLAYBACK_TBL(ifofile, pgc->cell_playback,
- pgc->nr_of_cells,
- offset + pgc->cell_playback_offset)) {
- ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
- if(pgc->program_map)
- free(pgc->program_map);
- free(pgc->cell_playback);
- return 0;
- }
- } else {
- pgc->cell_playback = NULL;
- }
- } else {
- pgc->cell_playback = NULL;
- }
-
- if(pgc->cell_position_offset != 0) {
- if(pgc->nr_of_cells != 0) {
-
- pgc->cell_position = malloc(pgc->nr_of_cells * sizeof(cell_position_t));
- if(!pgc->cell_position) {
- ifoFree_PGC(pgc);
- return 0;
- }
- if(!ifoRead_CELL_POSITION_TBL(ifofile, pgc->cell_position,
- pgc->nr_of_cells,
- offset + pgc->cell_position_offset)) {
- ifoFree_PGC(pgc);
- return 0;
- }
- } else {
- pgc->cell_position = NULL;
- }
- } else {
- pgc->cell_position = NULL;
- }
-
- return 1;
-}
-
-int ifoRead_FP_PGC(ifo_handle_t *ifofile) {
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vmgi_mat)
- return 0;
-
- /* It seems that first_play_pgc is optional after all. */
- ifofile->first_play_pgc = 0;
- if(ifofile->vmgi_mat->first_play_pgc == 0)
- return 1;
-
- ifofile->first_play_pgc = (pgc_t *)malloc(sizeof(pgc_t));
- if(!ifofile->first_play_pgc)
- return 0;
-
- if(!ifoRead_PGC(ifofile, ifofile->first_play_pgc,
- ifofile->vmgi_mat->first_play_pgc)) {
- free(ifofile->first_play_pgc);
- ifofile->first_play_pgc = 0;
- return 0;
- }
-
- return 1;
-}
-
-static void ifoFree_PGC(pgc_t *pgc) {
- if(pgc) {
- ifoFree_PGC_COMMAND_TBL(pgc->command_tbl);
- if(pgc->program_map)
- free(pgc->program_map);
- if(pgc->cell_playback)
- free(pgc->cell_playback);
- if(pgc->cell_position)
- free(pgc->cell_position);
- }
-}
-
-void ifoFree_FP_PGC(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->first_play_pgc) {
- ifoFree_PGC(ifofile->first_play_pgc);
- free(ifofile->first_play_pgc);
- ifofile->first_play_pgc = 0;
- }
-}
-
-
-int ifoRead_TT_SRPT(ifo_handle_t *ifofile) {
- tt_srpt_t *tt_srpt;
- int i, info_length;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vmgi_mat)
- return 0;
-
- if(ifofile->vmgi_mat->tt_srpt == 0) /* mandatory */
- return 0;
-
- if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->tt_srpt * DVD_BLOCK_LEN))
- return 0;
-
- tt_srpt = (tt_srpt_t *)malloc(sizeof(tt_srpt_t));
- if(!tt_srpt)
- return 0;
-
- ifofile->tt_srpt = tt_srpt;
-
- if(!(DVDReadBytes(ifofile->file, tt_srpt, TT_SRPT_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n");
- }
- free(tt_srpt);
- return 0;
- }
-
- B2N_16(tt_srpt->nr_of_srpts);
- B2N_32(tt_srpt->last_byte);
-
- info_length = tt_srpt->last_byte + 1 - TT_SRPT_SIZE;
-
- tt_srpt->title = (title_info_t *)malloc(info_length);
- if(!tt_srpt->title) {
- free(tt_srpt);
- ifofile->tt_srpt = 0;
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, tt_srpt->title, info_length))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n");
- }
- ifoFree_TT_SRPT(ifofile);
- return 0;
- }
-
- for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
- B2N_16(tt_srpt->title[i].nr_of_ptts);
- B2N_16(tt_srpt->title[i].parental_id);
- B2N_32(tt_srpt->title[i].title_set_sector);
- }
-
-
- CHECK_ZERO(tt_srpt->zero_1);
- CHECK_VALUE(tt_srpt->nr_of_srpts != 0);
- CHECK_VALUE(tt_srpt->nr_of_srpts < 100); /*??*/
- CHECK_VALUE(tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length);
-
- for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
- CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 == 0);
- CHECK_VALUE(tt_srpt->title[i].nr_of_angles != 0);
- CHECK_VALUE(tt_srpt->title[i].nr_of_angles < 10);
- /*CHECK_VALUE(tt_srpt->title[i].nr_of_ptts != 0);
- / XXX: this assertion breaks Ghostbusters:*/
- CHECK_VALUE(tt_srpt->title[i].nr_of_ptts < 1000); /*??*/
- CHECK_VALUE(tt_srpt->title[i].title_set_nr != 0);
- CHECK_VALUE(tt_srpt->title[i].title_set_nr < 100); /* ?? */
- CHECK_VALUE(tt_srpt->title[i].vts_ttn != 0);
- CHECK_VALUE(tt_srpt->title[i].vts_ttn < 100); /* ?? */
- /*CHECK_VALUE(tt_srpt->title[i].title_set_sector != 0);*/
- }
-
- /* Make this a function*/
-#if 0
- if(memcmp((uint8_t *)tt_srpt->title +
- tt_srpt->nr_of_srpts * sizeof(title_info_t),
- my_friendly_zeros,
- info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t))) {
- fprintf(stderr, "VMG_PTT_SRPT slack is != 0, ");
- hexdump((uint8_t *)tt_srpt->title +
- tt_srpt->nr_of_srpts * sizeof(title_info_t),
- info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t));
- }
-#endif
-
- return 1;
-}
-
-
-void ifoFree_TT_SRPT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->tt_srpt) {
- free(ifofile->tt_srpt->title);
- free(ifofile->tt_srpt);
- ifofile->tt_srpt = 0;
- }
-}
-
-
-int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
- vts_ptt_srpt_t *vts_ptt_srpt;
- int info_length, i, j;
- uint32_t *data;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vtsi_mat)
- return 0;
-
- if(ifofile->vtsi_mat->vts_ptt_srpt == 0) /* mandatory */
- return 0;
-
- if(!DVDFileSeek_(ifofile->file,
- ifofile->vtsi_mat->vts_ptt_srpt * DVD_BLOCK_LEN))
- return 0;
-
- vts_ptt_srpt = (vts_ptt_srpt_t *)malloc(sizeof(vts_ptt_srpt_t));
- if(!vts_ptt_srpt)
- return 0;
-
- ifofile->vts_ptt_srpt = vts_ptt_srpt;
-
- if(!(DVDReadBytes(ifofile->file, vts_ptt_srpt, VTS_PTT_SRPT_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
- }
- free(vts_ptt_srpt);
- return 0;
- }
-
- B2N_16(vts_ptt_srpt->nr_of_srpts);
- B2N_32(vts_ptt_srpt->last_byte);
-
- CHECK_ZERO(vts_ptt_srpt->zero_1);
- CHECK_VALUE(vts_ptt_srpt->nr_of_srpts != 0);
- CHECK_VALUE(vts_ptt_srpt->nr_of_srpts < 100); /* ??*/
-
- info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
-
- data = (uint32_t *)malloc(info_length);
- if(!data) {
- free(vts_ptt_srpt);
- ifofile->vts_ptt_srpt = 0;
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, data, info_length))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
- }
- free(vts_ptt_srpt);
- free(data);
- ifofile->vts_ptt_srpt = 0;
- return 0;
- }
-
- for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
- B2N_32(data[i]);
- /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
- Magic Knight Rayearth Daybreak is mastered very strange and has
- Titles with 0 PTTs. They all have a data[i] offsets beyond the end of
- of the vts_ptt_srpt structure. */
- CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4);
- }
-
- vts_ptt_srpt->ttu_offset = data;
-
- vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t));
- if(!vts_ptt_srpt->title) {
- free(vts_ptt_srpt);
- free(data);
- ifofile->vts_ptt_srpt = 0;
- return 0;
- }
- for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
- int n;
- if(i < vts_ptt_srpt->nr_of_srpts - 1)
- n = (data[i+1] - data[i]);
- else
- n = (vts_ptt_srpt->last_byte + 1 - data[i]);
- /* assert(n > 0 && (n % 4) == 0);
- Magic Knight Rayearth Daybreak is mastered very strange and has
- Titles with 0 PTTs. */
- if(n < 0) n = 0;
- CHECK_VALUE(n % 4 == 0);
-
- vts_ptt_srpt->title[i].nr_of_ptts = n / 4;
- vts_ptt_srpt->title[i].ptt = malloc(n * sizeof(ptt_info_t));
- if(!vts_ptt_srpt->title[i].ptt) {
- for(n = 0; n < i; n++)
- free(vts_ptt_srpt->title[n].ptt);
- free(vts_ptt_srpt);
- free(data);
- ifofile->vts_ptt_srpt = 0;
- return 0;
- }
- for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
- /* The assert placed here because of Magic Knight Rayearth Daybreak */
- CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
- vts_ptt_srpt->title[i].ptt[j].pgcn
- = *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_SIZE);
- vts_ptt_srpt->title[i].ptt[j].pgn
- = *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE);
- }
- }
-
- for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
- for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
- B2N_16(vts_ptt_srpt->title[i].ptt[j].pgcn);
- B2N_16(vts_ptt_srpt->title[i].ptt[j].pgn);
- }
- }
-
- for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
- CHECK_VALUE(vts_ptt_srpt->title[i].nr_of_ptts < 1000); /* ??*/
- for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
- CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 );
- CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); /* ??*/
- CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn != 0);
- CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn < 100); /* ?? */
- }
- }
-
- return 1;
-}
-
-
-void ifoFree_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->vts_ptt_srpt) {
- int i;
- for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++)
- free(ifofile->vts_ptt_srpt->title[i].ptt);
- free(ifofile->vts_ptt_srpt->ttu_offset);
- free(ifofile->vts_ptt_srpt->title);
- free(ifofile->vts_ptt_srpt);
- ifofile->vts_ptt_srpt = 0;
- }
-}
-
-
-int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
- ptl_mait_t *ptl_mait;
- int info_length;
- unsigned int i, j;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vmgi_mat)
- return 0;
-
- if(ifofile->vmgi_mat->ptl_mait == 0)
- return 1;
-
- if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
- return 0;
-
- ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t));
- if(!ptl_mait)
- return 0;
-
- ifofile->ptl_mait = ptl_mait;
-
- if(!(DVDReadBytes(ifofile->file, ptl_mait, PTL_MAIT_SIZE))) {
- free(ptl_mait);
- ifofile->ptl_mait = 0;
- return 0;
- }
-
- B2N_16(ptl_mait->nr_of_countries);
- B2N_16(ptl_mait->nr_of_vtss);
- B2N_32(ptl_mait->last_byte);
-
- CHECK_VALUE(ptl_mait->nr_of_countries != 0);
- CHECK_VALUE(ptl_mait->nr_of_countries < 100); /* ?? */
- CHECK_VALUE(ptl_mait->nr_of_vtss != 0);
- CHECK_VALUE(ptl_mait->nr_of_vtss < 100); /* ?? */
- CHECK_VALUE(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE
- <= ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
-
- info_length = ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t);
- ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length);
- if(!ptl_mait->countries) {
- free(ptl_mait);
- ifofile->ptl_mait = 0;
- return 0;
- }
-
- for(i = 0; i < ptl_mait->nr_of_countries; i++) {
- if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- ifofile->ptl_mait = 0;
- return 0;
- }
- }
-
- for(i = 0; i < ptl_mait->nr_of_countries; i++) {
- B2N_16(ptl_mait->countries[i].country_code);
- B2N_16(ptl_mait->countries[i].pf_ptl_mai_start_byte);
- }
-
- for(i = 0; i < ptl_mait->nr_of_countries; i++) {
- CHECK_ZERO(ptl_mait->countries[i].zero_1);
- CHECK_ZERO(ptl_mait->countries[i].zero_2);
- CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte +
- 16U * (ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1U);
- }
-
- for(i = 0; i < ptl_mait->nr_of_countries; i++) {
- uint16_t *pf_temp;
-
- if(!DVDFileSeek_(ifofile->file,
- ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
- + ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- return 0;
- }
- info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
- pf_temp = (uint16_t *)malloc(info_length);
- if(!pf_temp) {
- for(j = 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
- }
- free(pf_temp);
- for(j = 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- return 0;
- }
- for (j = 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
- B2N_16(pf_temp[j]);
- }
- ptl_mait->countries[i].pf_ptl_mai = (pf_level_t *)malloc(info_length);
- if(!ptl_mait->countries[i].pf_ptl_mai) {
- free(pf_temp);
- for(j = 0; j < i ; j++) {
- free(ptl_mait->countries[j].pf_ptl_mai);
- }
- free(ptl_mait->countries);
- free(ptl_mait);
- return 0;
- }
- { /* Transpose the array so we can use C indexing. */
- int level, vts;
- for(level = 0; level < 8; level++) {
- for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
- ptl_mait->countries[i].pf_ptl_mai[vts][level] =
- pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
- }
- }
- free(pf_temp);
- }
- }
- return 1;
-}
-
-void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) {
- unsigned int i;
-
- if(!ifofile)
- return;
-
- if(ifofile->ptl_mait) {
- for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
- free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
- }
- free(ifofile->ptl_mait->countries);
- free(ifofile->ptl_mait);
- ifofile->ptl_mait = 0;
- }
-}
-
-int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) {
- vts_tmapt_t *vts_tmapt;
- uint32_t *vts_tmap_srp;
- unsigned int offset;
- int info_length;
- unsigned int i, j;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vtsi_mat)
- return 0;
-
- /* Seems to be optional, at least when there are no OneSequencial Titles */
- if(ifofile->vtsi_mat->vts_tmapt == 0) {
- ifofile->vts_tmapt = NULL;
- return 1;
- }
-
- offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN;
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- vts_tmapt = (vts_tmapt_t *)malloc(sizeof(vts_tmapt_t));
- if(!vts_tmapt)
- return 0;
-
- ifofile->vts_tmapt = vts_tmapt;
-
- if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
- }
- free(vts_tmapt);
- ifofile->vts_tmapt = NULL;
- return 0;
- }
-
- B2N_16(vts_tmapt->nr_of_tmaps);
- B2N_32(vts_tmapt->last_byte);
-
- CHECK_ZERO(vts_tmapt->zero_1);
-
- info_length = vts_tmapt->nr_of_tmaps * 4;
-
- vts_tmap_srp = (uint32_t *)malloc(info_length);
- if(!vts_tmap_srp) {
- free(vts_tmapt);
- ifofile->vts_tmapt = NULL;
- return 0;
- }
-
- vts_tmapt->tmap_offset = vts_tmap_srp;
-
- if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
- }
- free(vts_tmap_srp);
- free(vts_tmapt);
- ifofile->vts_tmapt = NULL;
- return 0;
- }
-
- for (i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
- B2N_32(vts_tmap_srp[i]);
- }
-
-
- info_length = vts_tmapt->nr_of_tmaps * sizeof(vts_tmap_t);
-
- vts_tmapt->tmap = (vts_tmap_t *)malloc(info_length);
- if(!vts_tmapt->tmap) {
- free(vts_tmap_srp);
- free(vts_tmapt);
- ifofile->vts_tmapt = NULL;
- return 0;
- }
-
- memset(vts_tmapt->tmap, 0, info_length); /* So ifoFree_VTS_TMAPT works. */
-
- for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
- if(!DVDFileSeek_(ifofile->file, offset + vts_tmap_srp[i])) {
- ifoFree_VTS_TMAPT(ifofile);
- return 0;
- }
-
- if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n");
- }
- ifoFree_VTS_TMAPT(ifofile);
- return 0;
- }
-
- B2N_16(vts_tmapt->tmap[i].nr_of_entries);
- CHECK_ZERO(vts_tmapt->tmap[i].zero_1);
-
- if(vts_tmapt->tmap[i].nr_of_entries == 0) { /* Early out if zero entries */
- vts_tmapt->tmap[i].map_ent = NULL;
- continue;
- }
-
- info_length = vts_tmapt->tmap[i].nr_of_entries * sizeof(map_ent_t);
-
- vts_tmapt->tmap[i].map_ent = (map_ent_t *)malloc(info_length);
- if(!vts_tmapt->tmap[i].map_ent) {
- ifoFree_VTS_TMAPT(ifofile);
- return 0;
- }
-
- if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_length))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
- }
- ifoFree_VTS_TMAPT(ifofile);
- return 0;
- }
-
- for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++)
- B2N_32(vts_tmapt->tmap[i].map_ent[j]);
- }
-
- return 1;
-}
-
-void ifoFree_VTS_TMAPT(ifo_handle_t *ifofile) {
- unsigned int i;
-
- if(!ifofile)
- return;
-
- if(ifofile->vts_tmapt) {
- for(i = 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++)
- if(ifofile->vts_tmapt->tmap[i].map_ent)
- free(ifofile->vts_tmapt->tmap[i].map_ent);
- free(ifofile->vts_tmapt->tmap);
- free(ifofile->vts_tmapt->tmap_offset);
- free(ifofile->vts_tmapt);
- ifofile->vts_tmapt = NULL;
- }
-}
-
-
-int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) {
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vtsi_mat)
- return 0;
-
- if(ifofile->vtsi_mat->vts_c_adt == 0) /* mandatory */
- return 0;
-
- ifofile->vts_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t));
- if(!ifofile->vts_c_adt)
- return 0;
-
- if(!ifoRead_C_ADT_internal(ifofile, ifofile->vts_c_adt,
- ifofile->vtsi_mat->vts_c_adt)) {
- free(ifofile->vts_c_adt);
- ifofile->vts_c_adt = 0;
- return 0;
- }
-
- return 1;
-}
-
-int ifoRead_C_ADT(ifo_handle_t *ifofile) {
- unsigned int sector;
-
- if(!ifofile)
- return 0;
-
- if(ifofile->vmgi_mat) {
- if(ifofile->vmgi_mat->vmgm_c_adt == 0)
- return 1;
- sector = ifofile->vmgi_mat->vmgm_c_adt;
- } else if(ifofile->vtsi_mat) {
- if(ifofile->vtsi_mat->vtsm_c_adt == 0)
- return 1;
- sector = ifofile->vtsi_mat->vtsm_c_adt;
- } else {
- return 0;
- }
-
- ifofile->menu_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t));
- if(!ifofile->menu_c_adt)
- return 0;
-
- if(!ifoRead_C_ADT_internal(ifofile, ifofile->menu_c_adt, sector)) {
- free(ifofile->menu_c_adt);
- ifofile->menu_c_adt = 0;
- return 0;
- }
-
- return 1;
-}
-
-static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile,
- c_adt_t *c_adt, unsigned int sector) {
- int i, info_length;
-
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, c_adt, C_ADT_SIZE)))
- return 0;
-
- B2N_16(c_adt->nr_of_vobs);
- B2N_32(c_adt->last_byte);
-
- info_length = c_adt->last_byte + 1 - C_ADT_SIZE;
-
- CHECK_ZERO(c_adt->zero_1);
- /* assert(c_adt->nr_of_vobs > 0);
- Magic Knight Rayearth Daybreak is mastered very strange and has
- Titles with a VOBS that has no cells. */
- CHECK_VALUE(info_length % sizeof(cell_adr_t) == 0);
-
- /* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs);
- Enemy of the State region 2 (de) has Titles where nr_of_vobs field
- is to high, they high ones are never referenced though. */
- if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: *C_ADT nr_of_vobs > avaiable info entries\n");
- }
- c_adt->nr_of_vobs = info_length / sizeof(cell_adr_t);
- }
-
- c_adt->cell_adr_table = (cell_adr_t *)malloc(info_length);
- if(!c_adt->cell_adr_table)
- return 0;
-
- if(info_length &&
- !(DVDReadBytes(ifofile->file, c_adt->cell_adr_table, info_length))) {
- free(c_adt->cell_adr_table);
- return 0;
- }
-
- for(i = 0; i < info_length/sizeof(cell_adr_t); i++) {
- B2N_16(c_adt->cell_adr_table[i].vob_id);
- B2N_32(c_adt->cell_adr_table[i].start_sector);
- B2N_32(c_adt->cell_adr_table[i].last_sector);
-
- CHECK_ZERO(c_adt->cell_adr_table[i].zero_1);
- CHECK_VALUE(c_adt->cell_adr_table[i].vob_id > 0);
- CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs);
- CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0);
- CHECK_VALUE(c_adt->cell_adr_table[i].start_sector <
- c_adt->cell_adr_table[i].last_sector);
- }
-
- return 1;
-}
-
-
-static void ifoFree_C_ADT_internal(c_adt_t *c_adt) {
- if(c_adt) {
- free(c_adt->cell_adr_table);
- free(c_adt);
- }
-}
-
-void ifoFree_C_ADT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- ifoFree_C_ADT_internal(ifofile->menu_c_adt);
- ifofile->menu_c_adt = 0;
-}
-
-void ifoFree_TITLE_C_ADT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- ifoFree_C_ADT_internal(ifofile->vts_c_adt);
- ifofile->vts_c_adt = 0;
-}
-
-int ifoRead_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) {
- if(!ifofile)
- return 0;
-
- if(!ifofile->vtsi_mat)
- return 0;
-
- if(ifofile->vtsi_mat->vts_vobu_admap == 0) /* mandatory */
- return 0;
-
- ifofile->vts_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t));
- if(!ifofile->vts_vobu_admap)
- return 0;
-
- if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->vts_vobu_admap,
- ifofile->vtsi_mat->vts_vobu_admap)) {
- free(ifofile->vts_vobu_admap);
- ifofile->vts_vobu_admap = 0;
- return 0;
- }
-
- return 1;
-}
-
-int ifoRead_VOBU_ADMAP(ifo_handle_t *ifofile) {
- unsigned int sector;
-
- if(!ifofile)
- return 0;
-
- if(ifofile->vmgi_mat) {
- if(ifofile->vmgi_mat->vmgm_vobu_admap == 0)
- return 1;
- sector = ifofile->vmgi_mat->vmgm_vobu_admap;
- } else if(ifofile->vtsi_mat) {
- if(ifofile->vtsi_mat->vtsm_vobu_admap == 0)
- return 1;
- sector = ifofile->vtsi_mat->vtsm_vobu_admap;
- } else {
- return 0;
- }
-
- ifofile->menu_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t));
- if(!ifofile->menu_vobu_admap)
- return 0;
-
- if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->menu_vobu_admap, sector)) {
- free(ifofile->menu_vobu_admap);
- ifofile->menu_vobu_admap = 0;
- return 0;
- }
-
- return 1;
-}
-
-static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,
- vobu_admap_t *vobu_admap,
- unsigned int sector) {
- unsigned int i;
- int info_length;
-
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE)))
- return 0;
-
- B2N_32(vobu_admap->last_byte);
-
- info_length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
- /* assert(info_length > 0);
- Magic Knight Rayearth Daybreak is mastered very strange and has
- Titles with a VOBS that has no VOBUs. */
- CHECK_VALUE(info_length % sizeof(uint32_t) == 0);
-
- vobu_admap->vobu_start_sectors = (uint32_t *)malloc(info_length);
- if(!vobu_admap->vobu_start_sectors) {
- return 0;
- }
- if(info_length &&
- !(DVDReadBytes(ifofile->file,
- vobu_admap->vobu_start_sectors, info_length))) {
- free(vobu_admap->vobu_start_sectors);
- return 0;
- }
-
- for(i = 0; i < info_length/sizeof(uint32_t); i++)
- B2N_32(vobu_admap->vobu_start_sectors[i]);
-
- return 1;
-}
-
-
-static void ifoFree_VOBU_ADMAP_internal(vobu_admap_t *vobu_admap) {
- if(vobu_admap) {
- free(vobu_admap->vobu_start_sectors);
- free(vobu_admap);
- }
-}
-
-void ifoFree_VOBU_ADMAP(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- ifoFree_VOBU_ADMAP_internal(ifofile->menu_vobu_admap);
- ifofile->menu_vobu_admap = 0;
-}
-
-void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- ifoFree_VOBU_ADMAP_internal(ifofile->vts_vobu_admap);
- ifofile->vts_vobu_admap = 0;
-}
-
-int ifoRead_PGCIT(ifo_handle_t *ifofile) {
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vtsi_mat)
- return 0;
-
- if(ifofile->vtsi_mat->vts_pgcit == 0) /* mandatory */
- return 0;
-
- ifofile->vts_pgcit = (pgcit_t *)malloc(sizeof(pgcit_t));
- if(!ifofile->vts_pgcit)
- return 0;
-
- if(!ifoRead_PGCIT_internal(ifofile, ifofile->vts_pgcit,
- ifofile->vtsi_mat->vts_pgcit * DVD_BLOCK_LEN)) {
- free(ifofile->vts_pgcit);
- ifofile->vts_pgcit = 0;
- return 0;
- }
-
- return 1;
-}
-
-static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit,
- unsigned int offset) {
- int i, info_length;
- uint8_t *data, *ptr;
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, pgcit, PGCIT_SIZE)))
- return 0;
-
- B2N_16(pgcit->nr_of_pgci_srp);
- B2N_32(pgcit->last_byte);
-
- CHECK_ZERO(pgcit->zero_1);
- /* assert(pgcit->nr_of_pgci_srp != 0);
- Magic Knight Rayearth Daybreak is mastered very strange and has
- Titles with 0 PTTs. */
- CHECK_VALUE(pgcit->nr_of_pgci_srp < 10000); /* ?? seen max of 1338*/
-
- info_length = pgcit->nr_of_pgci_srp * PGCI_SRP_SIZE;
- data = malloc(info_length);
- if(!data)
- return 0;
-
- if(info_length && !(DVDReadBytes(ifofile->file, data, info_length))) {
- free(data);
- return 0;
- }
-
- pgcit->pgci_srp = malloc(pgcit->nr_of_pgci_srp * sizeof(pgci_srp_t));
- if(!pgcit->pgci_srp) {
- free(data);
- return 0;
- }
- ptr = data;
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
- memcpy(&pgcit->pgci_srp[i], ptr, PGCI_SRP_SIZE);
- ptr += PGCI_SRP_SIZE;
- B2N_16(pgcit->pgci_srp[i].ptl_id_mask);
- B2N_32(pgcit->pgci_srp[i].pgc_start_byte);
- CHECK_VALUE(pgcit->pgci_srp[i].unknown1 == 0);
- }
- free(data);
-
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++)
- CHECK_VALUE(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1);
-
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
- pgcit->pgci_srp[i].pgc = malloc(sizeof(pgc_t));
- if(!pgcit->pgci_srp[i].pgc) {
- int j;
- for(j = 0; j < i; j++) {
- ifoFree_PGC(pgcit->pgci_srp[j].pgc);
- free(pgcit->pgci_srp[j].pgc);
- }
- free(pgcit->pgci_srp);
- pgcit->pgci_srp = NULL;
- return 0;
- }
- if(!ifoRead_PGC(ifofile, pgcit->pgci_srp[i].pgc,
- offset + pgcit->pgci_srp[i].pgc_start_byte)) {
- int j;
- for(j = 0; j < i; j++) {
- ifoFree_PGC(pgcit->pgci_srp[j].pgc);
- free(pgcit->pgci_srp[j].pgc);
- }
- free(pgcit->pgci_srp);
- pgcit->pgci_srp = NULL;
- return 0;
- }
- }
-
- return 1;
-}
-
-static void ifoFree_PGCIT_internal(pgcit_t *pgcit) {
- if(pgcit) {
- int i;
- for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
- ifoFree_PGC(pgcit->pgci_srp[i].pgc);
- free(pgcit->pgci_srp[i].pgc);
- }
- free(pgcit->pgci_srp);
- }
-}
-
-void ifoFree_PGCIT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->vts_pgcit) {
- ifoFree_PGCIT_internal(ifofile->vts_pgcit);
- free(ifofile->vts_pgcit);
- ifofile->vts_pgcit = 0;
- }
-}
-
-
-int ifoRead_PGCI_UT(ifo_handle_t *ifofile) {
- pgci_ut_t *pgci_ut;
- unsigned int sector;
- unsigned int i;
- int info_length;
- uint8_t *data, *ptr;
-
- if(!ifofile)
- return 0;
-
- if(ifofile->vmgi_mat) {
- if(ifofile->vmgi_mat->vmgm_pgci_ut == 0)
- return 1;
- sector = ifofile->vmgi_mat->vmgm_pgci_ut;
- } else if(ifofile->vtsi_mat) {
- if(ifofile->vtsi_mat->vtsm_pgci_ut == 0)
- return 1;
- sector = ifofile->vtsi_mat->vtsm_pgci_ut;
- } else {
- return 0;
- }
-
- ifofile->pgci_ut = (pgci_ut_t *)malloc(sizeof(pgci_ut_t));
- if(!ifofile->pgci_ut)
- return 0;
-
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN)) {
- free(ifofile->pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
-
- if(!(DVDReadBytes(ifofile->file, ifofile->pgci_ut, PGCI_UT_SIZE))) {
- free(ifofile->pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
-
- pgci_ut = ifofile->pgci_ut;
-
- B2N_16(pgci_ut->nr_of_lus);
- B2N_32(pgci_ut->last_byte);
-
- CHECK_ZERO(pgci_ut->zero_1);
- CHECK_VALUE(pgci_ut->nr_of_lus != 0);
- CHECK_VALUE(pgci_ut->nr_of_lus < 100); /* ?? 3-4 ?*/
- CHECK_VALUE((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte);
-
- info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE;
- data = malloc(info_length);
- if(!data) {
- free(pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
- if(!(DVDReadBytes(ifofile->file, data, info_length))) {
- free(data);
- free(pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
-
- pgci_ut->lu = malloc(pgci_ut->nr_of_lus * sizeof(pgci_lu_t));
- if(!pgci_ut->lu) {
- free(data);
- free(pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
- ptr = data;
- for(i = 0; i < pgci_ut->nr_of_lus; i++) {
- memcpy(&pgci_ut->lu[i], ptr, PGCI_LU_SIZE);
- ptr += PGCI_LU_SIZE;
- B2N_16(pgci_ut->lu[i].lang_code);
- B2N_32(pgci_ut->lu[i].lang_start_byte);
- }
- free(data);
-
- for(i = 0; i < pgci_ut->nr_of_lus; i++) {
- /* Maybe this is only defined for v1.1 and later titles?
- If the bits in 'lu[i].exists' are enumerated abcd efgh then:
- VTS_x_yy.IFO VIDEO_TS.IFO
- a == 0x83 "Root" 0x82 "Title"
- b == 0x84 "Subpicture"
- c == 0x85 "Audio"
- d == 0x86 "Angle"
- e == 0x87 "PTT"
- */
- CHECK_VALUE((pgci_ut->lu[i].exists & 0x07) == 0);
- }
-
- for(i = 0; i < pgci_ut->nr_of_lus; i++) {
- pgci_ut->lu[i].pgcit = malloc(sizeof(pgcit_t));
- if(!pgci_ut->lu[i].pgcit) {
- unsigned int j;
- for(j = 0; j < i; j++) {
- ifoFree_PGCIT_internal(pgci_ut->lu[j].pgcit);
- free(pgci_ut->lu[j].pgcit);
- }
- free(pgci_ut->lu);
- free(pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
- if(!ifoRead_PGCIT_internal(ifofile, pgci_ut->lu[i].pgcit,
- sector * DVD_BLOCK_LEN
- + pgci_ut->lu[i].lang_start_byte)) {
- unsigned int j;
- for(j = 0; j < i; j++) {
- ifoFree_PGCIT_internal(pgci_ut->lu[j].pgcit);
- free(pgci_ut->lu[j].pgcit);
- }
- free(pgci_ut->lu[i].pgcit);
- free(pgci_ut->lu);
- free(pgci_ut);
- ifofile->pgci_ut = 0;
- return 0;
- }
- /* FIXME: Iterate and verify that all menus that should exists accordingly
- / to pgci_ut->lu[i].exists really do? */
- }
-
- return 1;
-}
-
-
-void ifoFree_PGCI_UT(ifo_handle_t *ifofile) {
- unsigned int i;
-
- if(!ifofile)
- return;
-
- if(ifofile->pgci_ut) {
- for(i = 0; i < ifofile->pgci_ut->nr_of_lus; i++) {
- ifoFree_PGCIT_internal(ifofile->pgci_ut->lu[i].pgcit);
- free(ifofile->pgci_ut->lu[i].pgcit);
- }
- free(ifofile->pgci_ut->lu);
- free(ifofile->pgci_ut);
- ifofile->pgci_ut = 0;
- }
-}
-
-static int ifoRead_VTS_ATTRIBUTES(ifo_handle_t *ifofile,
- vts_attributes_t *vts_attributes,
- unsigned int offset) {
- unsigned int i;
-
- if(!DVDFileSeek_(ifofile->file, offset))
- return 0;
-
- if(!(DVDReadBytes(ifofile->file, vts_attributes, sizeof(vts_attributes_t))))
- return 0;
-
- B2N_32(vts_attributes->last_byte);
- B2N_32(vts_attributes->vts_cat);
- B2N_16(vts_attributes->vtsm_audio_attr.lang_code);
- B2N_16(vts_attributes->vtsm_subp_attr.lang_code);
- for(i = 0; i < 8; i++)
- B2N_16(vts_attributes->vtstt_audio_attr[i].lang_code);
- for(i = 0; i < 32; i++)
- B2N_16(vts_attributes->vtstt_subp_attr[i].lang_code);
-
- CHECK_ZERO(vts_attributes->zero_1);
- CHECK_ZERO(vts_attributes->zero_2);
- CHECK_ZERO(vts_attributes->zero_3);
- CHECK_ZERO(vts_attributes->zero_4);
- CHECK_ZERO(vts_attributes->zero_5);
- CHECK_ZERO(vts_attributes->zero_6);
- CHECK_ZERO(vts_attributes->zero_7);
- CHECK_VALUE(vts_attributes->nr_of_vtsm_audio_streams <= 1);
- CHECK_VALUE(vts_attributes->nr_of_vtsm_subp_streams <= 1);
- CHECK_VALUE(vts_attributes->nr_of_vtstt_audio_streams <= 8);
- for(i = vts_attributes->nr_of_vtstt_audio_streams; i < 8; i++)
- CHECK_ZERO(vts_attributes->vtstt_audio_attr[i]);
- CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= 32);
- {
- unsigned int nr_coded;
- CHECK_VALUE(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE);
- nr_coded = (vts_attributes->last_byte + 1 - VTS_ATTRIBUTES_MIN_SIZE)/6;
- /* This is often nr_coded = 70, how do you know how many there really are?*/
- if(nr_coded > 32) { /* We haven't read more from disk/file anyway*/
- nr_coded = 32;
- }
- CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded);
- for(i = vts_attributes->nr_of_vtstt_subp_streams; i < nr_coded; i++)
- CHECK_ZERO(vts_attributes->vtstt_subp_attr[i]);
- }
-
- return 1;
-}
-
-
-
-int ifoRead_VTS_ATRT(ifo_handle_t *ifofile) {
- vts_atrt_t *vts_atrt;
- unsigned int i, info_length, sector;
- uint32_t *data;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vmgi_mat)
- return 0;
-
- if(ifofile->vmgi_mat->vts_atrt == 0) /* mandatory */
- return 0;
-
- sector = ifofile->vmgi_mat->vts_atrt;
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
- return 0;
-
- vts_atrt = (vts_atrt_t *)malloc(sizeof(vts_atrt_t));
- if(!vts_atrt)
- return 0;
-
- ifofile->vts_atrt = vts_atrt;
-
- if(!(DVDReadBytes(ifofile->file, vts_atrt, VTS_ATRT_SIZE))) {
- free(vts_atrt);
- ifofile->vts_atrt = 0;
- return 0;
- }
-
- B2N_16(vts_atrt->nr_of_vtss);
- B2N_32(vts_atrt->last_byte);
-
- CHECK_ZERO(vts_atrt->zero_1);
- CHECK_VALUE(vts_atrt->nr_of_vtss != 0);
- CHECK_VALUE(vts_atrt->nr_of_vtss < 100); /*??*/
- CHECK_VALUE((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) +
- VTS_ATRT_SIZE < vts_atrt->last_byte + 1);
-
- info_length = vts_atrt->nr_of_vtss * sizeof(uint32_t);
- data = (uint32_t *)malloc(info_length);
- if(!data) {
- free(vts_atrt);
- ifofile->vts_atrt = 0;
- return 0;
- }
-
- vts_atrt->vts_atrt_offsets = data;
-
- if(!(DVDReadBytes(ifofile->file, data, info_length))) {
- free(data);
- free(vts_atrt);
- ifofile->vts_atrt = 0;
- return 0;
- }
-
- for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
- B2N_32(data[i]);
- CHECK_VALUE(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1);
- }
-
- info_length = vts_atrt->nr_of_vtss * sizeof(vts_attributes_t);
- vts_atrt->vts = (vts_attributes_t *)malloc(info_length);
- if(!vts_atrt->vts) {
- free(data);
- free(vts_atrt);
- ifofile->vts_atrt = 0;
- return 0;
- }
- for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
- unsigned int offset = data[i];
- if(!ifoRead_VTS_ATTRIBUTES(ifofile, &(vts_atrt->vts[i]),
- (sector * DVD_BLOCK_LEN) + offset)) {
- free(data);
- free(vts_atrt);
- ifofile->vts_atrt = 0;
- return 0;
- }
-
- /* This assert cant be in ifoRead_VTS_ATTRIBUTES*/
- CHECK_VALUE(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1);
- /* Is this check correct?*/
- }
-
- return 1;
-}
-
-
-void ifoFree_VTS_ATRT(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->vts_atrt) {
- free(ifofile->vts_atrt->vts);
- free(ifofile->vts_atrt->vts_atrt_offsets);
- free(ifofile->vts_atrt);
- ifofile->vts_atrt = 0;
- }
-}
-
-
-int ifoRead_TXTDT_MGI(ifo_handle_t *ifofile) {
- txtdt_mgi_t *txtdt_mgi;
-
- if(!ifofile)
- return 0;
-
- if(!ifofile->vmgi_mat)
- return 0;
-
- /* Return successfully if there is nothing to read. */
- if(ifofile->vmgi_mat->txtdt_mgi == 0)
- return 1;
-
- if(!DVDFileSeek_(ifofile->file,
- ifofile->vmgi_mat->txtdt_mgi * DVD_BLOCK_LEN))
- return 0;
-
- txtdt_mgi = (txtdt_mgi_t *)malloc(sizeof(txtdt_mgi_t));
- if(!txtdt_mgi) {
- return 0;
- }
- ifofile->txtdt_mgi = txtdt_mgi;
-
- if(!(DVDReadBytes(ifofile->file, txtdt_mgi, TXTDT_MGI_SIZE))) {
- if(dvdread_verbose(device_of_file(ifofile->file)) >= 1) {
- fprintf(stderr, "libdvdread: Unable to read TXTDT_MGI.\n");
- }
- free(txtdt_mgi);
- ifofile->txtdt_mgi = 0;
- return 0;
- }
-
- /* fprintf(stderr, "-- Not done yet --\n");*/
- return 1;
-}
-
-void ifoFree_TXTDT_MGI(ifo_handle_t *ifofile) {
- if(!ifofile)
- return;
-
- if(ifofile->txtdt_mgi) {
- free(ifofile->txtdt_mgi);
- ifofile->txtdt_mgi = 0;
- }
-}
-
diff --git a/dvdread/ifo_read.h b/dvdread/ifo_read.h
deleted file mode 100644
index fb01983..0000000
--- a/dvdread/ifo_read.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef IFO_READ_H_INCLUDED
-#define IFO_READ_H_INCLUDED
-
-/*
- * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "ifo_types.h"
-#include "dvd_reader.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * handle = ifoOpen(dvd, title);
- *
- * Opens an IFO and reads in all the data for the IFO file corresponding to the
- * given title. If title 0 is given, the video manager IFO file is read.
- * Returns a handle to a completely parsed structure.
- */
-ifo_handle_t *ifoOpen(dvd_reader_t *, int );
-
-/**
- * handle = ifoOpenVMGI(dvd);
- *
- * Opens an IFO and reads in _only_ the vmgi_mat data. This call can be used
- * together with the calls below to read in each segment of the IFO file on
- * demand.
- */
-ifo_handle_t *ifoOpenVMGI(dvd_reader_t *);
-
-/**
- * handle = ifoOpenVTSI(dvd, title);
- *
- * Opens an IFO and reads in _only_ the vtsi_mat data. This call can be used
- * together with the calls below to read in each segment of the IFO file on
- * demand.
- */
-ifo_handle_t *ifoOpenVTSI(dvd_reader_t *, int);
-
-/**
- * ifoClose(ifofile);
- * Cleans up the IFO information. This will free all data allocated for the
- * substructures.
- */
-void ifoClose(ifo_handle_t *);
-
-/**
- * The following functions are for reading only part of the VMGI/VTSI files.
- * Returns 1 if the data was successfully read and 0 on error.
- */
-
-/**
- * okay = ifoRead_PLT_MAIT(ifofile);
- *
- * Read in the Parental Management Information table, filling the
- * ifofile->ptl_mait structure and its substructures. This data is only
- * located in the video manager information file. This fills the
- * ifofile->ptl_mait structure and all its substructures.
- */
-int ifoRead_PTL_MAIT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_VTS_ATRT(ifofile);
- *
- * Read in the attribute table for the main menu vob, filling the
- * ifofile->vts_atrt structure and its substructures. Only located in the
- * video manager information file. This fills in the ifofile->vts_atrt
- * structure and all its substructures.
- */
-int ifoRead_VTS_ATRT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_TT_SRPT(ifofile);
- *
- * Reads the title info for the main menu, filling the ifofile->tt_srpt
- * structure and its substructures. This data is only located in the video
- * manager information file. This structure is mandatory in the IFO file.
- */
-int ifoRead_TT_SRPT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_VTS_PTT_SRPT(ifofile);
- *
- * Reads in the part of title search pointer table, filling the
- * ifofile->vts_ptt_srpt structure and its substructures. This data is only
- * located in the video title set information file. This structure is
- * mandatory, and must be included in the VTSI file.
- */
-int ifoRead_VTS_PTT_SRPT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_FP_PGC(ifofile);
- *
- * Reads in the first play program chain data, filling the
- * ifofile->first_play_pgc structure. This data is only located in the video
- * manager information file (VMGI). This structure is optional.
- */
-int ifoRead_FP_PGC(ifo_handle_t *);
-
-/**
- * okay = ifoRead_PGCIT(ifofile);
- *
- * Reads in the program chain information table for the video title set. Fills
- * in the ifofile->vts_pgcit structure and its substructures, which includes
- * the data for each program chain in the set. This data is only located in
- * the video title set information file. This structure is mandatory, and must
- * be included in the VTSI file.
- */
-int ifoRead_PGCIT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_PGCI_UT(ifofile);
- *
- * Reads in the menu PGCI unit table for the menu VOB. For the video manager,
- * this corresponds to the VIDEO_TS.VOB file, and for each title set, this
- * corresponds to the VTS_XX_0.VOB file. This data is located in both the
- * video manager and video title set information files. For VMGI files, this
- * fills the ifofile->vmgi_pgci_ut structure and all its substructures. For
- * VTSI files, this fills the ifofile->vtsm_pgci_ut structure.
- */
-int ifoRead_PGCI_UT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_VTS_TMAPT(ifofile);
- *
- * Reads in the VTS Time Map Table, this data is only located in the video
- * title set information file. This fills the ifofile->vts_tmapt structure
- * and all its substructures. When pressent enables VOBU level time-based
- * seeking for One_Sequential_PGC_Titles.
- */
-int ifoRead_VTS_TMAPT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_C_ADT(ifofile);
- *
- * Reads in the cell address table for the menu VOB. For the video manager,
- * this corresponds to the VIDEO_TS.VOB file, and for each title set, this
- * corresponds to the VTS_XX_0.VOB file. This data is located in both the
- * video manager and video title set information files. For VMGI files, this
- * fills the ifofile->vmgm_c_adt structure and all its substructures. For VTSI
- * files, this fills the ifofile->vtsm_c_adt structure.
- */
-int ifoRead_C_ADT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_TITLE_C_ADT(ifofile);
- *
- * Reads in the cell address table for the video title set corresponding to
- * this IFO file. This data is only located in the video title set information
- * file. This structure is mandatory, and must be included in the VTSI file.
- * This call fills the ifofile->vts_c_adt structure and its substructures.
- */
-int ifoRead_TITLE_C_ADT(ifo_handle_t *);
-
-/**
- * okay = ifoRead_VOBU_ADMAP(ifofile);
- *
- * Reads in the VOBU address map for the menu VOB. For the video manager, this
- * corresponds to the VIDEO_TS.VOB file, and for each title set, this
- * corresponds to the VTS_XX_0.VOB file. This data is located in both the
- * video manager and video title set information files. For VMGI files, this
- * fills the ifofile->vmgm_vobu_admap structure and all its substructures. For
- * VTSI files, this fills the ifofile->vtsm_vobu_admap structure.
- */
-int ifoRead_VOBU_ADMAP(ifo_handle_t *);
-
-/**
- * okay = ifoRead_TITLE_VOBU_ADMAP(ifofile);
- *
- * Reads in the VOBU address map for the associated video title set. This data
- * is only located in the video title set information file. This structure is
- * mandatory, and must be included in the VTSI file. Fills the
- * ifofile->vts_vobu_admap structure and its substructures.
- */
-int ifoRead_TITLE_VOBU_ADMAP(ifo_handle_t *);
-
-/**
- * okay = ifoRead_TXTDT_MGI(ifofile);
- *
- * Reads in the text data strings for the DVD. Fills the ifofile->txtdt_mgi
- * structure and all its substructures. This data is only located in the video
- * manager information file. This structure is mandatory, and must be included
- * in the VMGI file.
- */
-int ifoRead_TXTDT_MGI(ifo_handle_t *);
-
-/**
- * The following functions are used for freeing parsed sections of the
- * ifo_handle_t structure and the allocated substructures. The free calls
- * below are safe: they will not mind if you attempt to free part of an IFO
- * file which was not read in or which does not exist.
- */
-void ifoFree_PTL_MAIT(ifo_handle_t *);
-void ifoFree_VTS_ATRT(ifo_handle_t *);
-void ifoFree_TT_SRPT(ifo_handle_t *);
-void ifoFree_VTS_PTT_SRPT(ifo_handle_t *);
-void ifoFree_FP_PGC(ifo_handle_t *);
-void ifoFree_PGCIT(ifo_handle_t *);
-void ifoFree_PGCI_UT(ifo_handle_t *);
-void ifoFree_VTS_TMAPT(ifo_handle_t *);
-void ifoFree_C_ADT(ifo_handle_t *);
-void ifoFree_TITLE_C_ADT(ifo_handle_t *);
-void ifoFree_VOBU_ADMAP(ifo_handle_t *);
-void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *);
-void ifoFree_TXTDT_MGI(ifo_handle_t *);
-
-#ifdef __cplusplus
-};
-#endif
-#endif /* IFO_READ_H_INCLUDED */
diff --git a/dvdread/ifo_types.h b/dvdread/ifo_types.h
deleted file mode 100644
index 0bf601c..0000000
--- a/dvdread/ifo_types.h
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef IFO_TYPES_H_INCLUDED
-#define IFO_TYPES_H_INCLUDED
-
-/*
- * Copyright (C) 2000, 2001 Björn Englund <d4bjorn@dtek.chalmers.se>,
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "dvd_reader.h"
-
-#if defined(__BEOS__)
-#if !defined(_INTTYPES_H_) && !defined(_INTTYPES_H) && !defined(_STDINT_H_) && !defined(_STDINT_H)
-#error "Must include <inttypes.h> or <stdint.h> before any libdvdread header."
-#endif
-#else
-#if !defined(UINT8_MAX) || !defined(UINT16_MAX) || !defined(INT32_MAX)
-#error "Must include <inttypes.h> or <stdint.h> before any libdvdread header."
-#endif
-#endif
-
-#undef ATTRIBUTE_PACKED
-#undef PRAGMA_PACK_BEGIN
-#undef PRAGMA_PACK_END
-
-#if defined(__GNUC__)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
-#define ATTRIBUTE_PACKED __attribute__ ((packed))
-#define PRAGMA_PACK 0
-#endif
-#endif
-
-#if !defined(ATTRIBUTE_PACKED)
-#define ATTRIBUTE_PACKED
-#define PRAGMA_PACK 1
-#endif
-
-#if PRAGMA_PACK
-#pragma pack(1)
-#endif
-
-
-/**
- * Common
- *
- * The following structures are used in both the VMGI and VTSI.
- */
-
-
-/**
- * DVD Time Information.
- */
-typedef struct {
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- uint8_t frame_u; /* The two high bits are the frame rate. */
-} ATTRIBUTE_PACKED dvd_time_t;
-
-/**
- * Type to store per-command data.
- */
-typedef struct {
- uint8_t bytes[8];
-} ATTRIBUTE_PACKED vm_cmd_t;
-#define COMMAND_DATA_SIZE 8U
-
-
-/**
- * Video Attributes.
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int mpeg_version : 2;
- unsigned int video_format : 2;
- unsigned int display_aspect_ratio : 2;
- unsigned int permitted_df : 2;
-
- unsigned int line21_cc_1 : 1;
- unsigned int line21_cc_2 : 1;
- unsigned int unknown1 : 1;
- unsigned int bit_rate : 1;
-
- unsigned int picture_size : 2;
- unsigned int letterboxed : 1;
- unsigned int film_mode : 1;
-#else
- unsigned int permitted_df : 2;
- unsigned int display_aspect_ratio : 2;
- unsigned int video_format : 2;
- unsigned int mpeg_version : 2;
-
- unsigned int film_mode : 1;
- unsigned int letterboxed : 1;
- unsigned int picture_size : 2;
-
- unsigned int bit_rate : 1;
- unsigned int unknown1 : 1;
- unsigned int line21_cc_2 : 1;
- unsigned int line21_cc_1 : 1;
-#endif
-} ATTRIBUTE_PACKED video_attr_t;
-
-/**
- * Audio Attributes.
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int audio_format : 3;
- unsigned int multichannel_extension : 1;
- unsigned int lang_type : 2;
- unsigned int application_mode : 2;
-
- unsigned int quantization : 2;
- unsigned int sample_frequency : 2;
- unsigned int unknown1 : 1;
- unsigned int channels : 3;
-#else
- unsigned int application_mode : 2;
- unsigned int lang_type : 2;
- unsigned int multichannel_extension : 1;
- unsigned int audio_format : 3;
-
- unsigned int channels : 3;
- unsigned int unknown1 : 1;
- unsigned int sample_frequency : 2;
- unsigned int quantization : 2;
-#endif
- uint16_t lang_code;
- uint8_t lang_extension;
- uint8_t code_extension;
- uint8_t unknown3;
- union {
- struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int unknown4 : 1;
- unsigned int channel_assignment : 3;
- unsigned int version : 2;
- unsigned int mc_intro : 1; /* probably 0: true, 1:false */
- unsigned int mode : 1; /* Karaoke mode 0: solo 1: duet */
-#else
- unsigned int mode : 1;
- unsigned int mc_intro : 1;
- unsigned int version : 2;
- unsigned int channel_assignment : 3;
- unsigned int unknown4 : 1;
-#endif
- } ATTRIBUTE_PACKED karaoke;
- struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int unknown5 : 4;
- unsigned int dolby_encoded : 1; /* suitable for surround decoding */
- unsigned int unknown6 : 3;
-#else
- unsigned int unknown6 : 3;
- unsigned int dolby_encoded : 1;
- unsigned int unknown5 : 4;
-#endif
- } ATTRIBUTE_PACKED surround;
- } ATTRIBUTE_PACKED app_info;
-} ATTRIBUTE_PACKED audio_attr_t;
-
-
-/**
- * MultiChannel Extension
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int zero1 : 7;
- unsigned int ach0_gme : 1;
-
- unsigned int zero2 : 7;
- unsigned int ach1_gme : 1;
-
- unsigned int zero3 : 4;
- unsigned int ach2_gv1e : 1;
- unsigned int ach2_gv2e : 1;
- unsigned int ach2_gm1e : 1;
- unsigned int ach2_gm2e : 1;
-
- unsigned int zero4 : 4;
- unsigned int ach3_gv1e : 1;
- unsigned int ach3_gv2e : 1;
- unsigned int ach3_gmAe : 1;
- unsigned int ach3_se2e : 1;
-
- unsigned int zero5 : 4;
- unsigned int ach4_gv1e : 1;
- unsigned int ach4_gv2e : 1;
- unsigned int ach4_gmBe : 1;
- unsigned int ach4_seBe : 1;
-#else
- unsigned int ach0_gme : 1;
- unsigned int zero1 : 7;
-
- unsigned int ach1_gme : 1;
- unsigned int zero2 : 7;
-
- unsigned int ach2_gm2e : 1;
- unsigned int ach2_gm1e : 1;
- unsigned int ach2_gv2e : 1;
- unsigned int ach2_gv1e : 1;
- unsigned int zero3 : 4;
-
- unsigned int ach3_se2e : 1;
- unsigned int ach3_gmAe : 1;
- unsigned int ach3_gv2e : 1;
- unsigned int ach3_gv1e : 1;
- unsigned int zero4 : 4;
-
- unsigned int ach4_seBe : 1;
- unsigned int ach4_gmBe : 1;
- unsigned int ach4_gv2e : 1;
- unsigned int ach4_gv1e : 1;
- unsigned int zero5 : 4;
-#endif
- uint8_t zero6[19];
-} ATTRIBUTE_PACKED multichannel_ext_t;
-
-
-/**
- * Subpicture Attributes.
- */
-typedef struct {
- /*
- * type: 0 not specified
- * 1 language
- * 2 other
- * coding mode: 0 run length
- * 1 extended
- * 2 other
- * language: indicates language if type == 1
- * lang extension: if type == 1 contains the lang extension
- */
-#ifdef WORDS_BIGENDIAN
- unsigned int code_mode : 3;
- unsigned int zero1 : 3;
- unsigned int type : 2;
-#else
- unsigned int type : 2;
- unsigned int zero1 : 3;
- unsigned int code_mode : 3;
-#endif
- uint8_t zero2;
- uint16_t lang_code;
- uint8_t lang_extension;
- uint8_t code_extension;
-} ATTRIBUTE_PACKED subp_attr_t;
-
-
-
-/**
- * PGC Command Table.
- */
-typedef struct {
- uint16_t nr_of_pre;
- uint16_t nr_of_post;
- uint16_t nr_of_cell;
- uint16_t last_byte;
- vm_cmd_t *pre_cmds;
- vm_cmd_t *post_cmds;
- vm_cmd_t *cell_cmds;
-} ATTRIBUTE_PACKED pgc_command_tbl_t;
-#define PGC_COMMAND_TBL_SIZE 8U
-
-/**
- * PGC Program Map
- */
-typedef uint8_t pgc_program_map_t;
-
-/**
- * Cell Playback Information.
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int block_mode : 2;
- unsigned int block_type : 2;
- unsigned int seamless_play : 1;
- unsigned int interleaved : 1;
- unsigned int stc_discontinuity: 1;
- unsigned int seamless_angle : 1;
-
- unsigned int playback_mode : 1; /**< When set, enter StillMode after each VOBU */
- unsigned int restricted : 1; /**< ?? drop out of fastforward? */
- unsigned int unknown2 : 6;
-#else
- unsigned int seamless_angle : 1;
- unsigned int stc_discontinuity: 1;
- unsigned int interleaved : 1;
- unsigned int seamless_play : 1;
- unsigned int block_type : 2;
- unsigned int block_mode : 2;
-
- unsigned int unknown2 : 6;
- unsigned int restricted : 1;
- unsigned int playback_mode : 1;
-#endif
- uint8_t still_time;
- uint8_t cell_cmd_nr;
- dvd_time_t playback_time;
- uint32_t first_sector;
- uint32_t first_ilvu_end_sector;
- uint32_t last_vobu_start_sector;
- uint32_t last_sector;
-} ATTRIBUTE_PACKED cell_playback_t;
-
-#define BLOCK_TYPE_NONE 0x0
-#define BLOCK_TYPE_ANGLE_BLOCK 0x1
-
-#define BLOCK_MODE_NOT_IN_BLOCK 0x0
-#define BLOCK_MODE_FIRST_CELL 0x1
-#define BLOCK_MODE_IN_BLOCK 0x2
-#define BLOCK_MODE_LAST_CELL 0x3
-
-/**
- * Cell Position Information.
- */
-typedef struct {
- uint16_t vob_id_nr;
- uint8_t zero_1;
- uint8_t cell_nr;
-} ATTRIBUTE_PACKED cell_position_t;
-
-/**
- * User Operations.
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int zero : 7; /* 25-31 */
- unsigned int video_pres_mode_change : 1; /* 24 */
-
- unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */
- unsigned int angle_change : 1;
- unsigned int subpic_stream_change : 1;
- unsigned int audio_stream_change : 1;
- unsigned int pause_on : 1;
- unsigned int still_off : 1;
- unsigned int button_select_or_activate : 1;
- unsigned int resume : 1; /* 16 */
-
- unsigned int chapter_menu_call : 1; /* 15 */
- unsigned int angle_menu_call : 1;
- unsigned int audio_menu_call : 1;
- unsigned int subpic_menu_call : 1;
- unsigned int root_menu_call : 1;
- unsigned int title_menu_call : 1;
- unsigned int backward_scan : 1;
- unsigned int forward_scan : 1; /* 8 */
-
- unsigned int next_pg_search : 1; /* 7 */
- unsigned int prev_or_top_pg_search : 1;
- unsigned int time_or_chapter_search : 1;
- unsigned int go_up : 1;
- unsigned int stop : 1;
- unsigned int title_play : 1;
- unsigned int chapter_search_or_play : 1;
- unsigned int title_or_time_play : 1; /* 0 */
-#else
- unsigned int video_pres_mode_change : 1; /* 24 */
- unsigned int zero : 7; /* 25-31 */
-
- unsigned int resume : 1; /* 16 */
- unsigned int button_select_or_activate : 1;
- unsigned int still_off : 1;
- unsigned int pause_on : 1;
- unsigned int audio_stream_change : 1;
- unsigned int subpic_stream_change : 1;
- unsigned int angle_change : 1;
- unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */
-
- unsigned int forward_scan : 1; /* 8 */
- unsigned int backward_scan : 1;
- unsigned int title_menu_call : 1;
- unsigned int root_menu_call : 1;
- unsigned int subpic_menu_call : 1;
- unsigned int audio_menu_call : 1;
- unsigned int angle_menu_call : 1;
- unsigned int chapter_menu_call : 1; /* 15 */
-
- unsigned int title_or_time_play : 1; /* 0 */
- unsigned int chapter_search_or_play : 1;
- unsigned int title_play : 1;
- unsigned int stop : 1;
- unsigned int go_up : 1;
- unsigned int time_or_chapter_search : 1;
- unsigned int prev_or_top_pg_search : 1;
- unsigned int next_pg_search : 1; /* 7 */
-#endif
-} ATTRIBUTE_PACKED user_ops_t;
-
-/**
- * Program Chain Information.
- */
-typedef struct {
- uint16_t zero_1;
- uint8_t nr_of_programs;
- uint8_t nr_of_cells;
- dvd_time_t playback_time;
- user_ops_t prohibited_ops;
- uint16_t audio_control[8]; /* New type? */
- uint32_t subp_control[32]; /* New type? */
- uint16_t next_pgc_nr;
- uint16_t prev_pgc_nr;
- uint16_t goup_pgc_nr;
- uint8_t pg_playback_mode;
- uint8_t still_time;
- uint32_t palette[16]; /* New type struct {zero_1, Y, Cr, Cb} ? */
- uint16_t command_tbl_offset;
- uint16_t program_map_offset;
- uint16_t cell_playback_offset;
- uint16_t cell_position_offset;
- pgc_command_tbl_t *command_tbl;
- pgc_program_map_t *program_map;
- cell_playback_t *cell_playback;
- cell_position_t *cell_position;
-} ATTRIBUTE_PACKED pgc_t;
-#define PGC_SIZE 236U
-
-/**
- * Program Chain Information Search Pointer.
- */
-typedef struct {
- uint8_t entry_id;
-#ifdef WORDS_BIGENDIAN
- unsigned int block_mode : 2;
- unsigned int block_type : 2;
- unsigned int unknown1 : 4;
-#else
- unsigned int unknown1 : 4;
- unsigned int block_type : 2;
- unsigned int block_mode : 2;
-#endif
- uint16_t ptl_id_mask;
- uint32_t pgc_start_byte;
- pgc_t *pgc;
-} ATTRIBUTE_PACKED pgci_srp_t;
-#define PGCI_SRP_SIZE 8U
-
-/**
- * Program Chain Information Table.
- */
-typedef struct {
- uint16_t nr_of_pgci_srp;
- uint16_t zero_1;
- uint32_t last_byte;
- pgci_srp_t *pgci_srp;
-} ATTRIBUTE_PACKED pgcit_t;
-#define PGCIT_SIZE 8U
-
-/**
- * Menu PGCI Language Unit.
- */
-typedef struct {
- uint16_t lang_code;
- uint8_t lang_extension;
- uint8_t exists;
- uint32_t lang_start_byte;
- pgcit_t *pgcit;
-} ATTRIBUTE_PACKED pgci_lu_t;
-#define PGCI_LU_SIZE 8U
-
-/**
- * Menu PGCI Unit Table.
- */
-typedef struct {
- uint16_t nr_of_lus;
- uint16_t zero_1;
- uint32_t last_byte;
- pgci_lu_t *lu;
-} ATTRIBUTE_PACKED pgci_ut_t;
-#define PGCI_UT_SIZE 8U
-
-/**
- * Cell Address Information.
- */
-typedef struct {
- uint16_t vob_id;
- uint8_t cell_id;
- uint8_t zero_1;
- uint32_t start_sector;
- uint32_t last_sector;
-} ATTRIBUTE_PACKED cell_adr_t;
-
-/**
- * Cell Address Table.
- */
-typedef struct {
- uint16_t nr_of_vobs; /* VOBs */
- uint16_t zero_1;
- uint32_t last_byte;
- cell_adr_t *cell_adr_table; /* No explicit size given. */
-} ATTRIBUTE_PACKED c_adt_t;
-#define C_ADT_SIZE 8U
-
-/**
- * VOBU Address Map.
- */
-typedef struct {
- uint32_t last_byte;
- uint32_t *vobu_start_sectors;
-} ATTRIBUTE_PACKED vobu_admap_t;
-#define VOBU_ADMAP_SIZE 4U
-
-
-
-
-/**
- * VMGI
- *
- * The following structures relate to the Video Manager.
- */
-
-/**
- * Video Manager Information Management Table.
- */
-typedef struct {
- char vmg_identifier[12];
- uint32_t vmg_last_sector;
- uint8_t zero_1[12];
- uint32_t vmgi_last_sector;
- uint8_t zero_2;
- uint8_t specification_version;
- uint32_t vmg_category;
- uint16_t vmg_nr_of_volumes;
- uint16_t vmg_this_volume_nr;
- uint8_t disc_side;
- uint8_t zero_3[19];
- uint16_t vmg_nr_of_title_sets; /* Number of VTSs. */
- char provider_identifier[32];
- uint64_t vmg_pos_code;
- uint8_t zero_4[24];
- uint32_t vmgi_last_byte;
- uint32_t first_play_pgc;
- uint8_t zero_5[56];
- uint32_t vmgm_vobs; /* sector */
- uint32_t tt_srpt; /* sector */
- uint32_t vmgm_pgci_ut; /* sector */
- uint32_t ptl_mait; /* sector */
- uint32_t vts_atrt; /* sector */
- uint32_t txtdt_mgi; /* sector */
- uint32_t vmgm_c_adt; /* sector */
- uint32_t vmgm_vobu_admap; /* sector */
- uint8_t zero_6[32];
-
- video_attr_t vmgm_video_attr;
- uint8_t zero_7;
- uint8_t nr_of_vmgm_audio_streams; /* should be 0 or 1 */
- audio_attr_t vmgm_audio_attr;
- audio_attr_t zero_8[7];
- uint8_t zero_9[17];
- uint8_t nr_of_vmgm_subp_streams; /* should be 0 or 1 */
- subp_attr_t vmgm_subp_attr;
- subp_attr_t zero_10[27]; /* XXX: how much 'padding' here? */
-} ATTRIBUTE_PACKED vmgi_mat_t;
-
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int zero_1 : 1;
- unsigned int multi_or_random_pgc_title : 1; /* 0: one sequential pgc title */
- unsigned int jlc_exists_in_cell_cmd : 1;
- unsigned int jlc_exists_in_prepost_cmd : 1;
- unsigned int jlc_exists_in_button_cmd : 1;
- unsigned int jlc_exists_in_tt_dom : 1;
- unsigned int chapter_search_or_play : 1; /* UOP 1 */
- unsigned int title_or_time_play : 1; /* UOP 0 */
-#else
- unsigned int title_or_time_play : 1;
- unsigned int chapter_search_or_play : 1;
- unsigned int jlc_exists_in_tt_dom : 1;
- unsigned int jlc_exists_in_button_cmd : 1;
- unsigned int jlc_exists_in_prepost_cmd : 1;
- unsigned int jlc_exists_in_cell_cmd : 1;
- unsigned int multi_or_random_pgc_title : 1;
- unsigned int zero_1 : 1;
-#endif
-} ATTRIBUTE_PACKED playback_type_t;
-
-/**
- * Title Information.
- */
-typedef struct {
- playback_type_t pb_ty;
- uint8_t nr_of_angles;
- uint16_t nr_of_ptts;
- uint16_t parental_id;
- uint8_t title_set_nr;
- uint8_t vts_ttn;
- uint32_t title_set_sector;
-} ATTRIBUTE_PACKED title_info_t;
-
-/**
- * PartOfTitle Search Pointer Table.
- */
-typedef struct {
- uint16_t nr_of_srpts;
- uint16_t zero_1;
- uint32_t last_byte;
- title_info_t *title;
-} ATTRIBUTE_PACKED tt_srpt_t;
-#define TT_SRPT_SIZE 8U
-
-
-/**
- * Parental Management Information Unit Table.
- * Level 1 (US: G), ..., 7 (US: NC-17), 8
- */
-typedef uint16_t pf_level_t[8];
-
-/**
- * Parental Management Information Unit Table.
- */
-typedef struct {
- uint16_t country_code;
- uint16_t zero_1;
- uint16_t pf_ptl_mai_start_byte;
- uint16_t zero_2;
- pf_level_t *pf_ptl_mai; /* table of (nr_of_vtss + 1), video_ts is first */
-} ATTRIBUTE_PACKED ptl_mait_country_t;
-#define PTL_MAIT_COUNTRY_SIZE 8U
-
-/**
- * Parental Management Information Table.
- */
-typedef struct {
- uint16_t nr_of_countries;
- uint16_t nr_of_vtss;
- uint32_t last_byte;
- ptl_mait_country_t *countries;
-} ATTRIBUTE_PACKED ptl_mait_t;
-#define PTL_MAIT_SIZE 8U
-
-/**
- * Video Title Set Attributes.
- */
-typedef struct {
- uint32_t last_byte;
- uint32_t vts_cat;
-
- video_attr_t vtsm_vobs_attr;
- uint8_t zero_1;
- uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */
- audio_attr_t vtsm_audio_attr;
- audio_attr_t zero_2[7];
- uint8_t zero_3[16];
- uint8_t zero_4;
- uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */
- subp_attr_t vtsm_subp_attr;
- subp_attr_t zero_5[27];
-
- uint8_t zero_6[2];
-
- video_attr_t vtstt_vobs_video_attr;
- uint8_t zero_7;
- uint8_t nr_of_vtstt_audio_streams;
- audio_attr_t vtstt_audio_attr[8];
- uint8_t zero_8[16];
- uint8_t zero_9;
- uint8_t nr_of_vtstt_subp_streams;
- subp_attr_t vtstt_subp_attr[32];
-} ATTRIBUTE_PACKED vts_attributes_t;
-#define VTS_ATTRIBUTES_SIZE 542U
-#define VTS_ATTRIBUTES_MIN_SIZE 356U
-
-/**
- * Video Title Set Attribute Table.
- */
-typedef struct {
- uint16_t nr_of_vtss;
- uint16_t zero_1;
- uint32_t last_byte;
- vts_attributes_t *vts;
- uint32_t *vts_atrt_offsets; /* offsets table for each vts_attributes */
-} ATTRIBUTE_PACKED vts_atrt_t;
-#define VTS_ATRT_SIZE 8U
-
-/**
- * Text Data. (Incomplete)
- */
-typedef struct {
- uint32_t last_byte; /* offsets are relative here */
- uint16_t offsets[100]; /* == nr_of_srpts + 1 (first is disc title) */
-#if 0
- uint16_t unknown; /* 0x48 ?? 0x48 words (16bit) info following */
- uint16_t zero_1;
-
- uint8_t type_of_info; /* ?? 01 == disc, 02 == Title, 04 == Title part */
- uint8_t unknown1;
- uint8_t unknown2;
- uint8_t unknown3;
- uint8_t unknown4; /* ?? allways 0x30 language?, text format? */
- uint8_t unknown5;
- uint16_t offset; /* from first */
-
- char text[12]; /* ended by 0x09 */
-#endif
-} ATTRIBUTE_PACKED txtdt_t;
-
-/**
- * Text Data Language Unit. (Incomplete)
- */
-typedef struct {
- uint16_t lang_code;
- uint16_t unknown; /* 0x0001, title 1? disc 1? side 1? */
- uint32_t txtdt_start_byte; /* prt, rel start of vmg_txtdt_mgi */
- txtdt_t *txtdt;
-} ATTRIBUTE_PACKED txtdt_lu_t;
-#define TXTDT_LU_SIZE 8U
-
-/**
- * Text Data Manager Information. (Incomplete)
- */
-typedef struct {
- char disc_name[14]; /* how many bytes?? */
- uint16_t nr_of_language_units; /* 32bit?? */
- uint32_t last_byte;
- txtdt_lu_t *lu;
-} ATTRIBUTE_PACKED txtdt_mgi_t;
-#define TXTDT_MGI_SIZE 20U
-
-
-/**
- * VTS
- *
- * Structures relating to the Video Title Set (VTS).
- */
-
-/**
- * Video Title Set Information Management Table.
- */
-typedef struct {
- char vts_identifier[12];
- uint32_t vts_last_sector;
- uint8_t zero_1[12];
- uint32_t vtsi_last_sector;
- uint8_t zero_2;
- uint8_t specification_version;
- uint32_t vts_category;
- uint16_t zero_3;
- uint16_t zero_4;
- uint8_t zero_5;
- uint8_t zero_6[19];
- uint16_t zero_7;
- uint8_t zero_8[32];
- uint64_t zero_9;
- uint8_t zero_10[24];
- uint32_t vtsi_last_byte;
- uint32_t zero_11;
- uint8_t zero_12[56];
- uint32_t vtsm_vobs; /* sector */
- uint32_t vtstt_vobs; /* sector */
- uint32_t vts_ptt_srpt; /* sector */
- uint32_t vts_pgcit; /* sector */
- uint32_t vtsm_pgci_ut; /* sector */
- uint32_t vts_tmapt; /* sector */
- uint32_t vtsm_c_adt; /* sector */
- uint32_t vtsm_vobu_admap; /* sector */
- uint32_t vts_c_adt; /* sector */
- uint32_t vts_vobu_admap; /* sector */
- uint8_t zero_13[24];
-
- video_attr_t vtsm_video_attr;
- uint8_t zero_14;
- uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */
- audio_attr_t vtsm_audio_attr;
- audio_attr_t zero_15[7];
- uint8_t zero_16[17];
- uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */
- subp_attr_t vtsm_subp_attr;
- subp_attr_t zero_17[27];
- uint8_t zero_18[2];
-
- video_attr_t vts_video_attr;
- uint8_t zero_19;
- uint8_t nr_of_vts_audio_streams;
- audio_attr_t vts_audio_attr[8];
- uint8_t zero_20[17];
- uint8_t nr_of_vts_subp_streams;
- subp_attr_t vts_subp_attr[32];
- uint16_t zero_21;
- multichannel_ext_t vts_mu_audio_attr[8];
- /* XXX: how much 'padding' here, if any? */
-} ATTRIBUTE_PACKED vtsi_mat_t;
-
-/**
- * PartOfTitle Unit Information.
- */
-typedef struct {
- uint16_t pgcn;
- uint16_t pgn;
-} ATTRIBUTE_PACKED ptt_info_t;
-
-/**
- * PartOfTitle Information.
- */
-typedef struct {
- uint16_t nr_of_ptts;
- ptt_info_t *ptt;
-} ATTRIBUTE_PACKED ttu_t;
-
-/**
- * PartOfTitle Search Pointer Table.
- */
-typedef struct {
- uint16_t nr_of_srpts;
- uint16_t zero_1;
- uint32_t last_byte;
- ttu_t *title;
- uint32_t *ttu_offset; /* offset table for each ttu */
-} ATTRIBUTE_PACKED vts_ptt_srpt_t;
-#define VTS_PTT_SRPT_SIZE 8U
-
-
-/**
- * Time Map Entry.
- */
-/* Should this be bit field at all or just the uint32_t? */
-typedef uint32_t map_ent_t;
-
-/**
- * Time Map.
- */
-typedef struct {
- uint8_t tmu; /* Time unit, in seconds */
- uint8_t zero_1;
- uint16_t nr_of_entries;
- map_ent_t *map_ent;
-} ATTRIBUTE_PACKED vts_tmap_t;
-#define VTS_TMAP_SIZE 4U
-
-/**
- * Time Map Table.
- */
-typedef struct {
- uint16_t nr_of_tmaps;
- uint16_t zero_1;
- uint32_t last_byte;
- vts_tmap_t *tmap;
- uint32_t *tmap_offset; /* offset table for each tmap */
-} ATTRIBUTE_PACKED vts_tmapt_t;
-#define VTS_TMAPT_SIZE 8U
-
-
-#if PRAGMA_PACK
-#pragma pack()
-#endif
-
-
-/**
- * The following structure defines an IFO file. The structure is divided into
- * two parts, the VMGI, or Video Manager Information, which is read from the
- * VIDEO_TS.[IFO,BUP] file, and the VTSI, or Video Title Set Information, which
- * is read in from the VTS_XX_0.[IFO,BUP] files.
- */
-typedef struct {
- dvd_file_t *file;
-
- /* VMGI */
- vmgi_mat_t *vmgi_mat;
- tt_srpt_t *tt_srpt;
- pgc_t *first_play_pgc;
- ptl_mait_t *ptl_mait;
- vts_atrt_t *vts_atrt;
- txtdt_mgi_t *txtdt_mgi;
-
- /* Common */
- pgci_ut_t *pgci_ut;
- c_adt_t *menu_c_adt;
- vobu_admap_t *menu_vobu_admap;
-
- /* VTSI */
- vtsi_mat_t *vtsi_mat;
- vts_ptt_srpt_t *vts_ptt_srpt;
- pgcit_t *vts_pgcit;
- vts_tmapt_t *vts_tmapt;
- c_adt_t *vts_c_adt;
- vobu_admap_t *vts_vobu_admap;
-} ifo_handle_t;
-
-#endif /* IFO_TYPES_H_INCLUDED */
diff --git a/dvdread/md5.c b/dvdread/md5.c
deleted file mode 100644
index 3e02b6b..0000000
--- a/dvdread/md5.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* md5.c - Functions to compute MD5 message digest of files or memory blocks
- according to the definition of MD5 in RFC 1321 from April 1992.
- Copyright (C) 1995, 1996, 2001 Free Software Foundation, Inc.
- NOTE: The canonical source of this file is maintained with the GNU C
- Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
- 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include "md5.h"
-
-#ifdef _LIBC
-# include <endian.h>
-# if __BYTE_ORDER == __BIG_ENDIAN
-# define WORDS_BIGENDIAN 1
-# endif
-#endif
-
-#ifdef WORDS_BIGENDIAN
-# define SWAP(n) \
- (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
-#else
-# define SWAP(n) (n)
-#endif
-
-
-/* This array contains the bytes used to pad the buffer to the next
- 64-byte boundary. (RFC 1321, 3.1: Step 1) */
-static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
-
-
-/* Initialize structure containing state of computation.
- (RFC 1321, 3.3: Step 3) */
-void
-md5_init_ctx (ctx)
- struct md5_ctx *ctx;
-{
- ctx->A = 0x67452301;
- ctx->B = 0xefcdab89;
- ctx->C = 0x98badcfe;
- ctx->D = 0x10325476;
-
- ctx->total[0] = ctx->total[1] = 0;
- ctx->buflen = 0;
-}
-
-/* Put result from CTX in first 16 bytes following RESBUF. The result
- must be in little endian byte order.
-
- IMPORTANT: On some systems it is required that RESBUF is correctly
- aligned for a 32 bits value. */
-void *
-md5_read_ctx (ctx, resbuf)
- const struct md5_ctx *ctx;
- void *resbuf;
-{
- ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
- ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
- ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
- ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
-
- return resbuf;
-}
-
-/* Process the remaining bytes in the internal buffer and the usual
- prolog according to the standard and write the result to RESBUF.
-
- IMPORTANT: On some systems it is required that RESBUF is correctly
- aligned for a 32 bits value. */
-void *
-md5_finish_ctx (ctx, resbuf)
- struct md5_ctx *ctx;
- void *resbuf;
-{
- /* Take yet unprocessed bytes into account. */
- md5_uint32 bytes = ctx->buflen;
- size_t pad;
-
- /* Now count remaining bytes. */
- ctx->total[0] += bytes;
- if (ctx->total[0] < bytes)
- ++ctx->total[1];
-
- pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
- memcpy (&ctx->buffer[bytes], fillbuf, pad);
-
- /* Put the 64-bit file length in *bits* at the end of the buffer. */
- *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
- *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
- (ctx->total[0] >> 29));
-
- /* Process last bytes. */
- md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
-
- return md5_read_ctx (ctx, resbuf);
-}
-
-/* Compute MD5 message digest for bytes read from STREAM. The
- resulting message digest number will be written into the 16 bytes
- beginning at RESBLOCK. */
-int
-md5_stream (stream, resblock)
- FILE *stream;
- void *resblock;
-{
- /* Important: BLOCKSIZE must be a multiple of 64. */
-#define BLOCKSIZE 4096
- struct md5_ctx ctx;
- char buffer[BLOCKSIZE + 72];
- size_t sum;
-
- /* Initialize the computation context. */
- md5_init_ctx (&ctx);
-
- /* Iterate over full file contents. */
- while (1)
- {
- /* We read the file in blocks of BLOCKSIZE bytes. One call of the
- computation function processes the whole buffer so that with the
- next round of the loop another block can be read. */
- size_t n;
- sum = 0;
-
- /* Read block. Take care for partial reads. */
- do
- {
- n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
- sum += n;
- }
- while (sum < BLOCKSIZE && n != 0);
- if (n == 0 && ferror (stream))
- return 1;
-
- /* If end of file is reached, end the loop. */
- if (n == 0)
- break;
-
- /* Process buffer with BLOCKSIZE bytes. Note that
- BLOCKSIZE % 64 == 0
- */
- md5_process_block (buffer, BLOCKSIZE, &ctx);
- }
-
- /* Add the last bytes if necessary. */
- if (sum > 0)
- md5_process_bytes (buffer, sum, &ctx);
-
- /* Construct result in desired memory. */
- md5_finish_ctx (&ctx, resblock);
- return 0;
-}
-
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
- result is always in little endian byte order, so that a byte-wise
- output yields to the wanted ASCII representation of the message
- digest. */
-void *
-md5_buffer (buffer, len, resblock)
- const char *buffer;
- size_t len;
- void *resblock;
-{
- struct md5_ctx ctx;
-
- /* Initialize the computation context. */
- md5_init_ctx (&ctx);
-
- /* Process whole buffer but last len % 64 bytes. */
- md5_process_bytes (buffer, len, &ctx);
-
- /* Put result in desired memory area. */
- return md5_finish_ctx (&ctx, resblock);
-}
-
-
-void
-md5_process_bytes (buffer, len, ctx)
- const void *buffer;
- size_t len;
- struct md5_ctx *ctx;
-{
- /* When we already have some bits in our internal buffer concatenate
- both inputs first. */
- if (ctx->buflen != 0)
- {
- size_t left_over = ctx->buflen;
- size_t add = 128 - left_over > len ? len : 128 - left_over;
-
- memcpy (&ctx->buffer[left_over], buffer, add);
- ctx->buflen += add;
-
- if (left_over + add > 64)
- {
- md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
- /* The regions in the following copy operation cannot overlap. */
- memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
- (left_over + add) & 63);
- ctx->buflen = (left_over + add) & 63;
- }
-
- buffer = (const char *) buffer + add;
- len -= add;
- }
-
- /* Process available complete blocks. */
- if (len > 64)
- {
- md5_process_block (buffer, len & ~63, ctx);
- buffer = (const char *) buffer + (len & ~63);
- len &= 63;
- }
-
- /* Move remaining bytes in internal buffer. */
- if (len > 0)
- {
- memcpy (ctx->buffer, buffer, len);
- ctx->buflen = len;
- }
-}
-
-
-/* These are the four functions used in the four steps of the MD5 algorithm
- and defined in the RFC 1321. The first function is a little bit optimized
- (as found in Colin Plumbs public domain implementation). */
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
-#define FG(b, c, d) FF (d, b, c)
-#define FH(b, c, d) (b ^ c ^ d)
-#define FI(b, c, d) (c ^ (b | ~d))
-
-/* Process LEN bytes of BUFFER, accumulating context into CTX.
- It is assumed that LEN % 64 == 0. */
-
-void
-md5_process_block (buffer, len, ctx)
- const void *buffer;
- size_t len;
- struct md5_ctx *ctx;
-{
- md5_uint32 correct_words[16];
- const md5_uint32 *words = buffer;
- size_t nwords = len / sizeof (md5_uint32);
- const md5_uint32 *endp = words + nwords;
- md5_uint32 A = ctx->A;
- md5_uint32 B = ctx->B;
- md5_uint32 C = ctx->C;
- md5_uint32 D = ctx->D;
-
- /* First increment the byte count. RFC 1321 specifies the possible
- length of the file up to 2^64 bits. Here we only compute the
- number of bytes. Do a double word increment. */
- ctx->total[0] += len;
- if (ctx->total[0] < len)
- ++ctx->total[1];
-
- /* Process all bytes in the buffer with 64 bytes in each round of
- the loop. */
- while (words < endp)
- {
- md5_uint32 *cwp = correct_words;
- md5_uint32 A_save = A;
- md5_uint32 B_save = B;
- md5_uint32 C_save = C;
- md5_uint32 D_save = D;
-
- /* First round: using the given function, the context and a constant
- the next context is computed. Because the algorithms processing
- unit is a 32-bit word and it is determined to work on words in
- little endian byte order we perhaps have to change the byte order
- before the computation. To reduce the work for the next steps
- we store the swapped words in the array CORRECT_WORDS. */
-
-#define OP(a, b, c, d, s, T) \
- do \
- { \
- a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
- ++words; \
- a = rol (a, s); \
- a += b; \
- } \
- while (0)
-
- /* Before we start, one word to the strange constants.
- They are defined in RFC 1321 as
-
- T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
- perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
- */
-
- /* Round 1. */
- OP (A, B, C, D, 7, 0xd76aa478);
- OP (D, A, B, C, 12, 0xe8c7b756);
- OP (C, D, A, B, 17, 0x242070db);
- OP (B, C, D, A, 22, 0xc1bdceee);
- OP (A, B, C, D, 7, 0xf57c0faf);
- OP (D, A, B, C, 12, 0x4787c62a);
- OP (C, D, A, B, 17, 0xa8304613);
- OP (B, C, D, A, 22, 0xfd469501);
- OP (A, B, C, D, 7, 0x698098d8);
- OP (D, A, B, C, 12, 0x8b44f7af);
- OP (C, D, A, B, 17, 0xffff5bb1);
- OP (B, C, D, A, 22, 0x895cd7be);
- OP (A, B, C, D, 7, 0x6b901122);
- OP (D, A, B, C, 12, 0xfd987193);
- OP (C, D, A, B, 17, 0xa679438e);
- OP (B, C, D, A, 22, 0x49b40821);
-
- /* For the second to fourth round we have the possibly swapped words
- in CORRECT_WORDS. Redefine the macro to take an additional first
- argument specifying the function to use. */
-#undef OP
-#define OP(f, a, b, c, d, k, s, T) \
- do \
- { \
- a += f (b, c, d) + correct_words[k] + T; \
- a = rol (a, s); \
- a += b; \
- } \
- while (0)
-
- /* Round 2. */
- OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
- OP (FG, D, A, B, C, 6, 9, 0xc040b340);
- OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
- OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
- OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
- OP (FG, D, A, B, C, 10, 9, 0x02441453);
- OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
- OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
- OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
- OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
- OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
- OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
- OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
- OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
- OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
- OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-
- /* Round 3. */
- OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
- OP (FH, D, A, B, C, 8, 11, 0x8771f681);
- OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
- OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
- OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
- OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
- OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
- OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
- OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
- OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
- OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
- OP (FH, B, C, D, A, 6, 23, 0x04881d05);
- OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
- OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
- OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
- OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
-
- /* Round 4. */
- OP (FI, A, B, C, D, 0, 6, 0xf4292244);
- OP (FI, D, A, B, C, 7, 10, 0x432aff97);
- OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
- OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
- OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
- OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
- OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
- OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
- OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
- OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
- OP (FI, C, D, A, B, 6, 15, 0xa3014314);
- OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
- OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
- OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
- OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
- OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
-
- /* Add the starting values of the context. */
- A += A_save;
- B += B_save;
- C += C_save;
- D += D_save;
- }
-
- /* Put checksum in context given as argument. */
- ctx->A = A;
- ctx->B = B;
- ctx->C = C;
- ctx->D = D;
-}
diff --git a/dvdread/md5.h b/dvdread/md5.h
deleted file mode 100644
index 2d9a8b4..0000000
--- a/dvdread/md5.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* md5.h - Declaration of functions and data types used for MD5 sum
- computing library functions.
- Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
- NOTE: The canonical source of this file is maintained with the GNU C
- Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
- 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _MD5_H
-#define _MD5_H
-
-#include <stdio.h>
-
-#if defined HAVE_LIMITS_H || _LIBC
-# include <limits.h>
-#endif
-
-/* The following contortions are an attempt to use the C preprocessor
- to determine an unsigned integral type that is 32 bits wide. An
- alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
- doing that would require that the configure script compile and *run*
- the resulting executable. Locally running cross-compiled executables
- is usually not possible. */
-
-#ifdef _LIBC
-# include <sys/types.h>
-typedef u_int32_t md5_uint32;
-#else
-# if defined __STDC__ && __STDC__
-# define UINT_MAX_32_BITS 4294967295U
-# else
-# define UINT_MAX_32_BITS 0xFFFFFFFF
-# endif
-
-/* If UINT_MAX isn't defined, assume it's a 32-bit type.
- This should be valid for all systems GNU cares about because
- that doesn't include 16-bit systems, and only modern systems
- (that certainly have <limits.h>) have 64+-bit integral types. */
-
-# ifndef UINT_MAX
-# define UINT_MAX UINT_MAX_32_BITS
-# endif
-
-# if UINT_MAX == UINT_MAX_32_BITS
-typedef unsigned int md5_uint32;
-# else
-# if USHRT_MAX == UINT_MAX_32_BITS
-typedef unsigned short md5_uint32;
-# else
-# if ULONG_MAX == UINT_MAX_32_BITS
-typedef unsigned long md5_uint32;
-# else
-/* The following line is intended to evoke an error.
- Using #error is not portable enough. */
-"Cannot determine unsigned 32-bit data type."
-# endif
-# endif
-# endif
-#endif
-
-#undef __P
-#if defined (__STDC__) && __STDC__
-#define __P(x) x
-#else
-#define __P(x) ()
-#endif
-
-/* Structure to save state of computation between the single steps. */
-struct md5_ctx
-{
- md5_uint32 A;
- md5_uint32 B;
- md5_uint32 C;
- md5_uint32 D;
-
- md5_uint32 total[2];
- md5_uint32 buflen;
- char buffer[128];
-};
-
-/*
- * The following three functions are build up the low level used in
- * the functions `md5_stream' and `md5_buffer'.
- */
-
-/* Initialize structure containing state of computation.
- (RFC 1321, 3.3: Step 3) */
-extern void md5_init_ctx __P ((struct md5_ctx *ctx));
-
-/* Starting with the result of former calls of this function (or the
- initialization function update the context for the next LEN bytes
- starting at BUFFER.
- It is necessary that LEN is a multiple of 64!!! */
-extern void md5_process_block __P ((const void *buffer, size_t len,
- struct md5_ctx *ctx));
-
-/* Starting with the result of former calls of this function (or the
- initialization function update the context for the next LEN bytes
- starting at BUFFER.
- It is NOT required that LEN is a multiple of 64. */
-extern void md5_process_bytes __P ((const void *buffer, size_t len,
- struct md5_ctx *ctx));
-
-/* Process the remaining bytes in the buffer and put result from CTX
- in first 16 bytes following RESBUF. The result is always in little
- endian byte order, so that a byte-wise output yields to the wanted
- ASCII representation of the message digest.
-
- IMPORTANT: On some systems it is required that RESBUF be correctly
- aligned for a 32 bits value. */
-extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
-
-
-/* Put result from CTX in first 16 bytes following RESBUF. The result is
- always in little endian byte order, so that a byte-wise output yields
- to the wanted ASCII representation of the message digest.
-
- IMPORTANT: On some systems it is required that RESBUF is correctly
- aligned for a 32 bits value. */
-extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
-
-
-/* Compute MD5 message digest for bytes read from STREAM. The
- resulting message digest number will be written into the 16 bytes
- beginning at RESBLOCK. */
-extern int md5_stream __P ((FILE *stream, void *resblock));
-
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
- result is always in little endian byte order, so that a byte-wise
- output yields to the wanted ASCII representation of the message
- digest. */
-extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
-
-/* The following is from gnupg-1.0.2's cipher/bithelp.h. */
-/* Rotate a 32 bit integer by n bytes */
-#if defined __GNUC__ && defined __i386__
-static md5_uint32
-rol(md5_uint32 x, int n)
-{
- __asm__("roll %%cl,%0"
- :"=r" (x)
- :"0" (x),"c" (n));
- return x;
-}
-#else
-# define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
-#endif
diff --git a/dvdread/nav_read.c b/dvdread/nav_read.c
deleted file mode 100644
index a96cd75..0000000
--- a/dvdread/nav_read.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-/*
- * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#if defined(HAVE_INTTYPES_H)
-#include <inttypes.h>
-#elif defined(HAVE_STDINT_H)
-#include <stdint.h>
-#endif
-
-#include "bswap.h"
-#include "nav_types.h"
-#include "nav_read.h"
-#include "dvdread_internal.h"
-
-void navRead_PCI(pci_t *pci, unsigned char *buffer) {
- int i, j;
-
- CHECK_VALUE(sizeof(pci_t) == PCI_BYTES - 1); /* -1 for substream id*/
-
- memcpy(pci, buffer, sizeof(pci_t));
-
- /* Endian conversions */
-
- /* pci pci_gi */
- B2N_32(pci->pci_gi.nv_pck_lbn);
- B2N_16(pci->pci_gi.vobu_cat);
- B2N_32(pci->pci_gi.vobu_s_ptm);
- B2N_32(pci->pci_gi.vobu_e_ptm);
- B2N_32(pci->pci_gi.vobu_se_e_ptm);
-
- /* pci nsml_agli */
- for(i = 0; i < 9; i++)
- B2N_32(pci->nsml_agli.nsml_agl_dsta[i]);
-
- /* pci hli hli_gi */
- B2N_16(pci->hli.hl_gi.hli_ss);
- B2N_32(pci->hli.hl_gi.hli_s_ptm);
- B2N_32(pci->hli.hl_gi.hli_e_ptm);
- B2N_32(pci->hli.hl_gi.btn_se_e_ptm);
-
- /* pci hli btn_colit */
- for(i = 0; i < 3; i++)
- for(j = 0; j < 2; j++)
- B2N_32(pci->hli.btn_colit.btn_coli[i][j]);
-
- /* NOTE: I've had to change the structure from the disk layout to get
- * the packing to work with Sun's Forte C compiler. */
-
- /* pci hli btni */
- for(i = 0; i < 36; i++) {
- char tmp[sizeof(pci->hli.btnit[i])], swap;
- memcpy(tmp, &(pci->hli.btnit[i]), sizeof(pci->hli.btnit[i]));
- /* Byte 4 to 7 are 'rotated' was: ABCD EFGH IJ is: ABCG DEFH IJ */
- swap = tmp[6];
- tmp[6] = tmp[5];
- tmp[5] = tmp[4];
- tmp[4] = tmp[3];
- tmp[3] = swap;
-
- /* Then there are the two B2N_24(..) calls */
-#ifndef WORDS_BIGENDIAN
- swap = tmp[0];
- tmp[0] = tmp[2];
- tmp[2] = swap;
-
- swap = tmp[4];
- tmp[4] = tmp[6];
- tmp[6] = swap;
-#endif
- memcpy(&(pci->hli.btnit[i]), tmp, sizeof(pci->hli.btnit[i]));
- }
-
-
-#ifndef NDEBUG
- /* Asserts */
-
- /* pci pci gi */
- CHECK_VALUE(pci->pci_gi.zero1 == 0);
-
- /* pci hli hli_gi */
- CHECK_VALUE(pci->hli.hl_gi.zero1 == 0);
- CHECK_VALUE(pci->hli.hl_gi.zero2 == 0);
- CHECK_VALUE(pci->hli.hl_gi.zero3 == 0);
- CHECK_VALUE(pci->hli.hl_gi.zero4 == 0);
- CHECK_VALUE(pci->hli.hl_gi.zero5 == 0);
-
- /* Are there buttons defined here? */
- if((pci->hli.hl_gi.hli_ss & 0x03) != 0) {
- CHECK_VALUE(pci->hli.hl_gi.btn_ns != 0);
- CHECK_VALUE(pci->hli.hl_gi.btngr_ns != 0);
- } else {
- CHECK_VALUE((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0)
- || (pci->hli.hl_gi.btn_ns == 0 && pci->hli.hl_gi.btngr_ns == 0));
- }
-
- /* pci hli btnit */
- for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) {
- for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) {
- int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j;
- CHECK_VALUE(pci->hli.btnit[n].zero1 == 0);
- CHECK_VALUE(pci->hli.btnit[n].zero2 == 0);
- CHECK_VALUE(pci->hli.btnit[n].zero3 == 0);
- CHECK_VALUE(pci->hli.btnit[n].zero4 == 0);
- CHECK_VALUE(pci->hli.btnit[n].zero5 == 0);
- CHECK_VALUE(pci->hli.btnit[n].zero6 == 0);
-
- if (j < pci->hli.hl_gi.btn_ns) {
- CHECK_VALUE(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end);
- CHECK_VALUE(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end);
- CHECK_VALUE(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns);
- CHECK_VALUE(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns);
- /*vmcmd_verify(pci->hli.btnit[n].cmd);*/
- } else {
- int k;
- CHECK_VALUE(pci->hli.btnit[n].btn_coln == 0);
- CHECK_VALUE(pci->hli.btnit[n].auto_action_mode == 0);
- CHECK_VALUE(pci->hli.btnit[n].x_start == 0);
- CHECK_VALUE(pci->hli.btnit[n].y_start == 0);
- CHECK_VALUE(pci->hli.btnit[n].x_end == 0);
- CHECK_VALUE(pci->hli.btnit[n].y_end == 0);
- CHECK_VALUE(pci->hli.btnit[n].up == 0);
- CHECK_VALUE(pci->hli.btnit[n].down == 0);
- CHECK_VALUE(pci->hli.btnit[n].left == 0);
- CHECK_VALUE(pci->hli.btnit[n].right == 0);
- for (k = 0; k < 8; k++)
- CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] == 0); /*CHECK_ZERO?*/
- }
- }
- }
-#endif /* !NDEBUG */
-}
-
-void navRead_DSI(dsi_t *dsi, unsigned char *buffer) {
- int i;
-
- CHECK_VALUE(sizeof(dsi_t) == DSI_BYTES - 1); /* -1 for substream id*/
-
- memcpy(dsi, buffer, sizeof(dsi_t));
-
- /* Endian conversions */
-
- /* dsi dsi gi */
- B2N_32(dsi->dsi_gi.nv_pck_scr);
- B2N_32(dsi->dsi_gi.nv_pck_lbn);
- B2N_32(dsi->dsi_gi.vobu_ea);
- B2N_32(dsi->dsi_gi.vobu_1stref_ea);
- B2N_32(dsi->dsi_gi.vobu_2ndref_ea);
- B2N_32(dsi->dsi_gi.vobu_3rdref_ea);
- B2N_16(dsi->dsi_gi.vobu_vob_idn);
-
- /* dsi sml pbi */
- B2N_16(dsi->sml_pbi.category);
- B2N_32(dsi->sml_pbi.ilvu_ea);
- B2N_32(dsi->sml_pbi.ilvu_sa);
- B2N_16(dsi->sml_pbi.size);
- B2N_32(dsi->sml_pbi.vob_v_s_s_ptm);
- B2N_32(dsi->sml_pbi.vob_v_e_e_ptm);
-
- /* dsi sml agli */
- for(i = 0; i < 9; i++) {
- B2N_32(dsi->sml_agli.data[ i ].address);
- B2N_16(dsi->sml_agli.data[ i ].size);
- }
-
- /* dsi vobu sri */
- B2N_32(dsi->vobu_sri.next_video);
- for(i = 0; i < 19; i++)
- B2N_32(dsi->vobu_sri.fwda[i]);
- B2N_32(dsi->vobu_sri.next_vobu);
- B2N_32(dsi->vobu_sri.prev_vobu);
- for(i = 0; i < 19; i++)
- B2N_32(dsi->vobu_sri.bwda[i]);
- B2N_32(dsi->vobu_sri.prev_video);
-
- /* dsi synci */
- for(i = 0; i < 8; i++)
- B2N_16(dsi->synci.a_synca[i]);
- for(i = 0; i < 32; i++)
- B2N_32(dsi->synci.sp_synca[i]);
-
-
- /* Asserts */
-
- /* dsi dsi gi */
- CHECK_VALUE(dsi->dsi_gi.zero1 == 0);
-}
-
diff --git a/dvdread/nav_read.h b/dvdread/nav_read.h
deleted file mode 100644
index d6c1a18..0000000
--- a/dvdread/nav_read.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef NAV_READ_H_INCLUDED
-#define NAV_READ_H_INCLUDED
-
-/*
- * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort@dtek.chalmers.se>.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "nav_types.h"
-
-/**
- * Parsing of NAV data, PCI and DSI parts.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Reads the PCI packet data pointed to into th pci struct.
- *
- * @param pci Pointer to the PCI data structure to be filled in.
- * @param bufffer Pointer to the buffer of the on disc PCI data.
- */
-void navRead_PCI(pci_t *, unsigned char *);
-
-/**
- * Reads the DSI packet data pointed to into dsi struct.
- *
- * @param dsi Pointer to the DSI data structure to be filled in.
- * @param bufffer Pointer to the buffer of the on disc DSI data.
- */
-void navRead_DSI(dsi_t *, unsigned char *);
-
-#ifdef __cplusplus
-};
-#endif
-#endif /* NAV_READ_H_INCLUDED */
diff --git a/dvdread/nav_types.h b/dvdread/nav_types.h
deleted file mode 100644
index 0678398..0000000
--- a/dvdread/nav_types.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#ifndef NAV_TYPES_H_INCLUDED
-#define NAV_TYPES_H_INCLUDED
-
-/*
- * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * The data structures in this file should represent the layout of the
- * pci and dsi packets as they are stored in the stream. Information
- * found by reading the source to VOBDUMP is the base for the structure
- * and names of these data types.
- *
- * VOBDUMP: a program for examining DVD .VOB files.
- * Copyright 1998, 1999 Eric Smith <eric@brouhaha.com>
- *
- * VOBDUMP is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. Note that I am not
- * granting permission to redistribute or modify VOBDUMP under the terms
- * of any later version of the General Public License.
- *
- * This program is distributed in the hope that it will be useful (or at
- * least amusing), 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA
- */
-
-#include "ifo_types.h"/* only dvd_time_t, vm_cmd_t and user_ops_t */
-/* If it's ever removed add a uintX_t test. */
-
-#undef ATTRIBUTE_PACKED
-#undef PRAGMA_PACK_BEGIN
-#undef PRAGMA_PACK_END
-
-#if defined(__GNUC__)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
-#define ATTRIBUTE_PACKED __attribute__ ((packed))
-#define PRAGMA_PACK 0
-#endif
-#endif
-
-#if !defined(ATTRIBUTE_PACKED)
-#define ATTRIBUTE_PACKED
-#define PRAGMA_PACK 1
-#endif
-
-
-/* The length including the substream id byte. */
-#define PCI_BYTES 0x3d4
-#define DSI_BYTES 0x3fa
-
-#define PS2_PCI_SUBSTREAM_ID 0x00
-#define PS2_DSI_SUBSTREAM_ID 0x01
-
-/* Remove this */
-#define DSI_START_BYTE 1031
-
-
-#if PRAGMA_PACK
-#pragma pack(1)
-#endif
-
-
-/**
- * PCI General Information
- */
-typedef struct {
- uint32_t nv_pck_lbn; /**< sector address of this nav pack */
- uint16_t vobu_cat; /**< 'category' of vobu */
- uint16_t zero1; /**< reserved */
- user_ops_t vobu_uop_ctl; /**< UOP of vobu */
- uint32_t vobu_s_ptm; /**< start presentation time of vobu */
- uint32_t vobu_e_ptm; /**< end presentation time of vobu */
- uint32_t vobu_se_e_ptm; /**< end ptm of sequence end in vobu */
- dvd_time_t e_eltm; /**< Cell elapsed time */
- char vobu_isrc[32];
-} ATTRIBUTE_PACKED pci_gi_t;
-
-/**
- * Non Seamless Angle Information
- */
-typedef struct {
- uint32_t nsml_agl_dsta[9]; /**< address of destination vobu in AGL_C#n */
-} ATTRIBUTE_PACKED nsml_agli_t;
-
-/**
- * Highlight General Information
- *
- * For btngrX_dsp_ty the bits have the following meaning:
- * 000b: normal 4/3 only buttons
- * XX1b: wide (16/9) buttons
- * X1Xb: letterbox buttons
- * 1XXb: pan&scan buttons
- */
-typedef struct {
- uint16_t hli_ss; /**< status, only low 2 bits 0: no buttons, 1: different 2: equal 3: eual except for button cmds */
- uint32_t hli_s_ptm; /**< start ptm of hli */
- uint32_t hli_e_ptm; /**< end ptm of hli */
- uint32_t btn_se_e_ptm; /**< end ptm of button select */
-#ifdef WORDS_BIGENDIAN
- unsigned int zero1 : 2; /**< reserved */
- unsigned int btngr_ns : 2; /**< number of button groups 1, 2 or 3 with 36/18/12 buttons */
- unsigned int zero2 : 1; /**< reserved */
- unsigned int btngr1_dsp_ty : 3; /**< display type of subpic stream for button group 1 */
- unsigned int zero3 : 1; /**< reserved */
- unsigned int btngr2_dsp_ty : 3; /**< display type of subpic stream for button group 2 */
- unsigned int zero4 : 1; /**< reserved */
- unsigned int btngr3_dsp_ty : 3; /**< display type of subpic stream for button group 3 */
-#else
- unsigned int btngr1_dsp_ty : 3;
- unsigned int zero2 : 1;
- unsigned int btngr_ns : 2;
- unsigned int zero1 : 2;
- unsigned int btngr3_dsp_ty : 3;
- unsigned int zero4 : 1;
- unsigned int btngr2_dsp_ty : 3;
- unsigned int zero3 : 1;
-#endif
- uint8_t btn_ofn; /**< button offset number range 0-255 */
- uint8_t btn_ns; /**< number of valid buttons <= 36/18/12 (low 6 bits) */
- uint8_t nsl_btn_ns; /**< number of buttons selectable by U_BTNNi (low 6 bits) nsl_btn_ns <= btn_ns */
- uint8_t zero5; /**< reserved */
- uint8_t fosl_btnn; /**< forcedly selected button (low 6 bits) */
- uint8_t foac_btnn; /**< forcedly activated button (low 6 bits) */
-} ATTRIBUTE_PACKED hl_gi_t;
-
-
-/**
- * Button Color Information Table
- * Each entry beeing a 32bit word that contains the color indexs and alpha
- * values to use. They are all represented by 4 bit number and stored
- * like this [Ci3, Ci2, Ci1, Ci0, A3, A2, A1, A0]. The actual palette
- * that the indexes reference is in the PGC.
- * @TODO split the uint32_t into a struct
- */
-typedef struct {
- uint32_t btn_coli[3][2]; /**< [button color number-1][select:0/action:1] */
-} ATTRIBUTE_PACKED btn_colit_t;
-
-/**
- * Button Information
- *
- * NOTE: I've had to change the structure from the disk layout to get
- * the packing to work with Sun's Forte C compiler.
- * The 4 and 7 bytes are 'rotated' was: ABC DEF GHIJ is: ABCG DEFH IJ
- */
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- unsigned int btn_coln : 2; /**< button color number */
- unsigned int x_start : 10; /**< x start offset within the overlay */
- unsigned int zero1 : 2; /**< reserved */
- unsigned int x_end : 10; /**< x end offset within the overlay */
-
- unsigned int zero3 : 2; /**< reserved */
- unsigned int up : 6; /**< button index when pressing up */
-
- unsigned int auto_action_mode : 2; /**< 0: no, 1: activated if selected */
- unsigned int y_start : 10; /**< y start offset within the overlay */
- unsigned int zero2 : 2; /**< reserved */
- unsigned int y_end : 10; /**< y end offset within the overlay */
-
- unsigned int zero4 : 2; /**< reserved */
- unsigned int down : 6; /**< button index when pressing down */
- unsigned int zero5 : 2; /**< reserved */
- unsigned int left : 6; /**< button index when pressing left */
- unsigned int zero6 : 2; /**< reserved */
- unsigned int right : 6; /**< button index when pressing right */
-#else
- unsigned int x_end : 10;
- unsigned int zero1 : 2;
- unsigned int x_start : 10;
- unsigned int btn_coln : 2;
-
- unsigned int up : 6;
- unsigned int zero3 : 2;
-
- unsigned int y_end : 10;
- unsigned int zero2 : 2;
- unsigned int y_start : 10;
- unsigned int auto_action_mode : 2;
-
- unsigned int down : 6;
- unsigned int zero4 : 2;
- unsigned int left : 6;
- unsigned int zero5 : 2;
- unsigned int right : 6;
- unsigned int zero6 : 2;
-#endif
- vm_cmd_t cmd;
-} ATTRIBUTE_PACKED btni_t;
-
-/**
- * Highlight Information
- */
-typedef struct {
- hl_gi_t hl_gi;
- btn_colit_t btn_colit;
- btni_t btnit[36];
-} ATTRIBUTE_PACKED hli_t;
-
-/**
- * PCI packet
- */
-typedef struct {
- pci_gi_t pci_gi;
- nsml_agli_t nsml_agli;
- hli_t hli;
- uint8_t zero1[189];
-} ATTRIBUTE_PACKED pci_t;
-
-
-
-
-/**
- * DSI General Information
- */
-typedef struct {
- uint32_t nv_pck_scr;
- uint32_t nv_pck_lbn; /**< sector address of this nav pack */
- uint32_t vobu_ea; /**< end address of this VOBU */
- uint32_t vobu_1stref_ea; /**< end address of the 1st reference image */
- uint32_t vobu_2ndref_ea; /**< end address of the 2nd reference image */
- uint32_t vobu_3rdref_ea; /**< end address of the 3rd reference image */
- uint16_t vobu_vob_idn; /**< VOB Id number that this VOBU is part of */
- uint8_t zero1; /**< reserved */
- uint8_t vobu_c_idn; /**< Cell Id number that this VOBU is part of */
- dvd_time_t c_eltm; /**< Cell elapsed time */
-} ATTRIBUTE_PACKED dsi_gi_t;
-
-/**
- * Seamless Playback Information
- */
-typedef struct {
- uint16_t category; /**< 'category' of seamless VOBU */
- uint32_t ilvu_ea; /**< end address of interleaved Unit */
- uint32_t ilvu_sa; /**< start address of next interleaved unit */
- uint16_t size; /**< size of next interleaved unit */
- uint32_t vob_v_s_s_ptm; /**< video start ptm in vob */
- uint32_t vob_v_e_e_ptm; /**< video end ptm in vob */
- struct {
- uint32_t stp_ptm1;
- uint32_t stp_ptm2;
- uint32_t gap_len1;
- uint32_t gap_len2;
- } vob_a[8];
-} ATTRIBUTE_PACKED sml_pbi_t;
-
-/**
- * Seamless Angle Infromation for one angle
- */
-typedef struct {
- uint32_t address; /**< offset to next ILVU, high bit is before/after */
- uint16_t size; /**< byte size of the ILVU pointed to by address */
-} ATTRIBUTE_PACKED sml_agl_data_t;
-
-/**
- * Seamless Angle Infromation
- */
-typedef struct {
- sml_agl_data_t data[9];
-} ATTRIBUTE_PACKED sml_agli_t;
-
-/**
- * VOBU Search Information
- */
-typedef struct {
- uint32_t next_video; /**< Next vobu that contains video */
- uint32_t fwda[19]; /**< Forwards, time */
- uint32_t next_vobu;
- uint32_t prev_vobu;
- uint32_t bwda[19]; /**< Backwards, time */
- uint32_t prev_video;
-} ATTRIBUTE_PACKED vobu_sri_t;
-
-#define SRI_END_OF_CELL 0x3fffffff
-
-/**
- * Synchronous Information
- */
-typedef struct {
- uint16_t a_synca[8]; /**< offset to first audio packet for this VOBU */
- uint32_t sp_synca[32]; /**< offset to first subpicture packet */
-} ATTRIBUTE_PACKED synci_t;
-
-/**
- * DSI packet
- */
-typedef struct {
- dsi_gi_t dsi_gi;
- sml_pbi_t sml_pbi;
- sml_agli_t sml_agli;
- vobu_sri_t vobu_sri;
- synci_t synci;
- uint8_t zero1[471];
-} ATTRIBUTE_PACKED dsi_t;
-
-
-#if PRAGMA_PACK
-#pragma pack()
-#endif
-
-#endif /* NAV_TYPES_H_INCLUDED */