1 /* @(#)ifo_read.c 1.18 18/09/17 joerg */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)ifo_read.c 1.18 18/09/17 joerg";
6 #endif
7 /*
8 * Copyright (C) 2002 Olaf Beck <olaf_sc@yahoo.com>
9 * Copyright (C) 2002-2016 J�rg Schilling <joerg@schily.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 /*
27 * NOTE: This is a cut down version of libdvdread for mkisofs, due
28 * to portability issues with the current libdvdread according to
29 * the maintainer of mkisofs.
30 * This cut down version only reads from a harddisk file structure
31 * and it only implements the functions necessary inorder to make
32 * mkisofs produce valid DVD-Video images.
33 * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL
34 * LIBDVDREAD INSTEAD
35 */
36 #ifdef DVD_AUD_VID
37
38 #include "mkisofs.h"
39 #include <schily/fcntl.h>
40 #include <schily/utypes.h>
41 #include <schily/schily.h>
42
43 #include "ifo_read.h"
44 #include "bswap.h"
45
46 LOCAL ifo_handle_t *ifoReadVTSI __PR((int file, ifo_handle_t *ifofile));
47 LOCAL ifo_handle_t *ifoReadVGMI __PR((int file, ifo_handle_t *ifofile));
48 EXPORT ifo_handle_t *ifoOpen __PR((dvd_reader_t *dvd, int title));
49 LOCAL void ifoFree_TT_SRPT __PR((ifo_handle_t *ifofile));
50 EXPORT void ifoClose __PR((ifo_handle_t *ifofile));
51
52
53 LOCAL ifo_handle_t *
ifoReadVTSI(file,ifofile)54 ifoReadVTSI(file, ifofile)
55 int file;
56 ifo_handle_t *ifofile;
57 {
58 off_t offset;
59 UInt32_t sector;
60
61 vtsi_mat_t *vtsi_mat;
62
63 /* Make the VMG part NULL */
64 ifofile->vmgi_mat = NULL;
65 ifofile->tt_srpt = NULL;
66
67 vtsi_mat = (vtsi_mat_t *)e_malloc(sizeof (vtsi_mat_t));
68 if (!vtsi_mat) {
69 /* fprintf(stderr, "Memmory allocation error\n");*/
70 free(ifofile);
71 return (0);
72 }
73
74 ifofile->vtsi_mat = vtsi_mat;
75
76 /* Last sector of VTS i.e. last sector of BUP */
77
78 offset = 12;
79
80 if (lseek(file, offset, SEEK_SET) != offset) {
81 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
82 ifoClose(ifofile);
83 return (0);
84 }
85
86 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
87 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
88 ifoClose(ifofile);
89 return (0);
90 }
91
92 B2N_32(sector);
93
94 vtsi_mat->vts_last_sector = sector;
95
96 /* Last sector of IFO */
97
98 offset = 28;
99
100 if (lseek(file, offset, SEEK_SET) != offset) {
101 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
102 ifoClose(ifofile);
103 return (0);
104 }
105
106 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
107 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
108 ifoClose(ifofile);
109 return (0);
110 }
111
112 B2N_32(sector);
113
114 vtsi_mat->vtsi_last_sector = sector;
115
116
117 /* Star sector of VTS Menu VOB */
118
119 offset = 192;
120
121 if (lseek(file, offset, SEEK_SET) != offset) {
122 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
123 ifoClose(ifofile);
124 return (0);
125 }
126
127
128 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
129 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
130 ifoClose(ifofile);
131 return (0);
132 }
133
134 B2N_32(sector);
135
136 vtsi_mat->vtsm_vobs = sector;
137
138
139 /* Start sector of VTS Title VOB */
140
141 offset = 196;
142
143 if (lseek(file, offset, SEEK_SET) != offset) {
144 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
145 ifoClose(ifofile);
146 return (0);
147 }
148
149
150 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
151 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
152 ifoClose(ifofile);
153 return (0);
154 }
155
156 B2N_32(sector);
157
158 vtsi_mat->vtstt_vobs = sector;
159
160 return (ifofile);
161 }
162
163
164 LOCAL ifo_handle_t *
ifoReadVGMI(file,ifofile)165 ifoReadVGMI(file, ifofile)
166 int file;
167 ifo_handle_t *ifofile;
168 {
169 off_t offset;
170 Uint counter;
171 UInt32_t sector;
172 UInt16_t titles;
173
174 vmgi_mat_t *vmgi_mat;
175 tt_srpt_t *tt_srpt;
176
177 /* Make the VTS part null */
178 ifofile->vtsi_mat = NULL;
179
180 vmgi_mat = (vmgi_mat_t *)e_malloc(sizeof (vmgi_mat_t));
181 if (!vmgi_mat) {
182 /* fprintf(stderr, "Memmory allocation error\n");*/
183 free(ifofile);
184 return (0);
185 }
186
187 ifofile->vmgi_mat = vmgi_mat;
188
189 /* Last sector of VMG i.e. last sector of BUP */
190
191 offset = 12;
192
193 if (lseek(file, offset, SEEK_SET) != offset) {
194 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
195 ifoClose(ifofile);
196 return (0);
197 }
198
199 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
200 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
201 ifoClose(ifofile);
202 return (0);
203 }
204
205 B2N_32(sector);
206
207 vmgi_mat->vmg_last_sector = sector;
208
209 /* Last sector of IFO */
210
211 offset = 28;
212
213 if (lseek(file, offset, SEEK_SET) != offset) {
214 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
215 ifoClose(ifofile);
216 return (0);
217 }
218
219
220 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
221 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
222 ifoClose(ifofile);
223 return (0);
224 }
225
226 B2N_32(sector);
227
228 vmgi_mat->vmgi_last_sector = sector;
229
230
231 /* Number of VTS i.e. title sets */
232
233 offset = 62;
234
235 if (lseek(file, offset, SEEK_SET) != offset) {
236 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
237 ifoClose(ifofile);
238 return (0);
239 }
240
241
242 if (read(file, &titles, sizeof (titles)) != sizeof (titles)) {
243 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
244 ifoClose(ifofile);
245 return (0);
246 }
247
248 B2N_16(titles);
249
250 vmgi_mat->vmg_nr_of_title_sets = titles;
251
252
253 /* Star sector of VMG Menu VOB */
254
255 offset = 192;
256
257 if (lseek(file, offset, SEEK_SET) != offset) {
258 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
259 ifoClose(ifofile);
260 return (0);
261 }
262
263
264 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
265 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
266 ifoClose(ifofile);
267 return (0);
268 }
269
270 B2N_32(sector);
271
272 vmgi_mat->vmgm_vobs = sector;
273
274
275 /* Sector offset to TT_SRPT */
276
277 offset = 196;
278
279 if (lseek(file, offset, SEEK_SET) != offset) {
280 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
281 ifoClose(ifofile);
282 return (0);
283 }
284
285
286 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
287 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
288 ifoClose(ifofile);
289 return (0);
290 }
291
292 B2N_32(sector);
293
294 vmgi_mat->tt_srpt = sector;
295
296 tt_srpt = (tt_srpt_t *)e_malloc(sizeof (tt_srpt_t));
297 if (!tt_srpt) {
298 /* fprintf(stderr, "Memmory allocation error\n");*/
299 ifoClose(ifofile);
300 return (0);
301 }
302
303 ifofile->tt_srpt = tt_srpt;
304
305
306 /* Number of titles in TT_SRPT */
307
308 offset = 2048 * vmgi_mat->tt_srpt;
309
310 if (lseek(file, offset, SEEK_SET) != offset) {
311 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
312 return (0);
313 }
314
315 if (read(file, &titles, sizeof (titles)) != sizeof (titles)) {
316 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
317 return (0);
318 }
319
320 B2N_16(titles);
321
322 tt_srpt->nr_of_srpts = titles;
323
324 tt_srpt->title = (title_info_t *)e_malloc(sizeof (title_info_t) * tt_srpt->nr_of_srpts);
325 if (!tt_srpt->title) {
326 /* fprintf(stderr, "Memmory allocation error\n");*/
327 ifoClose(ifofile);
328 return (0);
329 }
330
331 /* Start sector of each title in TT_SRPT */
332
333 for (counter = 0; counter < tt_srpt->nr_of_srpts; counter++) {
334 offset = (2048 * vmgi_mat->tt_srpt) + 8 + (counter * 12) + 8;
335 if (lseek(file, offset, SEEK_SET) != offset) {
336 errmsg(_("Failed to seek VIDEO_TS.IFO.\n"));
337 ifoClose(ifofile);
338 return (0);
339 }
340
341 if (read(file, §or, sizeof (sector)) != sizeof (sector)) {
342 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
343 ifoClose(ifofile);
344 return (0);
345 }
346
347 B2N_32(sector);
348
349 tt_srpt->title[counter].title_set_sector = sector;
350
351 }
352 return (ifofile);
353 }
354
355 EXPORT ifo_handle_t *
ifoOpen(dvd,title)356 ifoOpen(dvd, title)
357 dvd_reader_t *dvd;
358 int title;
359 {
360 /* The main ifofile structure */
361 ifo_handle_t *ifofile;
362
363 /* File handles and offset */
364 int file;
365 char full_path[ PATH_MAX + 1 ];
366
367 /* Identifier of the IFO */
368 char identifier[13];
369
370 identifier[0] = '\0';
371
372 ifofile = (ifo_handle_t *)e_malloc(sizeof (ifo_handle_t));
373
374 memset(ifofile, 0, sizeof (ifo_handle_t));
375
376 if (title) {
377 snprintf(full_path, sizeof (full_path),
378 "%s/VIDEO_TS/VTS_%02d_0.IFO", dvd->path_root, title);
379 } else {
380 snprintf(full_path, sizeof (full_path),
381 "%s/VIDEO_TS/VIDEO_TS.IFO", dvd->path_root);
382 }
383
384 if ((file = open(full_path, O_RDONLY | O_BINARY)) == -1) {
385 errmsg(_("Failed to open '%s'.\n"), full_path);
386 free(ifofile);
387 return (0);
388 }
389
390 /* Determine if we have a VMGI or VTSI */
391
392 if (read(file, identifier, sizeof (identifier)) != sizeof (identifier)) {
393 errmsg(_("Failed to read VIDEO_TS.IFO.\n"));
394 free(ifofile);
395 return (0);
396 }
397
398 if ((strstr("DVDVIDEO-VMG", identifier) != 0) && (title == 0)) {
399 ifofile = ifoReadVGMI(file, ifofile);
400 close(file);
401 return (ifofile);
402 } else if ((strstr("DVDVIDEO-VTS", identifier) != 0) && (title != 0)) {
403 ifofile = ifoReadVTSI(file, ifofile);
404 close(file);
405 return (ifofile);
406 } else {
407 errmsgno(EX_BAD, _("Giving up this is not a valid IFO file.\n"));
408 close(file);
409 free(ifofile);
410 ifofile = 0;
411 return (0);
412 }
413 }
414
415 LOCAL void
ifoFree_TT_SRPT(ifofile)416 ifoFree_TT_SRPT(ifofile)
417 ifo_handle_t *ifofile;
418 {
419 if (!ifofile)
420 return;
421
422 if (ifofile->tt_srpt) {
423 if (ifofile->tt_srpt->title) {
424 free(ifofile->tt_srpt->title);
425 }
426 free(ifofile->tt_srpt);
427 ifofile->tt_srpt = 0;
428 }
429 }
430
431 EXPORT void
ifoClose(ifofile)432 ifoClose(ifofile)
433 ifo_handle_t *ifofile;
434 {
435
436 if (!ifofile)
437 return;
438
439 ifoFree_TT_SRPT(ifofile);
440
441 if (ifofile->vmgi_mat) {
442 free(ifofile->vmgi_mat);
443 }
444
445 if (ifofile->vtsi_mat) {
446 free(ifofile->vtsi_mat);
447 }
448
449 free(ifofile);
450 ifofile = 0;
451 }
452 #endif /* DVD_AUD_VID */
453