filename | src/drivers/cdrom/cd_gdi.c |
changeset | 1109:700c5ab26a63 |
prev | 1097:d4807997e450 |
next | 1286:8376a612a79d |
author | nkeynes |
date | Tue Feb 28 18:22:52 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Add a GL-only video driver for android usage (since the Java code is responsible for creating the context) |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * NullDC GDI image format
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <sys/stat.h>
26 #include <glib/gutils.h>
27 #include <glib/gstrfuncs.h>
28 #include "drivers/cdrom/cdimpl.h"
31 static gboolean gdi_image_is_valid( FILE *f );
32 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err );
34 struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi",
35 gdi_image_is_valid, NULL, gdi_image_read_toc };
37 static gboolean gdi_image_is_valid( FILE *f )
38 {
39 char line[512];
40 uint32_t track_count;
42 fseek(f, 0, SEEK_SET);
43 if( fgets( line, sizeof(line), f ) == NULL ) {
44 return FALSE;
45 }
46 track_count = strtoul(line, NULL, 0);
47 if( track_count == 0 || track_count > 99 ) {
48 return FALSE;
49 }
50 return TRUE;
51 }
53 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err )
54 {
55 int i;
56 uint32_t track_count;
57 struct stat st;
58 char line[512];
59 int session = 1;
60 gchar *dirname;
62 FILE *f = cdrom_disc_get_base_file(disc);
64 fseek(f, 0, SEEK_SET);
66 if( fgets( line, sizeof(line), f ) == NULL ) {
67 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
68 return FALSE;
69 }
70 track_count = strtoul(line, NULL, 0);
71 if( track_count == 0 || track_count > 99 ) {
72 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
73 return FALSE;
74 }
76 dirname = g_path_get_dirname(disc->name);
77 disc->disc_type = CDROM_DISC_GDROM;
78 disc->track_count = track_count;
79 disc->session_count = 2;
80 for( i=0; i<track_count; i++ ) {
81 int track_no, start_lba, flags, size, offset;
82 char filename[256];
84 if( fgets( line, sizeof(line), f ) == NULL ) {
85 cdrom_disc_unref(disc);
86 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image - unexpected end of file" );
87 return FALSE;
88 }
89 sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
90 filename, &offset );
91 if( start_lba >= 45000 ) {
92 session = 2;
93 }
94 disc->track[i].sessionno = session;
95 disc->track[i].lba = start_lba;
96 disc->track[i].flags = (flags & 0x0F)<<4;
98 sector_mode_t mode;
99 if( disc->track[i].flags & TRACK_FLAG_DATA ) {
100 /* Data track */
101 switch(size) {
102 case 0: mode = SECTOR_MODE2_FORM1; break; /* Default */
103 case 2048: mode = SECTOR_MODE2_FORM1; break;
104 case 2324: mode = SECTOR_MODE2_FORM2; break;
105 case 2336: mode = SECTOR_SEMIRAW_MODE2; break;
106 case 2352: mode = SECTOR_RAW_XA; break;
107 default:
108 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' in GDI track %d", size, (i+1) );
109 g_free(dirname);
110 return FALSE;
111 }
112 } else {
113 /* Audio track */
114 mode = SECTOR_CDDA;
115 if( size == 0 )
116 size = 2352;
117 else if( size != 2352 ) {
118 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' for audio track %d", size, (i+1) );
119 g_free(dirname);
120 return FALSE;
121 }
122 }
123 if( strcasecmp( filename, "none" ) == 0 ) {
124 disc->track[i].source = null_sector_source_new( mode, 0 );
125 } else {
126 gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
127 disc->track[i].source = file_sector_source_new_filename( pathname, mode,
128 offset, FILE_SECTOR_FULL_FILE );
129 g_free(pathname);
130 if( disc->track[i].source == NULL ) {
131 /* Note: status is invalid because it's a failure of the GDI file */
132 SET_ERROR( err, LX_ERR_FILE_INVALID, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) );
133 g_free(dirname);
134 return FALSE;
135 }
136 }
137 }
138 g_free(dirname);
139 return TRUE;
140 }
.