4 * NullDC GDI image format
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
27 #include "drivers/cdrom/cdimpl.h"
30 static gboolean gdi_image_is_valid( FILE *f );
31 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err );
33 struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi",
34 gdi_image_is_valid, NULL, gdi_image_read_toc };
36 static gboolean gdi_image_is_valid( FILE *f )
41 fseek(f, 0, SEEK_SET);
42 if( fgets( line, sizeof(line), f ) == NULL ) {
45 track_count = strtoul(line, NULL, 0);
46 if( track_count == 0 || track_count > 99 ) {
52 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err )
60 FILE *f = cdrom_disc_get_base_file(disc);
62 fseek(f, 0, SEEK_SET);
64 if( fgets( line, sizeof(line), f ) == NULL ) {
65 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
68 track_count = strtoul(line, NULL, 0);
69 if( track_count == 0 || track_count > 99 ) {
70 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
74 dirname = g_path_get_dirname(disc->name);
75 disc->disc_type = CDROM_DISC_GDROM;
76 disc->track_count = track_count;
77 disc->session_count = 2;
78 for( i=0; i<track_count; i++ ) {
79 int track_no, start_lba, flags, size, offset;
82 if( fgets( line, sizeof(line), f ) == NULL ) {
83 cdrom_disc_unref(disc);
84 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image - unexpected end of file" );
87 sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
89 if( start_lba >= 45000 ) {
92 disc->track[i].sessionno = session;
93 disc->track[i].lba = start_lba;
94 disc->track[i].flags = (flags & 0x0F)<<4;
97 if( disc->track[i].flags & TRACK_FLAG_DATA ) {
100 case 0: mode = SECTOR_MODE2_FORM1; break; /* Default */
101 case 2048: mode = SECTOR_MODE2_FORM1; break;
102 case 2324: mode = SECTOR_MODE2_FORM2; break;
103 case 2336: mode = SECTOR_SEMIRAW_MODE2; break;
104 case 2352: mode = SECTOR_RAW_XA; break;
106 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' in GDI track %d", size, (i+1) );
115 else if( size != 2352 ) {
116 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' for audio track %d", size, (i+1) );
121 if( strcasecmp( filename, "none" ) == 0 ) {
122 disc->track[i].source = null_sector_source_new( mode, 0 );
124 gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
125 disc->track[i].source = file_sector_source_new_filename( pathname, mode,
126 offset, FILE_SECTOR_FULL_FILE );
128 if( disc->track[i].source == NULL ) {
129 /* Note: status is invalid because it's a failure of the GDI file */
130 SET_ERROR( err, LX_ERR_FILE_INVALID, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) );
.