This completes the task started in GIT hash 71c6fapull/1/head
parent
2fd0830c70
commit
b21d0b9415
@ -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
|
@ -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 */
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
@ -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 */
|
Loading…
Reference in new issue