rpms/libdvdnav/F-9 libdvdnav-r1001-r1043.patch, NONE, 1.1 libdvdnav.spec, 1.8, 1.9

Dominik Mierzejewski (rathann) fedora-extras-commits at redhat.com
Sat Jul 26 18:42:59 UTC 2008


Author: rathann

Update of /cvs/pkgs/rpms/libdvdnav/F-9
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv1419

Modified Files:
	libdvdnav.spec 
Added Files:
	libdvdnav-r1001-r1043.patch 
Log Message:
* Sat Jul 27 2008 Dominik Mierzejewski <rpm[AT]greysector.net> 4.1.2-2
- pull selected fixes from SVN
- re-enable parallel make


libdvdnav-r1001-r1043.patch:

--- NEW FILE libdvdnav-r1001-r1043.patch ---
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1001)
+++ ChangeLog	(revision 1043)
@@ -1,3 +1,7 @@
+libdvdnav /4.1.3)
+  * an embarassing amount of fixes regarding potential memory and resource leaks
+    (patches contributed by Erik Hovland)
+  * added dvdread-config (dvdnav-config's younger brother)
 libdvdnav (4.1.2)
   * multiple build system fixes
   * added dvdnav_describe_title_chapters(title) to get title and chapters
Index: src/read_cache.c
===================================================================
--- src/read_cache.c	(revision 1001)
+++ src/read_cache.c	(revision 1043)
@@ -42,7 +42,6 @@
 #include "remap.h"
 #include "vm/decoder.h"
 #include "vm/vm.h"
-#include "vm/vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 #include "read_cache.h"
Index: src/navigation.c
===================================================================
--- src/navigation.c	(revision 1001)
+++ src/navigation.c	(revision 1043)
@@ -35,7 +35,6 @@
 #include "remap.h"
 #include "vm/decoder.h"
 #include "vm/vm.h"
-#include "vm/vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 
@@ -105,7 +104,10 @@
   if ( (this->vm->state.domain == VTSM_DOMAIN)
       || (this->vm->state.domain == VMGM_DOMAIN) ) {
     /* Get current Menu ID: into *part. */
-    vm_get_current_menu(this->vm, part);
+    if(! vm_get_current_menu(this->vm, part)) {
+      pthread_mutex_unlock(&this->vm_lock);
+      return DVDNAV_STATUS_ERR;
+    }
     if (*part > -1) {
       *title = 0;
       pthread_mutex_unlock(&this->vm_lock);
Index: src/settings.c
===================================================================
--- src/settings.c	(revision 1001)
+++ src/settings.c	(revision 1043)
@@ -35,7 +35,6 @@
 #include "remap.h"
 #include "vm/decoder.h"
 #include "vm/vm.h"
-#include "vm/vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 
Index: src/vm/vm.c
===================================================================
--- src/vm/vm.c	(revision 1001)
+++ src/vm/vm.c	(revision 1043)
@@ -48,7 +48,6 @@
 #include "decoder.h"
 #include "remap.h"
 #include "vm.h"
-#include "vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 
@@ -613,6 +612,7 @@
   int pgcn;
   pgcn = (vm->state).pgcN;
   pgcit = get_PGCIT(vm);
+  if(pgcit==NULL) return 0;
   *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
   return 1;
 }
@@ -1824,13 +1824,15 @@
 
 /* Uses state to decide what to return */
 static pgcit_t* get_PGCIT(vm_t *vm) {
-  pgcit_t *pgcit;
+  pgcit_t *pgcit = NULL;
   
   switch ((vm->state).domain) {
   case VTS_DOMAIN:
+    if(!vm->vtsi) return NULL;
     pgcit = vm->vtsi->vts_pgcit;
     break;
   case VTSM_DOMAIN:
+    if(!vm->vtsi) return NULL;
     pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);
     break;
   case VMGM_DOMAIN:
Index: src/searching.c
===================================================================
--- src/searching.c	(revision 1001)
+++ src/searching.c	(revision 1043)
@@ -38,7 +38,6 @@
 #include "remap.h"
 #include "vm/decoder.h"
 #include "vm/vm.h"
-#include "vm/vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 
Index: src/remap.c
===================================================================
--- src/remap.c	(revision 1001)
+++ src/remap.c	(revision 1043)
@@ -45,7 +45,6 @@
 #include "remap.h"
 #include "vm/decoder.h"
 #include "vm/vm.h"
-#include "vm/vmcmd.h"
 #include "dvdnav.h"
 #include "dvdnav_internal.h"
 
@@ -229,8 +228,12 @@
 	    remap_add_node( map, tmp);
 	}
     }
+    fclose(fp);
 
-    if (map->nblocks == 0 && map->debug == 0) return NULL;
+    if (map->nblocks == 0 && map->debug == 0) {
+        free(map);
+        return NULL;
+    }
     return map;
 }
 
Index: src/dvdnav.c
===================================================================
--- src/dvdnav.c	(revision 1001)
+++ src/dvdnav.c	(revision 1043)
@@ -53,6 +53,7 @@
 static dvdnav_status_t dvdnav_clear(dvdnav_t * this) {
   /* clear everything except file, vm, mutex, readahead */
 
+  pthread_mutex_lock(&this->vm_lock);
   if (this->file) DVDCloseFile(this->file);
   this->file = NULL;
 
@@ -70,6 +71,7 @@
   this->cur_cell_time = 0;
 
   dvdnav_read_cache_clear(this->cache);
+  pthread_mutex_unlock(&this->vm_lock);
   
   return DVDNAV_STATUS_OK;
 }
@@ -108,7 +110,8 @@
   }
 
   /* Set the path. FIXME: Is a deep copy 'right' */
-  strncpy(this->path, path, MAX_PATH_LEN);
+  strncpy(this->path, path, MAX_PATH_LEN - 1);
+  this->path[MAX_PATH_LEN - 1] = '\0';
 
   /* Pre-open and close a file so that the CSS-keys are cached. */
   this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), 0, DVD_READ_MENU_VOBS);
@@ -134,11 +137,13 @@
 #endif
 
   if (this->file) {
+    pthread_mutex_lock(&this->vm_lock); 
     DVDCloseFile(this->file);
 #ifdef LOG_DEBUG
     fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
 #endif
     this->file = NULL;
+    pthread_mutex_unlock(&this->vm_lock); 
   }
 
   /* Free the VM */
@@ -413,6 +418,7 @@
     /* Start the VM */
     if (!vm_start(this->vm)) {
       printerr("Encrypted or faulty DVD");
+      pthread_mutex_unlock(&this->vm_lock);
       return DVDNAV_STATUS_ERR;
     }
     this->started = 1;
Index: src/dvdread/dvd_reader.c
===================================================================
--- src/dvdread/dvd_reader.c	(revision 1001)
+++ src/dvdread/dvd_reader.c	(revision 1043)
@@ -88,6 +88,8 @@
     void *udfcache;
 };
 
+#define TITLES_MAX 9
+
 struct dvd_file_s {
     /* Basic information. */
     dvd_reader_t *dvd;
@@ -100,8 +102,8 @@
     uint32_t seek_pos;
 
     /* Information required for a directory path drive. */
-    size_t title_sizes[ 9 ];
-    dvd_input_t title_devs[ 9 ];
+    size_t title_sizes[ TITLES_MAX ];
+    dvd_input_t title_devs[ TITLES_MAX ];
 
     /* Calculated at open-time, size in blocks. */
     ssize_t filesize;
@@ -441,10 +443,10 @@
 		path_copy[ strlen( path_copy ) - 1 ] = '\0';
 	}
 
-	if( strlen( path_copy ) > 9 ) {
-	    if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]), 
+	if( strlen( path_copy ) > TITLES_MAX ) {
+	    if( !strcasecmp( &(path_copy[ strlen( path_copy ) - TITLES_MAX ]), 
 			     "/video_ts" ) ) {
-	      path_copy[ strlen( path_copy ) - 9 ] = '\0';
+	      path_copy[ strlen( path_copy ) - TITLES_MAX ] = '\0';
 	    }
 	}
 	
