nkeynes@492: /** nkeynes@561: * $Id$ nkeynes@492: * nkeynes@492: * NullDC GDI image format nkeynes@492: * nkeynes@492: * Copyright (c) 2005 Nathan Keynes. nkeynes@492: * nkeynes@492: * This program is free software; you can redistribute it and/or modify nkeynes@492: * it under the terms of the GNU General Public License as published by nkeynes@492: * the Free Software Foundation; either version 2 of the License, or nkeynes@492: * (at your option) any later version. nkeynes@492: * nkeynes@492: * This program is distributed in the hope that it will be useful, nkeynes@492: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@492: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@492: * GNU General Public License for more details. nkeynes@492: */ nkeynes@492: nkeynes@492: #include nkeynes@492: #include nkeynes@492: #include nkeynes@759: #include nkeynes@492: #include nkeynes@492: #include nkeynes@492: #include nkeynes@1296: #include nkeynes@1097: #include "drivers/cdrom/cdimpl.h" nkeynes@492: nkeynes@492: nkeynes@492: static gboolean gdi_image_is_valid( FILE *f ); nkeynes@1097: static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err ); nkeynes@492: nkeynes@1097: struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi", nkeynes@1097: gdi_image_is_valid, NULL, gdi_image_read_toc }; nkeynes@492: nkeynes@492: static gboolean gdi_image_is_valid( FILE *f ) nkeynes@492: { nkeynes@492: char line[512]; nkeynes@492: uint32_t track_count; nkeynes@736: nkeynes@492: fseek(f, 0, SEEK_SET); nkeynes@492: if( fgets( line, sizeof(line), f ) == NULL ) { nkeynes@736: return FALSE; nkeynes@492: } nkeynes@492: track_count = strtoul(line, NULL, 0); nkeynes@492: if( track_count == 0 || track_count > 99 ) { nkeynes@736: return FALSE; nkeynes@492: } nkeynes@492: return TRUE; nkeynes@492: } nkeynes@492: nkeynes@1097: static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err ) nkeynes@492: { nkeynes@492: int i; nkeynes@492: uint32_t track_count; nkeynes@492: char line[512]; nkeynes@1097: int session = 1; nkeynes@492: gchar *dirname; nkeynes@492: nkeynes@1097: FILE *f = cdrom_disc_get_base_file(disc); nkeynes@1097: nkeynes@492: fseek(f, 0, SEEK_SET); nkeynes@736: nkeynes@492: if( fgets( line, sizeof(line), f ) == NULL ) { nkeynes@1109: SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" ); nkeynes@736: return FALSE; nkeynes@492: } nkeynes@492: track_count = strtoul(line, NULL, 0); nkeynes@492: if( track_count == 0 || track_count > 99 ) { nkeynes@1109: SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" ); nkeynes@1097: return FALSE; nkeynes@492: } nkeynes@492: nkeynes@1097: dirname = g_path_get_dirname(disc->name); nkeynes@1097: disc->disc_type = CDROM_DISC_GDROM; nkeynes@1023: disc->track_count = track_count; nkeynes@1097: disc->session_count = 2; nkeynes@492: for( i=0; i= 45000 ) { nkeynes@1097: session = 2; nkeynes@736: } nkeynes@1097: disc->track[i].sessionno = session; nkeynes@1097: disc->track[i].lba = start_lba; nkeynes@1023: disc->track[i].flags = (flags & 0x0F)<<4; nkeynes@1097: nkeynes@1097: sector_mode_t mode; nkeynes@1097: if( disc->track[i].flags & TRACK_FLAG_DATA ) { nkeynes@1097: /* Data track */ nkeynes@1097: switch(size) { nkeynes@1097: case 0: mode = SECTOR_MODE2_FORM1; break; /* Default */ nkeynes@1097: case 2048: mode = SECTOR_MODE2_FORM1; break; nkeynes@1097: case 2324: mode = SECTOR_MODE2_FORM2; break; nkeynes@1097: case 2336: mode = SECTOR_SEMIRAW_MODE2; break; nkeynes@1097: case 2352: mode = SECTOR_RAW_XA; break; nkeynes@1097: default: nkeynes@1109: SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' in GDI track %d", size, (i+1) ); nkeynes@1097: g_free(dirname); nkeynes@1097: return FALSE; nkeynes@1097: } nkeynes@1097: } else { nkeynes@1097: /* Audio track */ nkeynes@1097: mode = SECTOR_CDDA; nkeynes@1097: if( size == 0 ) nkeynes@1097: size = 2352; nkeynes@1097: else if( size != 2352 ) { nkeynes@1109: SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' for audio track %d", size, (i+1) ); nkeynes@1097: g_free(dirname); nkeynes@1097: return FALSE; nkeynes@1097: } nkeynes@1097: } nkeynes@736: if( strcasecmp( filename, "none" ) == 0 ) { nkeynes@1097: disc->track[i].source = null_sector_source_new( mode, 0 ); nkeynes@736: } else { nkeynes@736: gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename ); nkeynes@1097: disc->track[i].source = file_sector_source_new_filename( pathname, mode, nkeynes@1097: offset, FILE_SECTOR_FULL_FILE ); nkeynes@736: g_free(pathname); nkeynes@1097: if( disc->track[i].source == NULL ) { nkeynes@1109: /* Note: status is invalid because it's a failure of the GDI file */ nkeynes@1109: SET_ERROR( err, LX_ERR_FILE_INVALID, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) ); nkeynes@736: g_free(dirname); nkeynes@1097: return FALSE; nkeynes@736: } nkeynes@736: } nkeynes@492: } nkeynes@492: g_free(dirname); nkeynes@1097: return TRUE; nkeynes@492: }