patch genisoimage multi extent
[platform/upstream/cdrkit.git] / genisoimage / dvd_file.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)dvd_file.c       1.3 04/03/04 joerg */
14 /*
15  * DVD_VIDEO code
16  *  Copyright (c) 2002 Olaf Beck - olaf_sc@yahoo.com
17  *                      Jörg Schilling <schilling@fokus.gmd.de>
18  *                      (making the code portable)
19  */
20 /*
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU General Public License version 2
23  * as published by the Free Software Foundation.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License along with
31  * this program; see the file COPYING.  If not, write to the Free Software
32  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33  */
34
35 #ifdef DVD_VIDEO
36
37 #include <mconfig.h>
38 #include "genisoimage.h"
39 #include <schily.h>
40 #include "dvd_reader.h"
41 #include "dvd_file.h"
42 #include "ifo_read.h"
43
44 static  void    bsort(int sector[], int title[], int size);
45 static  void    uniq(int sector[], int title[], int title_sets_array[],
46                                                   int sector_sets_array[], int titles);
47 static  void    DVDFreeFileSetArrays(int *sector, int *title, 
48                                                                                                 int *title_sets_array, 
49                                                                                                 int *sector_sets_array);
50 void    DVDFreeFileSet(title_set_info_t *title_set_info);
51 title_set_info_t *DVDGetFileSet(char *dvd);
52 int     DVDGetFilePad(title_set_info_t *title_set_info, char *name);
53
54
55 static void
56 bsort(int sector[], int title[], int size)
57 {
58         int     temp_title;
59         int     temp_sector;
60         int     i;
61         int     j;
62
63   /* this is not bubble sort, this is primitive selection sort. Replace with
64    * bubble sort later, maybe bidirectional, aka Coctail Sort */
65         for (i = 0; i < size; i++) {
66                 for (j = 0; j < size; j++) {
67                         if (sector[i] < sector[j]) {
68                                 temp_sector = sector[i];
69                                 temp_title = title[i];
70                                 sector[i] = sector[j];
71                                 title[i] = title[j];
72                                 sector[j] = temp_sector;
73                                 title[j] = temp_title;
74                         }
75                 }
76         }
77 }
78
79
80 static void
81 uniq(int sector[], int title[], int title_sets_array[], 
82           int sector_sets_array[], int titles)
83 {
84         int     i;
85         int     j;
86
87
88         for (i = 0, j = 0; j < titles; ) {
89                 if (sector[j] != sector[j+1]) {
90                         title_sets_array[i]  = title[j];
91                         sector_sets_array[i] = sector[j];
92 #ifdef DEBUG
93                         fprintf(stderr, "Sector offset is %d\n", sector_sets_array[i]);
94 #endif
95                         i++;
96                         j++;
97                 } else {
98                         do {
99                                 if (j < titles)
100                                         j++;
101
102                         } while (sector[j] == sector[j+1]);
103
104                 }
105         }
106
107 }
108
109 static void
110 DVDFreeFileSetArrays(int *sector, int *title, int *title_sets_array, 
111                                                         int *sector_sets_array)
112 {
113         free(sector);
114         free(title);
115         free(title_sets_array);
116         free(sector_sets_array);
117 }
118
119 void
120 DVDFreeFileSet(title_set_info_t *title_set_info)
121 {
122         free(title_set_info->title_set);
123         free(title_set_info);
124 }
125
126 title_set_info_t *
127 DVDGetFileSet(char *dvd)
128 {
129         /*
130          * TODO  Fix close of files if
131          *      we error out
132          *      We also assume that all
133          *      DVD files are of valid
134          *      size i.e. file%2048 == 0
135          */
136
137         /* title interation */
138         int             title_sets;
139         int             titles;
140         int             counter;
141         int             i;
142
143         /* DVD file structures */
144         dvd_reader_t *  _dvd = NULL;
145
146         ifo_handle_t *  vmg_ifo = NULL;
147         ifo_handle_t *  vts_ifo = NULL;
148
149         dvd_file_t   *  vmg_vob_file = NULL;
150         dvd_file_t   *  vmg_ifo_file = NULL;
151
152         dvd_file_t   *  vts_ifo_file = NULL;
153         dvd_file_t   *  vts_menu_file = NULL;
154         dvd_file_t   *  vts_title_file = NULL;
155
156         /* The sizes it self of each file */
157         int             ifo;
158         int             bup;
159         int             menu_vob;
160         int             title_vob;
161
162         /* Arrays keeping the title - filset relationship */
163         int             * sector;
164         int             * title;
165         int             * title_sets_array;
166         int             * sector_sets_array;
167
168         /* DVD Video files */
169         struct stat     fileinfo;
170         char            temppoint[PATH_MAX + 1];
171
172         /* The Title Set Info struct*/
173         title_set_info_t * title_set_info;
174
175         /* Temporary mount point - to be used later */
176         char            mountpoint[PATH_MAX + 1];
177
178         strncpy(mountpoint, dvd, sizeof (mountpoint));
179         mountpoint[sizeof (mountpoint)-1] = '\0';
180
181
182         _dvd = DVDOpen(dvd);
183         if (!_dvd) {
184 #ifdef  USE_LIBSCHILY
185                 errmsgno(EX_BAD, "Can't open device '%s'\n", dvd);
186 #else
187                 fprintf(stderr, "Can't open device\n");
188 #endif
189                 return (0);
190         }
191         vmg_ifo = ifoOpen(_dvd, 0);
192         if (!vmg_ifo) {
193 #ifdef  USE_LIBSCHILY
194                 errmsgno(EX_BAD, "Can't open VMG info for '%s'.\n", dvd);
195 #else
196                 fprintf(stderr, "Can't open VMG info.\n");
197 #endif
198                 return (0);
199         }
200
201         /* Check mount point */
202
203         snprintf(temppoint, sizeof (temppoint),
204                                 "%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint);
205
206
207         if (stat(temppoint, &fileinfo) < 0) {
208                 /* If we can't stat the file, give up */
209 #ifdef  USE_LIBSCHILY
210                 errmsg("Can't stat %s\n", temppoint);
211 #else
212                 fprintf(stderr, "Can't stat %s\n", temppoint);
213                 perror("");
214 #endif
215                 return (0);
216         }
217
218
219
220         title_sets = vmg_ifo->vmgi_mat->vmg_nr_of_title_sets;
221         titles = vmg_ifo->tt_srpt->nr_of_srpts;
222
223         sector = e_malloc(titles * sizeof (int));
224         memset(sector, 0, titles * sizeof (int));
225         title = e_malloc(titles * sizeof (int));
226         title_sets_array = e_malloc(title_sets * sizeof (int));
227         sector_sets_array = e_malloc(title_sets * sizeof (int));
228         title_set_info = (title_set_info_t *)e_malloc(sizeof (title_set_info_t));
229         title_set_info->title_set = (title_set_t *)e_malloc((title_sets + 1) *
230                                                         sizeof (title_set_t));
231
232         title_set_info->num_titles = title_sets;
233
234
235         /* Fill and sort the arrays for titles*/
236
237         if (titles >= 1) {
238                 for (counter = 0; counter < titles; counter++) {
239                         sector[counter] = vmg_ifo->tt_srpt->title[counter].title_set_sector;
240                         title[counter]  = counter + 1;
241                 }
242         }
243
244         /* Yes, we should probably do a better sort than B - but what the heck*/
245         bsort(sector, title, titles);
246
247
248         /*
249          * Since title sets and titles are not the same we will need to sort
250          * out "bogus" titles
251          */
252
253         uniq(sector, title, title_sets_array, sector_sets_array, titles);
254
255
256         /* Open VIDEO_TS.VOB is present */
257
258         vmg_vob_file = DVDOpenFile(_dvd, 0, DVD_READ_MENU_VOBS);
259
260         /* Check VIDEO_TS title set */
261
262         vmg_ifo_file = DVDOpenFile(_dvd, 0, DVD_READ_INFO_FILE);
263
264         if ((vmg_vob_file == 0) && vmg_ifo->vmgi_mat->vmg_last_sector + 1
265                         < 2 * DVDFileSize(vmg_ifo_file)) {
266 #ifdef  USE_LIBSCHILY
267                 errmsgno(EX_BAD, "IFO is not of correct size aborting\n");
268 #else
269                 fprintf(stderr, "IFO is not of correct size aborting\n");
270 #endif
271                 DVDFreeFileSetArrays(sector, title, title_sets_array,
272                                         sector_sets_array);
273                 DVDFreeFileSet(title_set_info);
274                 return (0);
275         } else if ((vmg_vob_file != 0) && (vmg_ifo->vmgi_mat->vmg_last_sector
276                     + 1  < 2 * DVDFileSize(vmg_ifo_file) +
277                     DVDFileSize(vmg_vob_file))) {
278 #ifdef  USE_LIBSCHILY
279                 errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size");
280 #else
281                 fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size");
282 #endif
283                 DVDFreeFileSetArrays(sector, title, title_sets_array,
284                                         sector_sets_array);
285                 DVDFreeFileSet(title_set_info);
286                 return (0);
287         }
288
289         /* Find the actuall right size of VIDEO_TS.IFO */
290         if (vmg_vob_file == 0) {
291                 if (vmg_ifo->vmgi_mat->vmg_last_sector + 1 > 2
292                                 *  DVDFileSize(vmg_ifo_file)) {
293                         ifo = vmg_ifo->vmgi_mat->vmg_last_sector
294                                 - DVDFileSize(vmg_ifo_file) + 1;
295                 } else {
296                         ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1;
297                 }
298         } else {
299                 if (vmg_ifo->vmgi_mat->vmgi_last_sector + 1
300                                 < vmg_ifo->vmgi_mat->vmgm_vobs) {
301                         ifo = vmg_ifo->vmgi_mat->vmgm_vobs;
302                 } else {
303                         ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1;
304                 }
305         }
306
307         title_set_info->title_set[0].size_ifo = ifo * 2048;
308         title_set_info->title_set[0].realsize_ifo = fileinfo.st_size;
309         title_set_info->title_set[0].pad_ifo = ifo - DVDFileSize(vmg_ifo_file);
310
311         /* Find the actuall right size of VIDEO_TS.VOB */
312         if (vmg_vob_file != 0) {
313                 if (ifo + DVDFileSize(vmg_ifo_file) +
314                     DVDFileSize(vmg_vob_file) - 1 <
315                     vmg_ifo->vmgi_mat->vmg_last_sector) {
316                                 menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector -
317                                                 ifo - DVDFileSize(vmg_ifo_file) + 1;
318                 } else {
319                         menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector
320                         - ifo - DVDFileSize(vmg_ifo_file) + 1;
321                 }
322
323                 snprintf(temppoint, sizeof (temppoint),
324                                 "%s/VIDEO_TS/VIDEO_TS.VOB", mountpoint);
325                 if (stat(temppoint, &fileinfo) < 0) {
326 #ifdef  USE_LIBSCHILY
327                         errmsg("calc: Can't stat %s\n", temppoint);
328 #else
329                         fprintf(stderr, "calc: Can't stat %s\n", temppoint);
330                         perror("");
331 #endif
332                         DVDFreeFileSetArrays(sector, title, title_sets_array,
333                                                 sector_sets_array);
334                         DVDFreeFileSet(title_set_info);
335                         return (0);
336                 }
337
338                 title_set_info->title_set[0].realsize_menu = fileinfo.st_size;
339                 title_set_info->title_set[0].pad_menu = menu_vob -
340                                                 DVDFileSize(vmg_vob_file);
341                 title_set_info->title_set[0].size_menu = menu_vob * 2048;
342                 DVDCloseFile(vmg_vob_file);
343         } else {
344                 title_set_info->title_set[0].size_menu = 0;
345                 title_set_info->title_set[0].realsize_menu = 0;
346                 title_set_info->title_set[0].pad_menu = 0;
347                 menu_vob = 0;
348         }
349
350
351         /* Finding the actuall right size of VIDEO_TS.BUP */
352         if (title_sets >= 1) {
353                 bup = sector_sets_array[0] - menu_vob - ifo;
354         } else {
355                 /* Just in case we burn a DVD-Video without any title_sets */
356                 bup = vmg_ifo->vmgi_mat->vmg_last_sector + 1 - menu_vob - ifo;
357         }
358
359         /* Never trust the BUP file - use a copy of the IFO */
360         snprintf(temppoint, sizeof (temppoint),
361                                 "%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint);
362
363         if (stat(temppoint, &fileinfo) < 0) {
364 #ifdef  USE_LIBSCHILY
365                 errmsg("calc: Can't stat %s\n", temppoint);
366 #else
367                 fprintf(stderr, "calc: Can't stat %s\n", temppoint);
368                 perror("");
369 #endif
370                 DVDFreeFileSetArrays(sector, title, title_sets_array,
371                                         sector_sets_array);
372                 DVDFreeFileSet(title_set_info);
373                 return (0);
374         }
375
376         title_set_info->title_set[0].realsize_bup = fileinfo.st_size;
377         title_set_info->title_set[0].size_bup = bup * 2048;
378         title_set_info->title_set[0].pad_bup = bup - DVDFileSize(vmg_ifo_file);
379
380         /* Take care of the titles which we don't have in VMG */
381
382         title_set_info->title_set[0].number_of_vob_files = 0;
383         title_set_info->title_set[0].realsize_vob[0] = 0;
384         title_set_info->title_set[0].pad_title = 0;
385
386         DVDCloseFile(vmg_ifo_file);
387
388         if (title_sets >= 1) {
389                 for (counter = 0; counter < title_sets; counter++) {
390
391                         vts_ifo = ifoOpen(_dvd, counter + 1);
392
393                         if (!vts_ifo) {
394 #ifdef  USE_LIBSCHILY
395                                 errmsgno(EX_BAD, "Can't open VTS info.\n");
396 #else
397                                 fprintf(stderr, "Can't open VTS info.\n");
398 #endif
399                                 DVDFreeFileSetArrays(sector, title,
400                                         title_sets_array, sector_sets_array);
401                                 DVDFreeFileSet(title_set_info);
402                                 return (0);
403                         }
404
405                         snprintf(temppoint, sizeof (temppoint),
406                                 "%s/VIDEO_TS/VTS_%02i_0.IFO",
407                                 mountpoint, counter + 1);
408
409                         if (stat(temppoint, &fileinfo) < 0) {
410 #ifdef  USE_LIBSCHILY
411                                 errmsg("calc: Can't stat %s\n", temppoint);
412 #else
413                                 fprintf(stderr, "calc: Can't stat %s\n",
414                                         temppoint);
415                                 perror("");
416 #endif
417                                 DVDFreeFileSetArrays(sector, title,
418                                         title_sets_array, sector_sets_array);
419                                 DVDFreeFileSet(title_set_info);
420                                 return (0);
421                         }
422
423
424                         /* Test if VTS_XX_0.VOB is present */
425
426                         vts_menu_file = DVDOpenFile(_dvd, counter + 1,
427                                         DVD_READ_MENU_VOBS);
428
429                         /* Test if VTS_XX_X.VOB are present */
430
431                         vts_title_file = DVDOpenFile(_dvd, counter + 1,
432                                                 DVD_READ_TITLE_VOBS);
433
434                         /* Check VIDEO_TS.IFO */
435
436                         vts_ifo_file = DVDOpenFile(_dvd, counter + 1,
437                                                         DVD_READ_INFO_FILE);
438
439                         /*
440                          * Checking that title will fit in the
441                          * space given by the ifo file
442                          */
443
444
445                         if (vts_ifo->vtsi_mat->vts_last_sector + 1
446                                 < 2 * DVDFileSize(vts_ifo_file)) {
447 #ifdef  USE_LIBSCHILY
448                                 errmsgno(EX_BAD, "IFO is not of correct size aborting.\n");
449 #else
450                                 fprintf(stderr, "IFO is not of correct size aborting\n");
451 #endif
452                                 DVDFreeFileSetArrays(sector, title,
453                                         title_sets_array, sector_sets_array);
454                                 DVDFreeFileSet(title_set_info);
455                                 return (0);
456                         } else if ((vts_title_file != 0) &&
457                                     (vts_menu_file != 0) &&
458                                     (vts_ifo->vtsi_mat->vts_last_sector + 1
459                                     < 2 * DVDFileSize(vts_ifo_file) +
460                                     DVDFileSize(vts_title_file) +
461                                     DVDFileSize(vts_menu_file))) {
462 #ifdef  USE_LIBSCHILY
463                                 errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n");
464 #else
465                                 fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size");
466 #endif
467                                 DVDFreeFileSetArrays(sector, title,
468                                         title_sets_array, sector_sets_array);
469                                 DVDFreeFileSet(title_set_info);
470                                 return (0);
471                         } else if ((vts_title_file != 0) &&
472                                     (vts_menu_file == 0) &&
473                                     (vts_ifo->vtsi_mat->vts_last_sector + 1
474                                     < 2 * DVDFileSize(vts_ifo_file) +
475                                     DVDFileSize(vts_title_file))) {
476 #ifdef  USE_LIBSCHILY
477                                 errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n");
478 #else
479                                 fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size");
480 #endif
481                                 DVDFreeFileSetArrays(sector, title,
482                                         title_sets_array, sector_sets_array);
483                                 DVDFreeFileSet(title_set_info);
484                                 return (0);
485                         } else if ((vts_menu_file != 0) &&
486                                     (vts_title_file == 0) &&
487                                     (vts_ifo->vtsi_mat->vts_last_sector + 1
488                                     < 2 * DVDFileSize(vts_ifo_file) +
489                                     DVDFileSize(vts_menu_file))) {
490 #ifdef  USE_LIBSCHILY
491                                 errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n");
492 #else
493                                 fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size");
494 #endif
495                                 DVDFreeFileSetArrays(sector, title,
496                                         title_sets_array, sector_sets_array);
497                                 DVDFreeFileSet(title_set_info);
498                                 return (0);
499                         }
500
501
502                         /* Find the actuall right size of VTS_XX_0.IFO */
503                         if ((vts_title_file == 0) && (vts_menu_file == 0)) {
504                                 if (vts_ifo->vtsi_mat->vts_last_sector + 1 >
505                                     2 * DVDFileSize(vts_ifo_file)) {
506                                         ifo = vts_ifo->vtsi_mat->vts_last_sector
507                                                 - DVDFileSize(vts_ifo_file) + 1;
508                                 } else {
509                                         ifo = vts_ifo->vtsi_mat->vts_last_sector
510                                                 - DVDFileSize(vts_ifo_file) + 1;
511                                 }
512                         } else if (vts_title_file == 0) {
513                                 if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 <
514                                     vts_ifo->vtsi_mat->vtstt_vobs) {
515                                         ifo = vmg_ifo->vtsi_mat->vtstt_vobs;
516                                 } else {
517                                         ifo = vmg_ifo->vtsi_mat->vtstt_vobs;
518                                 }
519                         } else {
520                                 if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 <
521                                     vts_ifo->vtsi_mat->vtsm_vobs) {
522                                         ifo = vts_ifo->vtsi_mat->vtsm_vobs;
523                                 } else {
524                                         ifo = vts_ifo->vtsi_mat->vtsi_last_sector + 1;
525                                 }
526                         }
527                         title_set_info->title_set[counter + 1].size_ifo =
528                                                 ifo * 2048;
529                         title_set_info->title_set[counter + 1].realsize_ifo =
530                                                 fileinfo.st_size;
531                         title_set_info->title_set[counter + 1].pad_ifo =
532                                                 ifo - DVDFileSize(vts_ifo_file);
533
534
535                         /* Find the actuall right size of VTS_XX_0.VOB */
536                         if (vts_menu_file != 0) {
537                                 if (vts_ifo->vtsi_mat->vtsm_vobs == 0)  {
538                                         /*
539                                          * Apparently start sector 0 means that
540                                          * VTS_XX_0.VOB is empty after all...
541                                          */
542                                         menu_vob = 0;
543                                         if (DVDFileSize(vts_menu_file) != 0) {
544                                                 /*
545                                                  * Paranoia: we most likely never
546                                                  * come here...
547                                                  */
548 #ifdef  USE_LIBSCHILY
549                                                 errmsgno(EX_BAD,
550                                                         "%s/VIDEO_TS/VTS_%02i_0.IFO appears to be corrupted.\n",
551                                                         mountpoint, counter+1);
552 #else
553                                                 fprintf(stderr,
554                                                         "%s/VIDEO_TS/VTS_%02i_0.IFO appears to be corrupted.\n",
555                                                         mountpoint, counter+1);
556 #endif
557                                                 return (0);
558                                         }
559                                 } else if ((vts_title_file != 0) &&
560                                         (vts_ifo->vtsi_mat->vtstt_vobs -
561                                         vts_ifo->vtsi_mat->vtsm_vobs >
562                                                 DVDFileSize(vts_menu_file))) {
563                                         menu_vob = vts_ifo->vtsi_mat->vtstt_vobs -
564                                                         vts_ifo->vtsi_mat->vtsm_vobs;
565                                 } else if ((vts_title_file == 0) &&
566                                             (vts_ifo->vtsi_mat->vtsm_vobs +
567                                             DVDFileSize(vts_menu_file) +
568                                             DVDFileSize(vts_ifo_file) - 1 <
569                                             vts_ifo->vtsi_mat->vts_last_sector)) {
570                                         menu_vob = vts_ifo->vtsi_mat->vts_last_sector
571                                                 - DVDFileSize(vts_ifo_file)
572                                                 - vts_ifo->vtsi_mat->vtsm_vobs + 1;
573                                 } else {
574                                         menu_vob = vts_ifo->vtsi_mat->vtstt_vobs -
575                                                         vts_ifo->vtsi_mat->vtsm_vobs;
576                                 }
577
578                                 snprintf(temppoint, sizeof (temppoint),
579                                         "%s/VIDEO_TS/VTS_%02i_0.VOB", mountpoint, counter + 1);
580
581                                 if (stat(temppoint, &fileinfo)  < 0) {
582 #ifdef  USE_LIBSCHILY
583                                         errmsg("calc: Can't stat %s\n", temppoint);
584 #else
585                                         fprintf(stderr, "calc: Can't stat %s\n",
586                                                 temppoint);
587                                         perror("");
588 #endif
589                                         DVDFreeFileSetArrays(sector, title,
590                                                 title_sets_array, sector_sets_array);
591                                         DVDFreeFileSet(title_set_info);
592                                         return (0);
593                                 }
594
595                                 title_set_info->title_set[counter + 1].realsize_menu = fileinfo.st_size;
596                                 title_set_info->title_set[counter + 1].size_menu = menu_vob * 2048;
597                                 title_set_info->title_set[counter + 1].pad_menu = menu_vob - DVDFileSize(vts_menu_file);
598
599                         } else {
600                                 title_set_info->title_set[counter + 1].size_menu = 0;
601                                 title_set_info->title_set[counter + 1].realsize_menu = 0;
602                                 title_set_info->title_set[counter + 1].pad_menu = 0;
603                                 menu_vob = 0;
604                         }
605
606
607                         /* Find the actuall total size of VTS_XX_[1 to 9].VOB */
608
609                         if (vts_title_file != 0) {
610                                 if (ifo + menu_vob + DVDFileSize(vts_ifo_file) -
611                                     1 < vts_ifo->vtsi_mat->vts_last_sector) {
612                                     title_vob = vts_ifo->vtsi_mat->vts_last_sector
613                                                 + 1 - ifo - menu_vob -
614                                                 DVDFileSize(vts_ifo_file);
615                                 } else {
616                                         title_vob = vts_ifo->vtsi_mat->vts_last_sector +
617                                                 1 - ifo - menu_vob -
618                                                 DVDFileSize(vts_ifo_file);
619                                 }
620                                 /*
621                                  * Find out how many vob files
622                                  * and the size of them
623                                  */
624                                 for (i = 0; i < 9; ++i) {
625                                         snprintf(temppoint, sizeof (temppoint),
626                                                 "%s/VIDEO_TS/VTS_%02i_%i.VOB",
627                                                 mountpoint, counter + 1, i + 1);
628                                         if (stat(temppoint, &fileinfo) < 0) {
629                                                 break;
630                                         }
631                                         title_set_info->title_set[counter + 1].realsize_vob[i] = fileinfo.st_size;
632                                 }
633                                 title_set_info->title_set[counter + 1].number_of_vob_files = i;
634                                 title_set_info->title_set[counter + 1].size_title = title_vob * 2048;
635                                 title_set_info->title_set[counter + 1].pad_title = title_vob - DVDFileSize(vts_title_file);
636                         } else {
637                                 title_set_info->title_set[counter + 1].number_of_vob_files = 0;
638                                 title_set_info->title_set[counter + 1].realsize_vob[0] = 0;
639                                 title_set_info->title_set[counter + 1].size_title = 0;
640                                 title_set_info->title_set[counter + 1].pad_title = 0;
641                                 title_vob = 0;
642
643                         }
644
645
646                         /* Find the actuall total size of VTS_XX_0.BUP */
647                         if (title_sets - 1 > counter) {
648                                 bup = sector_sets_array[counter+1]
649                                         - sector_sets_array[counter]
650                                         - title_vob - menu_vob - ifo;
651                         } else {
652                                 bup = vts_ifo->vtsi_mat->vts_last_sector + 1
653                                         - title_vob - menu_vob - ifo;
654                         }
655
656                         /* Never trust the BUP use a copy of the IFO */
657                         snprintf(temppoint, sizeof (temppoint),
658                                 "%s/VIDEO_TS/VTS_%02i_0.IFO",
659                                 mountpoint, counter + 1);
660
661                         if (stat(temppoint, &fileinfo) < 0) {
662 #ifdef  USE_LIBSCHILY
663                                 errmsg("calc: Can't stat %s\n", temppoint);
664 #else
665                                 fprintf(stderr, "calc: Can't stat %s\n",
666                                         temppoint);
667                                 perror("");
668 #endif
669                                 DVDFreeFileSetArrays(sector, title,
670                                         title_sets_array, sector_sets_array);
671                                 DVDFreeFileSet(title_set_info);
672                                 return (0);
673                         }
674
675                         title_set_info->title_set[counter + 1].size_bup =
676                                                 bup * 2048;
677                         title_set_info->title_set[counter + 1].realsize_bup =
678                                                 fileinfo.st_size;
679                         title_set_info->title_set[counter + 1].pad_bup =
680                                                 bup - DVDFileSize(vts_ifo_file);
681
682
683                         /* Closing files */
684
685                         if (vts_menu_file != 0) {
686                                 DVDCloseFile(vts_menu_file);
687                         }
688
689                         if (vts_title_file != 0) {
690                                 DVDCloseFile(vts_title_file);
691                         }
692
693
694                         if (vts_ifo_file != 0) {
695                                 DVDCloseFile(vts_ifo_file);
696                         }
697
698                         ifoClose(vts_ifo);
699
700                 }
701
702         }
703
704         DVDFreeFileSetArrays(sector, title, title_sets_array, sector_sets_array);
705
706         /* Close the VMG ifo file we got all the info we need */
707         ifoClose(vmg_ifo);
708
709
710         /* Close the DVD */
711         DVDClose(_dvd);
712
713         /* Return the actuall info*/
714         return (title_set_info);
715
716
717 }
718
719 int
720 DVDGetFilePad(title_set_info_t *title_set_info, char *name)
721 {
722         char    title_a[3];
723         char    vob_a[2];
724         int     title;
725         int     vob;
726
727         title_a[0] = title_a[1] = title_a[2] = '\0';
728         vob_a[0] = vob_a[1] = '\0';
729
730         if (name[0] != 'V') {
731                 return (0);
732         }
733         if (memcmp(name, "VIDEO_TS", 8) == 0) {
734                 if (strstr(name, ".IFO") != 0) {
735                         return (title_set_info->title_set[0].pad_ifo);
736                 } else if (strstr(name, ".VOB") != 0) {
737                         return (title_set_info->title_set[0].pad_menu);
738                 } else if (strstr(name, ".BUP") != 0) {
739                         return (title_set_info->title_set[0].pad_bup);
740                 } else {
741                         return (0);
742                 }
743         } else if (memcmp(name, "VTS_", 4) == 0) {
744                 title_a[0] = name[4];
745                 title_a[1] = name[5];
746                 title_a[2] = '\0';
747                 vob_a[0] = name[7];
748                 vob_a[1] = '\0';
749                 title = atoi(title_a);
750                 vob = atoi(vob_a);
751                 if (title > title_set_info->num_titles) {
752                         return (0);
753                 } else {
754                         if (strstr(name, ".IFO") != 0) {
755                                 return (title_set_info->title_set[title].pad_ifo);
756                         } else if (strstr(name, ".BUP") != 0) {
757                                 return (title_set_info->title_set[title].pad_bup);
758                         } else if (vob == 0) {
759                                 return (title_set_info->title_set[title].pad_menu);
760                         } else if (vob == title_set_info->title_set[title].number_of_vob_files) {
761                                 return (title_set_info->title_set[title].pad_title);
762                         } else {
763                                 return (0);
764                         }
765                 }
766         } else {
767                 return (0);
768         }
769 }
770
771 #endif /*DVD_VIDEO*/