@@ -788,7 +790,7 @@
         dvd_file->filesize = dvd_file->title_sizes[ 0 ];
 
     } else {
-        for( i = 0; i < 9; ++i ) {
+        for( i = 0; i < TITLES_MAX; ++i ) {
 
             sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 );
             if( !findDVDFile( dvd, filename, full_path ) ) {
@@ -873,7 +875,7 @@
         if( dvd_file->dvd->isImageFile ) {
 	    ;
 	} else {
-            for( i = 0; i < 9; ++i ) {
+            for( i = 0; i < TITLES_MAX; ++i ) {
                 if( dvd_file->title_devs[ i ] ) {
                     dvdinput_close( dvd_file->title_devs[i] );
                 }
@@ -936,7 +938,7 @@
 
     ret = 0;
     ret2 = 0;
-    for( i = 0; i < 9; ++i ) {
+    for( i = 0; i < TITLES_MAX; ++i ) {
       if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */
 
         if( offset < dvd_file->title_sizes[ i ] ) {
@@ -969,7 +971,8 @@
                  * also error from this read will not show in ret. */
 		
 		/* Does the next part exist? If not then return now. */
-		if( !dvd_file->title_devs[ i + 1 ] ) return ret;
+		if( i + 1 >= TITLES_MAX || !dvd_file->title_devs[ i + 1 ] )
+                    return ret;
 
                 /* Read part 2 */
                 off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 );
@@ -1039,6 +1042,28 @@
     return offset;
 }
 
+int DVDFileSeekForce(dvd_file_t *dvd_file, int offset, int force_size)
+{
+    /* Check arguments. */
+    if( dvd_file == NULL || offset <= 0 )
+        return -1;
+
+    if( dvd_file->dvd->isImageFile ) {
+        if( force_size < 0 )
+            force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1;
+        if( dvd_file->filesize < force_size ) {
+            dvd_file->filesize = force_size;
+            fprintf(stderr, "libdvdread: Ignored size of file indicated in UDF.\n");
+        }
+    }
+
+    if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN )
+        return -1;
+
+    dvd_file->seek_pos = (uint32_t) offset;
+    return offset;
+}
+
 ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
 {
     unsigned char *secbuf_base, *secbuf;
@@ -1079,7 +1104,7 @@
     memcpy( data, &(secbuf[ seek_byte ]), byte_size );
     free( secbuf_base );
 
-    dvd_file->seek_pos += byte_size;
+    DVDFileSeekForce(dvd_file, dvd_file->seek_pos + byte_size, -1);
     return byte_size;
 }
 
@@ -1114,6 +1139,7 @@
 	    char *buffer = (unsigned char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048);
 	    
 	    if( buffer_base == NULL ) {
+	        DVDCloseFile( dvd_file );
 		fprintf( stderr, "libdvdread: DVDDiscId, failed to "
 			 "allocate memory for file read!\n" );
 		return -1;
Index: src/dvdread/bitreader.c
===================================================================
--- src/dvdread/bitreader.c	(revision 0)
+++ src/dvdread/bitreader.c	(revision 1043)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort at 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "bitreader.h"
+
+int dvdread_getbits_init(getbits_state_t *state, uint8_t *start) {
+  if ((state == NULL) || (start == NULL)) return 0;
+  state->start = start;
+  state->bit_position = 0;
+  state->byte_position = 0;
+  state->byte = start[0];
+  return 1;
+}
+
+/* Non-optimized getbits. */
+/* This can easily be optimized for particular platforms. */
+uint32_t dvdread_getbits(getbits_state_t *state, uint32_t number_of_bits) {
+  uint32_t result=0;
+  uint8_t byte=0;
+  if (number_of_bits > 32) {
+    printf("Number of bits > 32 in getbits\n");
+    abort();
+  }
+
+  if ((state->bit_position) > 0) {  /* Last getbits left us in the middle of a byte. */
+    if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */
+      byte = state->byte;
+      byte = byte >> (state->bit_position);
+      result = byte;
+      number_of_bits -= (8-state->bit_position);
+      state->bit_position = 0;
+      state->byte_position++;
+      state->byte = state->start[state->byte_position];
+    } else {
+      byte=state->byte;
+      state->byte = state->byte << number_of_bits;
+      byte = byte >> (8 - number_of_bits);
+      result = byte;
+      state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */
+      if (state->bit_position == 8) {
+        state->bit_position = 0;
+        state->byte_position++;
+        state->byte = state->start[state->byte_position];
+      }
+      number_of_bits = 0;
+    }
+  }
+  if ((state->bit_position) == 0) {
+    while (number_of_bits > 7) {
+      result = (result << 8) + state->byte;
+      state->byte_position++;
+      state->byte = state->start[state->byte_position];
+      number_of_bits -= 8;
+    }
+    if (number_of_bits > 0) { /* number_of_bits < 8 */
+      byte = state->byte;
+      state->byte = state->byte << number_of_bits;
+      state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */
+      byte = byte >> (8 - number_of_bits);
+      result = (result << number_of_bits) + byte;
+      number_of_bits = 0;
+    }
+  }
+
+  return result;
+}
+
+#if 0  /* TODO: optimized versions not yet used */
+
+/* WARNING: This function can only be used on a byte boundary.
+            No checks are made that we are in fact on a byte boundary.
+ */
+uint16_t dvdread_get16bits(getbits_state_t *state) {
+  uint16_t result;
+  state->byte_position++;
+  result = (state->byte << 8) + state->start[state->byte_position++];
+  state->byte = state->start[state->byte_position];
+  return result;
+}
+
+/* WARNING: This function can only be used on a byte boundary.
+            No checks are made that we are in fact on a byte boundary.
+ */
+uint32_t dvdread_get32bits(getbits_state_t *state) {
+  uint32_t result;
+  state->byte_position++;
+  result = (state->byte << 8) + state->start[state->byte_position++];
+  result = (result << 8) + state->start[state->byte_position++];
+  result = (result << 8) + state->start[state->byte_position++];
+  state->byte = state->start[state->byte_position];
+  return result;
+}
+
+#endif

Property changes on: src/dvdread/bitreader.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Index: src/dvdread/dvd_reader.h
===================================================================
--- src/dvdread/dvd_reader.h	(revision 1001)
+++ src/dvdread/dvd_reader.h	(revision 1043)
@@ -229,6 +229,8 @@
 int DVDUDFVolumeInfo( dvd_reader_t *, char *, unsigned int,
 		      unsigned char *, unsigned int );
 
+int DVDFileSeekForce( dvd_file_t *, int offset, int force_size);
+
 /**
  * Get the ISO9660 VolumeIdentifier and VolumeSetIdentifier
  *
Index: src/dvdread/ifo_types.h
===================================================================
--- src/dvdread/ifo_types.h	(revision 1001)
+++ src/dvdread/ifo_types.h	(revision 1043)
@@ -75,7 +75,6 @@
  * Video Attributes.
  */
 typedef struct {
-#ifdef WORDS_BIGENDIAN
   unsigned char mpeg_version         : 2;
   unsigned char video_format         : 2;
   unsigned char display_aspect_ratio : 2;
@@ -89,28 +88,12 @@
   unsigned char picture_size         : 2;
   unsigned char letterboxed          : 1;
   unsigned char film_mode            : 1;
-#else
-  unsigned char permitted_df         : 2;
-  unsigned char display_aspect_ratio : 2;
-  unsigned char video_format         : 2;
-  unsigned char mpeg_version         : 2;
-  
-  unsigned char film_mode            : 1;
-  unsigned char letterboxed          : 1;
-  unsigned char picture_size         : 2;
-  
-  unsigned char bit_rate             : 1;
-  unsigned char unknown1             : 1;
-  unsigned char line21_cc_2          : 1;
-  unsigned char line21_cc_1          : 1;
-#endif
 } ATTRIBUTE_PACKED video_attr_t;
 
 /**
  * Audio Attributes.
  */
 typedef struct {
-#ifdef WORDS_BIGENDIAN
   unsigned char audio_format           : 3;
   unsigned char multichannel_extension : 1;
   unsigned char lang_type              : 2;
@@ -120,47 +103,22 @@
   unsigned char sample_frequency       : 2;
   unsigned char unknown1               : 1;
   unsigned char channels               : 3;
-#else
-  unsigned char application_mode       : 2;
-  unsigned char lang_type              : 2;
-  unsigned char multichannel_extension : 1;
-  unsigned char audio_format           : 3;
-  
-  unsigned char channels               : 3;
-  unsigned char unknown1               : 1;
-  unsigned char sample_frequency       : 2;
-  unsigned char quantization           : 2;
-#endif
   uint16_t lang_code;
   uint8_t  lang_extension;
   uint8_t  code_extension;
   uint8_t unknown3;
   union {
     struct ATTRIBUTE_PACKED {
-#ifdef WORDS_BIGENDIAN
       unsigned char unknown4           : 1;
       unsigned char channel_assignment : 3;
       unsigned char version            : 2;
       unsigned char mc_intro           : 1; /* probably 0: true, 1:false */
       unsigned char mode               : 1; /* Karaoke mode 0: solo 1: duet */
-#else
-      unsigned char mode               : 1;
-      unsigned char mc_intro           : 1;
-      unsigned char version            : 2;
-      unsigned char channel_assignment : 3;
-      unsigned char unknown4           : 1;
-#endif
     } karaoke;
     struct ATTRIBUTE_PACKED {
-#ifdef WORDS_BIGENDIAN
       unsigned char unknown5           : 4;
       unsigned char dolby_encoded      : 1; /* suitable for surround decoding */
       unsigned char unknown6           : 3;
-#else
-      unsigned char unknown6           : 3;
-      unsigned char dolby_encoded      : 1;
-      unsigned char unknown5           : 4;
-#endif
     } surround;
   } app_info;
 } ATTRIBUTE_PACKED audio_attr_t;
@@ -170,7 +128,6 @@
  * MultiChannel Extension
  */
 typedef struct {
-#ifdef WORDS_BIGENDIAN
   unsigned int zero1      : 7;
   unsigned int ach0_gme   : 1;
 
@@ -194,31 +151,6 @@
   unsigned int ach4_gv2e  : 1;
   unsigned int ach4_gmBe  : 1;
   unsigned int ach4_seBe  : 1;
-#else
-  unsigned char ach0_gme   : 1;
-  unsigned char zero1      : 7;
-
-  unsigned char ach1_gme   : 1;
-  unsigned char zero2      : 7;
-
-  unsigned char ach2_gm2e  : 1;
-  unsigned char ach2_gm1e  : 1;
-  unsigned char ach2_gv2e  : 1;
-  unsigned char ach2_gv1e  : 1;
-  unsigned char zero3      : 4;
-
-  unsigned char ach3_se2e  : 1;
-  unsigned char ach3_gmAe  : 1;
-  unsigned char ach3_gv2e  : 1;
-  unsigned char ach3_gv1e  : 1;
-  unsigned char zero4      : 4;
-
-  unsigned char ach4_seBe  : 1;
-  unsigned char ach4_gmBe  : 1;
-  unsigned char ach4_gv2e  : 1;
-  unsigned char ach4_gv1e  : 1;
-  unsigned char zero5      : 4;
-#endif
   uint8_t zero6[19];
 } ATTRIBUTE_PACKED multichannel_ext_t;
 
@@ -237,15 +169,9 @@
    * language: indicates language if type == 1
    * lang extension: if type == 1 contains the lang extension
    */
-#ifdef WORDS_BIGENDIAN
   unsigned char code_mode : 3;
   unsigned char zero1     : 3;
   unsigned char type      : 2;
-#else
-  unsigned char type      : 2;
-  unsigned char zero1     : 3;
-  unsigned char code_mode : 3;
-#endif
   uint8_t  zero2;
   uint16_t lang_code;
   uint8_t  lang_extension;
@@ -277,29 +203,15 @@
  * 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 char seamless_angle   : 1;
-  unsigned char stc_discontinuity: 1;
-  unsigned char interleaved      : 1;
-  unsigned char seamless_play    : 1;
-  unsigned char block_type       : 2;
-  unsigned char block_mode       : 2;
-  
-  unsigned char unknown2         : 6;
-  unsigned char restricted       : 1;
-  unsigned char playback_mode    : 1;
-#endif
   uint8_t still_time;
   uint8_t cell_cmd_nr;
   dvd_time_t playback_time;
@@ -330,7 +242,6 @@
  * User Operations.
  */
 typedef struct {
-#ifdef WORDS_BIGENDIAN
   unsigned int zero                           : 7; /* 25-31 */
   unsigned int video_pres_mode_change         : 1; /* 24 */
   
@@ -360,37 +271,6 @@
   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;
 
 /**
@@ -426,15 +306,9 @@
  */
 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 char unknown1   : 4;
-  unsigned char block_type : 2;
-  unsigned char block_mode : 2;
-#endif  
   uint16_t ptl_id_mask;
   uint32_t pgc_start_byte;
   pgc_t *pgc;
@@ -559,7 +433,6 @@
 } 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;
@@ -568,16 +441,6 @@
   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 char title_or_time_play        : 1;
-  unsigned char chapter_search_or_play    : 1;
-  unsigned char jlc_exists_in_tt_dom      : 1;
-  unsigned char jlc_exists_in_button_cmd  : 1;
-  unsigned char jlc_exists_in_prepost_cmd : 1;
-  unsigned char jlc_exists_in_cell_cmd    : 1;
-  unsigned char multi_or_random_pgc_title : 1;
-  unsigned char zero_1                    : 1;
-#endif
 } ATTRIBUTE_PACKED playback_type_t;
 
 /**
Index: src/dvdread/bitreader.h
===================================================================
--- src/dvdread/bitreader.h	(revision 0)
+++ src/dvdread/bitreader.h	(revision 1043)
@@ -0,0 +1,40 @@
+#ifndef BITREADER_H_INCLUDED
+#define BITREADER_H_INCLUDED
+
+/*
+ * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort at 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+  uint8_t *start;
+  uint32_t byte_position;
+  uint32_t bit_position;
+  uint8_t byte;
+} getbits_state_t;
+
+int dvdread_getbits_init(getbits_state_t *state, uint8_t *start);
+uint32_t dvdread_getbits(getbits_state_t *state, uint32_t number_of_bits);
+
+#ifdef __cplusplus
+};
+#endif
+#endif /* BITREADER_H_INCLUDED */
Index: src/dvdread/ifo_read.c
===================================================================
--- src/dvdread/ifo_read.c	(revision 1001)
+++ src/dvdread/ifo_read.c	(revision 1043)
@@ -30,6 +30,7 @@
 #include "ifo_read.h"
 #include "dvd_reader.h"
 #include "dvdread_internal.h"
+#include "bitreader.h"
 
 #ifndef DVD_BLOCK_LEN
 #define DVD_BLOCK_LEN 2048
@@ -88,12 +89,193 @@
 static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl);
 static void ifoFree_PGCIT_internal(pgcit_t *pgcit);
 
+static inline int DVDFileSeekForce_( dvd_file_t *dvd_file, uint32_t offset, int force_size ) {
+  return (DVDFileSeekForce(dvd_file, (int)offset, force_size) == (int)offset);
+}
 
 static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
   return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
 }
 
+static void read_video_attr(video_attr_t *va) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(video_attr_t)];
 
+  memcpy(buf, va, sizeof(video_attr_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  va->mpeg_version = dvdread_getbits(&state, 2);
+  va->video_format = dvdread_getbits(&state, 2);
+  va->display_aspect_ratio = dvdread_getbits(&state, 2);
+  va->permitted_df = dvdread_getbits(&state, 2);
+  va->line21_cc_1 = dvdread_getbits(&state, 1);
+  va->line21_cc_2 = dvdread_getbits(&state, 1);
+  va->unknown1 = dvdread_getbits(&state, 1);
+  va->bit_rate = dvdread_getbits(&state, 1);
+  va->picture_size = dvdread_getbits(&state, 2);
+  va->letterboxed = dvdread_getbits(&state, 1);
+  va->film_mode = dvdread_getbits(&state, 1);
+}
+
+static void read_audio_attr(audio_attr_t *aa) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(audio_attr_t)];
+  
+  memcpy(buf, aa, sizeof(audio_attr_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  aa->audio_format = dvdread_getbits(&state, 3);
+  aa->multichannel_extension = dvdread_getbits(&state, 1);
+  aa->lang_type = dvdread_getbits(&state, 2);
+  aa->application_mode = dvdread_getbits(&state, 2);
+  aa->quantization = dvdread_getbits(&state, 2);
+  aa->sample_frequency = dvdread_getbits(&state, 2);
+  aa->unknown1 = dvdread_getbits(&state, 1);
+  aa->channels = dvdread_getbits(&state, 3);
+  aa->lang_code = dvdread_getbits(&state, 16);
+  aa->lang_extension = dvdread_getbits(&state, 8);
+  aa->code_extension = dvdread_getbits(&state, 8);
+  aa->unknown3 = dvdread_getbits(&state, 8);
+  aa->app_info.karaoke.unknown4 = dvdread_getbits(&state, 1);
+  aa->app_info.karaoke.channel_assignment = dvdread_getbits(&state, 3);
+  aa->app_info.karaoke.version = dvdread_getbits(&state, 2);
+  aa->app_info.karaoke.mc_intro = dvdread_getbits(&state, 1);
+  aa->app_info.karaoke.mode = dvdread_getbits(&state, 1);
+}
+
+static void read_multichannel_ext(multichannel_ext_t *me) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(multichannel_ext_t)];
+  
+  memcpy(buf, me, sizeof(multichannel_ext_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  me->zero1 = dvdread_getbits(&state, 7);
+  me->ach0_gme = dvdread_getbits(&state, 1);
+  me->zero2 = dvdread_getbits(&state, 7);
+  me->ach1_gme = dvdread_getbits(&state, 1);
+  me->zero3 = dvdread_getbits(&state, 4);
+  me->ach2_gv1e = dvdread_getbits(&state, 1);
+  me->ach2_gv2e = dvdread_getbits(&state, 1);
+  me->ach2_gm1e = dvdread_getbits(&state, 1);
+  me->ach2_gm2e = dvdread_getbits(&state, 1);
+  me->zero4 = dvdread_getbits(&state, 4);
+  me->ach3_gv1e = dvdread_getbits(&state, 1);
+  me->ach3_gv2e = dvdread_getbits(&state, 1);
+  me->ach3_gmAe = dvdread_getbits(&state, 1);
+  me->ach3_se2e = dvdread_getbits(&state, 1);
+  me->zero5 = dvdread_getbits(&state, 4);
+  me->ach4_gv1e = dvdread_getbits(&state, 1);
+  me->ach4_gv2e = dvdread_getbits(&state, 1);
+  me->ach4_gmBe = dvdread_getbits(&state, 1);
+  me->ach4_seBe = dvdread_getbits(&state, 1);
+}
+
+static void read_subp_attr(subp_attr_t *sa) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(subp_attr_t)];
+  
+  memcpy(buf, sa, sizeof(subp_attr_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  sa->code_mode = dvdread_getbits(&state, 3);
+  sa->zero1 = dvdread_getbits(&state, 3);
+  sa->type = dvdread_getbits(&state, 2);
+  sa->zero2 = dvdread_getbits(&state, 8);
+  sa->lang_code = dvdread_getbits(&state, 16);
+  sa->lang_extension = dvdread_getbits(&state, 8);
+  sa->code_extension = dvdread_getbits(&state, 8);
+}
+
+static void read_user_ops(user_ops_t *uo) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(user_ops_t)];
+  
+  memcpy(buf, uo, sizeof(user_ops_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  uo->zero                           = dvdread_getbits(&state, 7);
+  uo->video_pres_mode_change         = dvdread_getbits(&state, 1);
+  uo->karaoke_audio_pres_mode_change = dvdread_getbits(&state, 1);
+  uo->angle_change                   = dvdread_getbits(&state, 1);
+  uo->subpic_stream_change           = dvdread_getbits(&state, 1);
+  uo->audio_stream_change            = dvdread_getbits(&state, 1);
+  uo->pause_on                       = dvdread_getbits(&state, 1);
+  uo->still_off                      = dvdread_getbits(&state, 1);
+  uo->button_select_or_activate      = dvdread_getbits(&state, 1);
+  uo->resume                         = dvdread_getbits(&state, 1);
+  uo->chapter_menu_call              = dvdread_getbits(&state, 1);
+  uo->angle_menu_call                = dvdread_getbits(&state, 1);
+  uo->audio_menu_call                = dvdread_getbits(&state, 1);
+  uo->subpic_menu_call               = dvdread_getbits(&state, 1);
+  uo->root_menu_call                 = dvdread_getbits(&state, 1);
+  uo->title_menu_call                = dvdread_getbits(&state, 1);
+  uo->backward_scan                  = dvdread_getbits(&state, 1);
+  uo->forward_scan                   = dvdread_getbits(&state, 1);
+  uo->next_pg_search                 = dvdread_getbits(&state, 1);
+  uo->prev_or_top_pg_search          = dvdread_getbits(&state, 1);
+  uo->time_or_chapter_search         = dvdread_getbits(&state, 1);
+  uo->go_up                          = dvdread_getbits(&state, 1);
+  uo->stop                           = dvdread_getbits(&state, 1);
+  uo->title_play                     = dvdread_getbits(&state, 1);
+  uo->chapter_search_or_play         = dvdread_getbits(&state, 1);
+  uo->title_or_time_play             = dvdread_getbits(&state, 1);
+}
+
+static void read_pgci_srp(pgci_srp_t *ps) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(pgci_srp_t)];
+  
+  memcpy(buf, ps, sizeof(pgci_srp_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  ps->entry_id                       = dvdread_getbits(&state, 8);
+  ps->block_mode                     = dvdread_getbits(&state, 2);
+  ps->block_type                     = dvdread_getbits(&state, 2);
+  ps->unknown1                       = dvdread_getbits(&state, 4);
+  ps->ptl_id_mask                    = dvdread_getbits(&state, 16);
+  ps->pgc_start_byte                 = dvdread_getbits(&state, 32);
+}
+
+static void read_cell_playback(cell_playback_t *cp) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(cell_playback_t)];
+  
+  memcpy(buf, cp, sizeof(cell_playback_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  cp->block_mode                      = dvdread_getbits(&state, 2);
+  cp->block_type                      = dvdread_getbits(&state, 2);
+  cp->seamless_play                   = dvdread_getbits(&state, 1);
+  cp->interleaved                     = dvdread_getbits(&state, 1);
+  cp->stc_discontinuity               = dvdread_getbits(&state, 1);
+  cp->seamless_angle                  = dvdread_getbits(&state, 1);
+  cp->playback_mode                   = dvdread_getbits(&state, 1);
+  cp->restricted                      = dvdread_getbits(&state, 1);
+  cp->unknown2                        = dvdread_getbits(&state, 6);
+  cp->still_time                      = dvdread_getbits(&state, 8);
+  cp->cell_cmd_nr                     = dvdread_getbits(&state, 8);
+  
+  cp->playback_time.hour              = dvdread_getbits(&state, 8);
+  cp->playback_time.minute            = dvdread_getbits(&state, 8);
+  cp->playback_time.second            = dvdread_getbits(&state, 8);
+  cp->playback_time.frame_u           = dvdread_getbits(&state, 8);
+  
+  cp->first_sector                    = dvdread_getbits(&state, 32);
+  cp->first_ilvu_end_sector           = dvdread_getbits(&state, 32);
+  cp->last_vobu_start_sector          = dvdread_getbits(&state, 32);
+  cp->last_sector                     = dvdread_getbits(&state, 32);
+}
+
+static void read_playback_type(playback_type_t *pt) {
+  getbits_state_t state;
+  uint8_t buf[sizeof(playback_type_t)];
+  
+  memcpy(buf, pt, sizeof(playback_type_t));
+  if (!dvdread_getbits_init(&state, buf)) abort();
+  pt->zero_1                          = dvdread_getbits(&state, 1);
+  pt->multi_or_random_pgc_title       = dvdread_getbits(&state, 1);
+  pt->jlc_exists_in_cell_cmd          = dvdread_getbits(&state, 1);
+  pt->jlc_exists_in_prepost_cmd       = dvdread_getbits(&state, 1);
+  pt->jlc_exists_in_button_cmd        = dvdread_getbits(&state, 1);
+  pt->jlc_exists_in_tt_dom            = dvdread_getbits(&state, 1);
+  pt->chapter_search_or_play          = dvdread_getbits(&state, 1);
+  pt->title_or_time_play              = dvdread_getbits(&state, 1);
+}
+
 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
   ifo_handle_t *ifofile;
 
@@ -121,7 +303,7 @@
 
     /* These are both mandatory. */
     if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n");
+      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_FP_PGC() failed.\n");
       ifoClose(ifofile);
       return NULL;
     }
@@ -131,7 +313,7 @@
 
     /* This is also mandatory. */
     if(!ifoRead_VTS_ATRT(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n");
+      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_VTS_ATRT() failed.\n");
       ifoClose(ifofile);
       return NULL;
     }
@@ -200,7 +382,7 @@
   if(ifoRead_VMG(ifofile))
     return ifofile;
 
-  fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n");
+  fprintf(stderr, "libdvdread,ifoOpenVMGI(): Invalid main menu IFO (VIDEO_TS.IFO).\n");
   ifoClose(ifofile);
   return NULL;
 }
@@ -316,8 +498,9 @@
   B2N_32(vmgi_mat->txtdt_mgi);
   B2N_32(vmgi_mat->vmgm_c_adt);
   B2N_32(vmgi_mat->vmgm_vobu_admap);
-  B2N_16(vmgi_mat->vmgm_audio_attr.lang_code);
-  B2N_16(vmgi_mat->vmgm_subp_attr.lang_code);
+  read_video_attr(&vmgi_mat->vmgm_video_attr);
+  read_audio_attr(&vmgi_mat->vmgm_audio_attr);
+  read_subp_attr(&vmgi_mat->vmgm_subp_attr);
 
 
   CHECK_ZERO(vmgi_mat->zero_1);
@@ -390,6 +573,14 @@
     return 0;
   }
 
+  read_video_attr(&vtsi_mat->vtsm_video_attr);
+  read_video_attr(&vtsi_mat->vts_video_attr);
+  read_audio_attr(&vtsi_mat->vtsm_audio_attr);
+  for(i=0; i<8; i++)
+    read_audio_attr(&vtsi_mat->vts_audio_attr[i]);
+  read_subp_attr(&vtsi_mat->vtsm_subp_attr);
+  for(i=0; i<32; i++)
+    read_subp_attr(&vtsi_mat->vts_subp_attr[i]);
   B2N_32(vtsi_mat->vts_last_sector);
   B2N_32(vtsi_mat->vtsi_last_sector);
   B2N_32(vtsi_mat->vts_category);
@@ -404,12 +595,6 @@
   B2N_32(vtsi_mat->vtsm_vobu_admap);
   B2N_32(vtsi_mat->vts_c_adt);
   B2N_32(vtsi_mat->vts_vobu_admap);
-  B2N_16(vtsi_mat->vtsm_audio_attr.lang_code);
-  B2N_16(vtsi_mat->vtsm_subp_attr.lang_code);
-  for(i = 0; i < 8; i++)
-    B2N_16(vtsi_mat->vts_audio_attr[i].lang_code);
-  for(i = 0; i < 32; i++)
-    B2N_16(vtsi_mat->vts_subp_attr[i].lang_code);
 
 
   CHECK_ZERO(vtsi_mat->zero_1);
@@ -462,6 +647,7 @@
     CHECK_ZERO(vtsi_mat->vts_subp_attr[i]);      
   
   for(i = 0; i < 8; i++) {
+    read_multichannel_ext(&vtsi_mat->vts_mu_audio_attr[i]);
     CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1);
     CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2);
     CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3);
@@ -586,11 +772,7 @@
     return 0;
 
   for(i = 0; i < nr; i++) {
-    B2N_32(cell_playback[i].first_sector);
-    B2N_32(cell_playback[i].first_ilvu_end_sector);
-    B2N_32(cell_playback[i].last_vobu_start_sector);
-    B2N_32(cell_playback[i].last_sector);
-    
+    read_cell_playback(&cell_playback[i]);
     /* Changed < to <= because this was false in the movie 'Pi'. */
     CHECK_VALUE(cell_playback[i].last_vobu_start_sector <= 
            cell_playback[i].last_sector);
@@ -631,6 +813,7 @@
   if(!(DVDReadBytes(ifofile->file, pgc, PGC_SIZE)))
     return 0;
 
+  read_user_ops(&pgc->prohibited_ops);
   B2N_16(pgc->next_pgc_nr);
   B2N_16(pgc->prev_pgc_nr);
   B2N_16(pgc->goup_pgc_nr);
@@ -849,6 +1032,7 @@
   CHECK_VALUE((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length);
   
   for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
+    read_playback_type(&tt_srpt->title[i].pb_ty);
     CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 == 0);
     CHECK_VALUE(tt_srpt->title[i].nr_of_angles != 0);
     CHECK_VALUE(tt_srpt->title[i].nr_of_angles < 10);
@@ -1508,7 +1692,7 @@
   unsigned int i;
   int info_length;
 
-  if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
+  if(!DVDFileSeekForce_(ifofile->file, sector * DVD_BLOCK_LEN, sector))
     return 0;
 
   if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE)))
@@ -1627,8 +1811,7 @@
   for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
     memcpy(&pgcit->pgci_srp[i], ptr, PGCI_SRP_SIZE);
     ptr += PGCI_SRP_SIZE;
-    B2N_16(pgcit->pgci_srp[i].ptl_id_mask);
-    B2N_32(pgcit->pgci_srp[i].pgc_start_byte);
+    read_pgci_srp(&pgcit->pgci_srp[i]);
     CHECK_VALUE(pgcit->pgci_srp[i].unknown1 == 0);
   }
   free(data);
@@ -1841,14 +2024,16 @@
   if(!(DVDReadBytes(ifofile->file, vts_attributes, sizeof(vts_attributes_t))))
     return 0;
 
+  read_video_attr(&vts_attributes->vtsm_vobs_attr);
+  read_video_attr(&vts_attributes->vtstt_vobs_video_attr);
+  read_audio_attr(&vts_attributes->vtsm_audio_attr);
+  for(i=0; i<8; i++)
+    read_audio_attr(&vts_attributes->vtstt_audio_attr[i]);
+  read_subp_attr(&vts_attributes->vtsm_subp_attr);
+  for(i=0; i<32; i++)
+    read_subp_attr(&vts_attributes->vtstt_subp_attr[i]);
   B2N_32(vts_attributes->last_byte);
   B2N_32(vts_attributes->vts_cat);
-  B2N_16(vts_attributes->vtsm_audio_attr.lang_code);
-  B2N_16(vts_attributes->vtsm_subp_attr.lang_code);
-  for(i = 0; i < 8; i++)
-    B2N_16(vts_attributes->vtstt_audio_attr[i].lang_code);
-  for(i = 0; i < 32; i++)
-    B2N_16(vts_attributes->vtstt_subp_attr[i].lang_code);
   
   CHECK_ZERO(vts_attributes->zero_1);
   CHECK_ZERO(vts_attributes->zero_2);
Index: src/dvdread/dvd_udf.c
===================================================================
--- src/dvdread/dvd_udf.c	(revision 1001)
+++ src/dvdread/dvd_udf.c	(revision 1043)
@@ -56,7 +56,6 @@
   size_t count = block_count;
   
   while(count > 0) {
-    
     ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted);
         
     if(ret <= 0) {
@@ -145,18 +144,17 @@
 void FreeUDFCache(void *cache)
 {
   struct udf_cache *c = (struct udf_cache *)cache;
-  if(c == NULL) {
+  if(c == NULL)
     return;
-  }
+
   if(c->lbs) {
     int n;
     for(n = 0; n < c->lb_num; n++)
       free(c->lbs[n].data_base);
     free(c->lbs);
   }
-  if(c->maps) {
+  if(c->maps)
     free(c->maps);
-  }
   free(c);
 }
 
@@ -167,15 +165,13 @@
   int n;
   struct udf_cache *c;
 
-  if(DVDUDFCacheLevel(device, -1) <= 0) {
+  if(DVDUDFCacheLevel(device, -1) <= 0)
     return 0;
-  }
   
   c = (struct udf_cache *)GetUDFCacheHandle(device);
   
-  if(c == NULL) {
+  if(c == NULL)
     return 0;
-  }
   
   switch(type) {
   case AVDPCache:
@@ -230,19 +226,18 @@
 {
   int n;
   struct udf_cache *c;
+  void *tmp;
 
-  if(DVDUDFCacheLevel(device, -1) <= 0) {
+  if(DVDUDFCacheLevel(device, -1) <= 0)
     return 0;
-  }
 
   c = (struct udf_cache *)GetUDFCacheHandle(device);
   
   if(c == NULL) {
     c = calloc(1, sizeof(struct udf_cache));    
     /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */
-    if(c == NULL) {
+    if(c == NULL)
       return 0;
-    }
     SetUDFCacheHandle(device, c);
   }
   
@@ -275,16 +270,18 @@
       }
     }
     c->lb_num++;
-    c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf));
+    tmp = realloc(c->lbs, c->lb_num * sizeof(struct lbudf));
     /*
     fprintf(stderr, "realloc lb: %d * %d = %d\n",
 	    c->lb_num, sizeof(struct lbudf),
 	    c->lb_num * sizeof(struct lbudf));
     */
-    if(c->lbs == NULL) {
+    if(tmp == NULL) {
+      if(c->lbs) free(c->lbs);
       c->lb_num = 0;
       return 0;
     }
+    c->lbs = tmp;
     c->lbs[n].data_base = ((uint8_t **)data)[0];
     c->lbs[n].data = ((uint8_t **)data)[1];
     c->lbs[n].lb = nr;
@@ -299,16 +296,18 @@
       }
     }
     c->map_num++;
-    c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap));
+    tmp = realloc(c->maps, c->map_num * sizeof(struct icbmap));
     /*
     fprintf(stderr, "realloc maps: %d * %d = %d\n",
 	    c->map_num, sizeof(struct icbmap),
 	    c->map_num * sizeof(struct icbmap));
     */
-    if(c->maps == NULL) {
+    if(tmp == NULL) {
+      if(c->maps) free(c->maps);
       c->map_num = 0;
       return 0;
     }
+    c->maps = tmp;
     c->maps[n] = *(struct icbmap *)data;
     c->maps[n].lbn = nr;
     break;
@@ -501,20 +500,19 @@
     tmpmap.lbn = lbnum;
     if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
       *FileType = tmpmap.filetype;
-      *File = tmpmap.file;
+      memcpy(File, &tmpmap.file, sizeof(tmpmap.file));
       return 1;
     }
 
     do {
-        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
+        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 )
             TagID = 0;
-        } else {
+        else
             UDFDescriptor( LogBlock, &TagID );
-        }
 
         if( TagID == 261 ) {
             UDFFileEntry( LogBlock, FileType, partition, File );
-           tmpmap.file = *File;
+           memcpy(&tmpmap.file, File, sizeof(tmpmap.file));
            tmpmap.filetype = *FileType;
            SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
             return 1;
@@ -556,18 +554,18 @@
       
       if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
 	dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
-	if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) {
+          if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL)
 	  return 0;
-	}
+
 	cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048);
 	if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) {
 	  free(cached_dir_base);
+            cached_dir_base = NULL;
 	  cached_dir = NULL;
 	}
 	/*
 	if(cached_dir) {
-	  fprintf(stderr, "malloc dir: %d\n",
-		  dir_lba * DVD_VIDEO_LB_LEN);
+            fprintf(stderr, "malloc dir: %d\n",  dir_lba * DVD_VIDEO_LB_LEN);
 	}
 	*/
 	{
@@ -576,21 +574,18 @@
 	  data[1] = cached_dir;
 	  SetUDFCache(device, LBUDFCache, lbnum, data);
 	}
-      } else {
+      } else
 	in_cache = 1;
-      }
       
-      if(cached_dir == NULL) {
+      if(cached_dir == NULL)
 	return 0;
-      }
       
       p = 0;
       
       while( p < Dir.Length ) {
         UDFDescriptor( &cached_dir[ p ], &TagID );
         if( TagID == 257 ) {
-	  p += UDFFileIdentifier( &cached_dir[ p ], &filechar,
-				  filename, &tmpICB );
+          p += UDFFileIdentifier( &cached_dir[ p ], &filechar, filename, &tmpICB );
 	  if(cache_file_info && !in_cache) {
 	    uint8_t tmpFiletype;
 	    struct AD tmpFile;
@@ -598,10 +593,8 @@
 	    if( !strcasecmp( FileName, filename ) ) {
 	      *FileICB = tmpICB;
 	      found = 1;
-	      
 	    }
-	    UDFMapICB(device, tmpICB, &tmpFiletype,
-		      partition, &tmpFile);
+            UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile);
 	  } else {
 	    if( !strcasecmp( FileName, filename ) ) {
 	      *FileICB = tmpICB;
@@ -609,21 +602,18 @@
 	    }
 	  }
         } else {
-	  if(cache_file_info && (!in_cache) && found) {
+          if(cache_file_info && (!in_cache) && found)
 	    return 1;
-	  }
 	  return 0;
         }
       }
-      if(cache_file_info && (!in_cache) && found) {
+      if(cache_file_info && (!in_cache) && found)
 	return 1;
-      }
       return 0;
     }
 
-    if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
+    if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 )
         return 0;
-    }
 
     p = 0;
     while( p < Dir.Length ) {
@@ -642,10 +632,9 @@
             if( !strcasecmp( FileName, filename ) ) {
                 return 1;
             }
-        } else {
+      } else
             return 0;
         }
-    }
 
     return 0;
 }
@@ -662,9 +651,8 @@
   int terminate;
   struct avdp_t; 
   
-  if(GetUDFCache(device, AVDPCache, 0, avdp)) {
+  if(GetUDFCache(device, AVDPCache, 0, avdp))
     return 1;
-  }
 
   /* Find Anchor */
   lastsector = 0;
@@ -682,27 +670,25 @@
       if( terminate ) return 0; /* Final try failed */
       
       if( lastsector ) {
-	
-	/* We already found the last sector.  Try #3, alternative
+        /*
+         * We already found the last sector.  Try #3, alternative
 	 * backup anchor.  If that fails, don't try again.
 	 */
 	lbnum = lastsector;
 	terminate = 1;
       } else {
 	/* TODO: Find last sector of the disc (this is optional). */
-	if( lastsector ) {
+        if( lastsector )
 	  /* Try #2, backup anchor */
 	  lbnum = lastsector - 256;
-	} else {
+        else
 	  /* Unable to find last sector */
 	  return 0;
 	}
-      }
-    } else {
+    } else
       /* It's an anchor! We can leave */
       break;
     }
-  }
   /* Main volume descriptor */
   UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
   avdp->mvds.location = MVDS_location;
@@ -733,10 +719,8 @@
     int i, volvalid;
     struct avdp_t avdp;
 
-    
-    if(!UDFGetAVDP(device, &avdp)) {
+    if(!UDFGetAVDP(device, &avdp))
       return 0;
-    }
 
     /* Main volume descriptor */
     MVDS_location = avdp.mvds.location;
@@ -751,11 +735,10 @@
         lbnum = MVDS_location;
         do {
 
-            if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
+            if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 )
                 TagID = 0;
-            } else {
+            else
                 UDFDescriptor( LogBlock, &TagID );
-            }
 
             if( ( TagID == 5 ) && ( !part->valid ) ) {
                 /* Partition Descriptor */
@@ -766,10 +749,9 @@
                 /* Logical Volume Descriptor */
                 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) {  
                     /* TODO: sector size wrong! */
-                } else {
+                } else
                     volvalid = 1;
                 }
-            }
 
         } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
                  / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
@@ -801,9 +783,8 @@
 
     *filesize = 0;
     tokenline[0] = '\0';
-    strcat( tokenline, filename );
+    strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1);
 
-    
     if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
         GetUDFCache(device, RootICBCache, 0, &RootICB))) {
       /* Find partition, 0 is the standard location for DVD Video.*/
@@ -813,16 +794,14 @@
       /* Find root dir ICB */
       lbnum = partition.Start;
       do {
-        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
+        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 )
             TagID = 0;
-        } else {
+        else
             UDFDescriptor( LogBlock, &TagID );
-        }
 
         /* File Set Descriptor */
-        if( TagID == 256 ) {  /* File Set Descriptor */
+        if( TagID == 256 )  /* File Set Descriptor */
             UDFLongAD( &LogBlock[ 400 ], &RootICB );
-        }
     } while( ( lbnum < partition.Start + partition.Length )
              && ( TagID != 8 ) && ( TagID != 256 ) );
 
@@ -840,26 +819,20 @@
       int cache_file_info = 0;
       /* Tokenize filepath */
       token = strtok(tokenline, "/");
-      
       while( token != NULL ) {
-       
         if( !UDFScanDir( device, File, token, &partition, &ICB,
-                        cache_file_info)) {
+                        cache_file_info))
          return 0;
-       }
-        if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
+        if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) )
          return 0;
-       }
-       if(!strcmp(token, "VIDEO_TS")) {
+       if(!strcmp(token, "VIDEO_TS"))
          cache_file_info = 1;
-       }
         token = strtok( NULL, "/" );
       }
     } 
 
     /* Sanity check. */
     if( File.Partition != 0 ) return 0;
-   
     *filesize = File.Length;
     /* Hack to not return partition.Start for empty files. */
     if( !File.Location )
@@ -889,34 +862,27 @@
   lastsector = 0;
   lbnum = 256;   /* Try #1, prime anchor */
   terminate = 0;
-  if(bufsize < DVD_VIDEO_LB_LEN) {
+  if(bufsize < DVD_VIDEO_LB_LEN)
     return 0;
-  }
   
-  if(!UDFGetAVDP(device, &avdp)) {
+  if(!UDFGetAVDP(device, &avdp))
     return 0;
-  }
 
   /* Main volume descriptor */
   MVDS_location = avdp.mvds.location;
   MVDS_length = avdp.mvds.length;
-  
   i = 1;
   do {
     /* Find  Descriptor */
     lbnum = MVDS_location;
     do {
-      
-      if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) {
+      if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 )
 	TagID = 0;
-      } else {
+      else
 	UDFDescriptor( descriptor, &TagID );
-      }
-      
-      if( (TagID == id) && ( !desc_found ) ) {
+      if( (TagID == id) && ( !desc_found ) )
 	/* Descriptor */
 	desc_found = 1;
-      }
     } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
 	       / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
 	     && ( !desc_found) );
@@ -936,19 +902,15 @@
 {
   uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048];
   uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048);
-  
-  if(GetUDFCache(device, PVDCache, 0, pvd)) {
+  if(GetUDFCache(device, PVDCache, 0, pvd))
     return 1;
-  }
 
-  if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) {
+  if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf)))
     return 0;
-  }
   
   memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
   memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
   SetUDFCache(device, PVDCache, 0, pvd);
-  
   return 1;
 }
 
@@ -965,20 +927,16 @@
   unsigned int volid_len;
 
   /* get primary volume descriptor */
-  if(!UDFGetPVD(device, &pvd)) {
+  if(!UDFGetPVD(device, &pvd))
     return 0;
-  }
 
   volid_len = pvd.VolumeIdentifier[31];
-  if(volid_len > 31) {
+  if(volid_len > 31)
     /* this field is only 32 bytes something is wrong */
     volid_len = 31;
-  }
-  if(volid_size > volid_len) {
+  if(volid_size > volid_len)
     volid_size = volid_len;
-  }
   Unicodedecode(pvd.VolumeIdentifier, volid_size, volid);
-  
   return volid_len;
 }
 
@@ -997,16 +955,13 @@
   struct pvd_t pvd;
 
   /* get primary volume descriptor */
-  if(!UDFGetPVD(device, &pvd)) {
+  if(!UDFGetPVD(device, &pvd))
     return 0;
-  }
 
 
-  if(volsetid_size > 128) {
+  if(volsetid_size > 128)
     volsetid_size = 128;
-  }
   
   memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size);
-  
   return 128;
 }
Index: src/dvdread/nav_read.c
===================================================================
--- src/dvdread/nav_read.c	(revision 1001)
+++ src/dvdread/nav_read.c	(revision 1043)
@@ -27,104 +27,11 @@
 #include "nav_types.h"
 #include "nav_read.h"
 #include "dvdread_internal.h"
+#include "bitreader.h"
 
-typedef struct {
-  uint8_t *start;
-  uint32_t byte_position;
-  uint32_t bit_position;
-  uint8_t byte;
-} getbits_state_t;
+#define getbits_init dvdread_getbits_init
+#define getbits dvdread_getbits
 
-static int getbits_init(getbits_state_t *state, uint8_t *start) {
-  if ((state == NULL) || (start == NULL)) return 0;
-  state->start = start;
-  state->bit_position = 0;
-  state->byte_position = 0;
-  state->byte = start[0];
-  return 1;
-}
-
-/* Non-optimized getbits. */
-/* This can easily be optimized for particular platforms. */
-static uint32_t getbits(getbits_state_t *state, uint32_t number_of_bits) {
-  uint32_t result=0;
-  uint8_t byte=0;
-  if (number_of_bits > 32) {
-    printf("Number of bits > 32 in getbits\n");
-    abort();
-  }
-
-  if ((state->bit_position) > 0) {  /* Last getbits left us in the middle of a byte. */
-    if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */
-      byte = state->byte;
-      byte = byte >> (state->bit_position);
-      result = byte;
-      number_of_bits -= (8-state->bit_position);
-      state->bit_position = 0;
-      state->byte_position++;
-      state->byte = state->start[state->byte_position];
-    } else {
-      byte=state->byte;
-      state->byte = state->byte << number_of_bits;
-      byte = byte >> (8 - number_of_bits);
-      result = byte;
-      state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */
-      if (state->bit_position == 8) {
-        state->bit_position = 0;
-        state->byte_position++;
-        state->byte = state->start[state->byte_position];
-      }
-      number_of_bits = 0;
-    }
-  }
-  if ((state->bit_position) == 0) {
-    while (number_of_bits > 7) {
-      result = (result << 8) + state->byte;
-      state->byte_position++;
-      state->byte = state->start[state->byte_position];
-      number_of_bits -= 8;
-    }
-    if (number_of_bits > 0) { /* number_of_bits < 8 */
-      byte = state->byte;
-      state->byte = state->byte << number_of_bits;
-      state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */
-      byte = byte >> (8 - number_of_bits);
-      result = (result << number_of_bits) + byte;
-      number_of_bits = 0;
-    }
-  }
-
-  return result;
-}
-
-#if 0  /* TODO: optimized versions not yet used */
-
-/* WARNING: This function can only be used on a byte boundary.
-            No checks are made that we are in fact on a byte boundary.
- */
-static uint16_t get16bits(getbits_state_t *state) {
-  uint16_t result;
-  state->byte_position++;
-  result = (state->byte << 8) + state->start[state->byte_position++];
-  state->byte = state->start[state->byte_position];
-  return result;
-}
-
-/* WARNING: This function can only be used on a byte boundary.
-            No checks are made that we are in fact on a byte boundary.
- */
-static uint32_t get32bits(getbits_state_t *state) {
-  uint32_t result;
-  state->byte_position++;
-  result = (state->byte << 8) + state->start[state->byte_position++];
-  result = (result << 8) + state->start[state->byte_position++];
-  result = (result << 8) + state->start[state->byte_position++];
-  state->byte = state->start[state->byte_position];
-  return result;
-}
-
-#endif
-
 void navRead_PCI(pci_t *pci, unsigned char *buffer) {
   int32_t i, j;
   getbits_state_t state;
Index: src/dvdread/Makefile.am
===================================================================
--- src/dvdread/Makefile.am	(revision 1001)
+++ src/dvdread/Makefile.am	(revision 1043)
@@ -7,8 +7,8 @@
 lib_LTLIBRARIES = libdvdread.la
 
 libdvdread_la_SOURCES = dvd_reader.c nav_read.c ifo_read.c \
-	dvd_input.c dvd_udf.c md5.c nav_print.c ifo_print.c \
-	bswap.h dvd_input.h dvdread_internal.h dvd_udf.h md5.h
+	dvd_input.c dvd_udf.c md5.c nav_print.c ifo_print.c bitreader.c \
+	bswap.h dvd_input.h dvdread_internal.h dvd_udf.h md5.h bitreader.h
 
 libdvdread_la_LIBADD = $(DYNAMIC_LD_LIBS)
 
@@ -16,4 +16,4 @@
 	-export-symbols-regex "(^dvd.*|^nav.*|^ifo.*|^DVD.*|^UDF.*)"
 
 include_HEADERS = dvd_reader.h nav_read.h ifo_read.h \
-	nav_print.h ifo_print.h ifo_types.h nav_types.h dvd_udf.h
+	nav_print.h ifo_print.h ifo_types.h nav_types.h dvd_udf.h bitreader.h
Index: src/dvdread/ifo_print.c
===================================================================
--- src/dvdread/ifo_print.c	(revision 1001)
+++ src/dvdread/ifo_print.c	(revision 1043)
@@ -25,7 +25,6 @@
 #include <ctype.h>
 #include <assert.h>
 
-#include "config.h" // Needed for WORDS_BIGENDIAN
 #include "ifo_types.h"
 #include "ifo_read.h"
 #include "ifo_print.h"
Index: src/dvdread/dvd_input.c
===================================================================
--- src/dvdread/dvd_input.c	(revision 1001)
+++ src/dvdread/dvd_input.c	(revision 1043)
@@ -341,7 +341,7 @@
     fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
     */
     fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
-	    *dvdcss_version);
+	    dvdcss_version ? *dvdcss_version : "");
     
     /* libdvdcss wrapper functions */
     dvdinput_open  = css_open;
Index: misc/dvdread-config.sh
===================================================================
--- misc/dvdread-config.sh	(revision 0)
+++ misc/dvdread-config.sh	(revision 1043)
@@ -0,0 +1,56 @@
+dvdreadlib="-ldvdread"
+
+usage()
+{
+	cat <<EOF
+Usage: dvdread-config [OPTIONS] [LIBRARIES]
+Options:
+	[--prefix[=DIR]]
+	[--version]
+        [--libs]
+	[--cflags]
+EOF
+	exit $1
+}
+
+if test $# -eq 0; then
+	usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --version)
+      echo $version
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "$echo_prefix" = "yes"; then
+	echo $prefix
+fi
+
+if test "$echo_cflags" = "yes"; then
+      echo -I$prefix/include $extracflags
+fi
+
+if test "$echo_libs" = "yes"; then
+      echo -L$libdir $dvdreadlib
+fi      
Index: version.sh
===================================================================
--- version.sh	(revision 1001)
+++ version.sh	(revision 1043)
@@ -1,11 +1,15 @@
 #!/bin/sh
 
 svn_revision=`cd "$1" && LC_ALL=C svn info 2> /dev/null | grep Revision | cut -d' ' -f2`
-test $svn_revision || svn_revision=`cd "$1" && grep revision .svn/entries | \
+test $svn_revision || svn_revision=`cd "$1" && grep revision .svn/entries 2>/dev/null | \
                                     cut -d '"' -f2 2> /dev/null`
 test $svn_revision || svn_revision=UNKNOWN
 
+if test "$svn_revision" = UNKNOWN && test -n "$2"; then
+    NEW_REVISION="#define VERSION \"$2\""
+else
 NEW_REVISION="#define VERSION \"SVN-r$svn_revision\""
+fi
 OLD_REVISION=`cat version.h 2> /dev/null`
 
 # Update version.h only on revision changes to avoid spurious rebuilds
Index: Makefile
===================================================================
--- Makefile	(revision 1001)
+++ Makefile	(revision 1043)
@@ -35,9 +35,10 @@
 	src/dvdread/nav_print.h \
 	src/dvdread/nav_read.h \
 	src/dvdread/dvd_udf.h \
-	src/dvdread/nav_types.h
+	src/dvdread/nav_types.h \
+	src/dvdread/bitreader.h
 DVDREAD_SRCS = dvd_input.c dvd_reader.c dvd_udf.c ifo_print.c ifo_read.c \
-	md5.c nav_print.c nav_read.c
+	md5.c nav_print.c nav_read.c bitreader.c
 CFLAGS += -I$(SRC_PATH)/src/dvdread
 else
 CFLAGS += -I$(DVDREAD_DIR)
@@ -60,13 +61,13 @@
 BUILDDEPS = Makefile config.mak
 
 ifeq ($(BUILD_SHARED),yes)
-all:	$(SHLIB) $(MINI_SHLIB) $(DVDREAD_SHLIB) dvdnav-config
-install: $(SHLIB) $(DVDREAD_SHLIB) install-shared install-dvdnav-config
+all:	$(SHLIB) $(MINI_SHLIB) $(DVDREAD_SHLIB) dvdnav-config dvdread-config
+install: $(SHLIB) $(DVDREAD_SHLIB) install-shared install-dvdnav-config install-dvdread-config
 endif
 
 ifeq ($(BUILD_STATIC),yes)
-all:	$(LIB) $(DVDREAD_LIB) dvdnav-config
-install: $(LIB) $(DVDREAD_LIB) install-static install-dvdnav-config
+all:	$(LIB) $(DVDREAD_LIB) dvdnav-config dvdread-config
+install: $(LIB) $(DVDREAD_LIB) install-static install-dvdnav-config install-dvdread-config
 endif
 
 install: install-headers
@@ -79,9 +80,11 @@
 endif
 
 version.h:
-	sh $(SRC_PATH)/version.sh $(SRC_PATH)
+	sh $(SRC_PATH)/version.sh $(SRC_PATH) "$(SHLIB_VERSION)"
 
+$(SRCS) $(DVDREAD_SRCS): version.h
 
+
 # General targets
 
 $(.OBJDIR):
@@ -188,7 +191,19 @@
 	install -d $(DESTDIR)$(PREFIX)/bin
 	install -m 0755 $(.OBJDIR)/dvdnav-config $(DESTDIR)$(PREFIX)/bin/dvdnav-config
 
+dvdread-config: $(.OBJDIR)
+	@echo '#!/bin/sh' > $(.OBJDIR)/dvdread-config
+	@echo 'prefix='$(PREFIX) >> $(.OBJDIR)/dvdread-config
+	@echo 'libdir='$(shlibdir) >> $(.OBJDIR)/dvdread-config
+	@echo 'version='$(SHLIB_VERSION) >> $(.OBJDIR)/dvdread-config
+	@echo >> $(.OBJDIR)/dvdread-config
+	cat $(SRC_PATH_BARE)/misc/dvdread-config.sh >> $(.OBJDIR)/dvdread-config
+	chmod 0755 $(.OBJDIR)/dvdread-config
 
+install-dvdread-config: dvdread-config
+	install -d $(DESTDIR)$(PREFIX)/bin
+	install -m 0755 $(.OBJDIR)/dvdread-config $(DESTDIR)$(PREFIX)/bin/dvdread-config
+
 vpath %.so ${.OBJDIR}
 vpath %.o ${.OBJDIR}
 vpath ${LIB} ${.OBJDIR}
Index: examples/menus.c
===================================================================
--- examples/menus.c	(revision 1001)
+++ examples/menus.c	(revision 1043)
@@ -215,7 +215,6 @@
        * engine of the player so that it knows the dimensions of the button areas. */
       {
 	pci_t *pci;
-	dsi_t *dsi;
 	
 	/* Applications with fifos should not use these functions to retrieve NAV packets,
 	 * they should implement their own NAV handling, because the packet you get from these
@@ -223,7 +222,7 @@
 	 * Applications with fifos should therefore pass the NAV packet through the fifo
 	 * and decoding pipeline just like any other data. */
 	pci = dvdnav_get_current_nav_pci(dvdnav);
-	dsi = dvdnav_get_current_nav_dsi(dvdnav);
+	dvdnav_get_current_nav_dsi(dvdnav);
 	
 	if(pci->hli.hl_gi.btn_ns > 0) {
 	  int button;


Index: libdvdnav.spec
===================================================================
RCS file: /cvs/pkgs/rpms/libdvdnav/F-9/libdvdnav.spec,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- libdvdnav.spec	13 Apr 2008 15:32:17 -0000	1.8
+++ libdvdnav.spec	26 Jul 2008 18:42:29 -0000	1.9
@@ -1,11 +1,12 @@
 Name:           libdvdnav
 Version:        4.1.2
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        A library for reading DVD video discs based on Ogle code
 
 Group:          System Environment/Libraries
 License:        GPLv2+
 Source:         http://www.mplayerhq.hu/MPlayer/releases/dvdnav/libdvdnav-%{version}.tar.gz
+Patch0:         %{name}-r1001-r1043.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires:  doxygen
@@ -45,6 +46,7 @@
 
 %prep
 %setup -q
+%patch0 -p0
 
 %build
 ./configure2 \
@@ -56,9 +58,7 @@
  --prefix=%{_prefix} \
  --shlibdir=%{_libdir} \
 
-#parallel make fails
-#make %{?_smp_mflags}
-make
+make %{?_smp_mflags}
 pushd doc
 doxygen doxy.conf
 popd
@@ -101,10 +101,15 @@
 
 %files -n libdvdread-devel
 %defattr(-,root,root,-)
+%{_bindir}/dvdnav-config
 %{_includedir}/dvdread
 %{_libdir}/libdvdread.so
 
 %changelog
+* Sat Jul 27 2008 Dominik Mierzejewski <rpm[AT]greysector.net> 4.1.2-2
+- pull selected fixes from SVN
+- re-enable parallel make
+
 * Sun Apr 13 2008 Dominik Mierzejewski <rpm[AT]greysector.net> 4.1.2-1
 - update to 4.1.2
 - drop obsolete patches (merged upstream)




More information about the fedora-extras-commits mailing list