Search
lxdream.org :: lxdream/src/gdrom/gdi.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/gdi.c
changeset 836:d314bf370949
prev759:f16975739abc
next1023:264e2fd90be8
author nkeynes
date Tue Sep 02 03:34:23 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Add omitted ctype.h include
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 "gdrom/gddriver.h"
    30 static gboolean gdi_image_is_valid( FILE *f );
    31 static gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f );
    33 struct gdrom_image_class gdi_image_class = { "NullDC GD-Rom Image", "gdi", 
    34         gdi_image_is_valid, gdi_image_open };
    36 static gboolean gdi_image_is_valid( FILE *f )
    37 {
    38     char line[512];
    39     uint32_t track_count;
    41     fseek(f, 0, SEEK_SET);
    42     if( fgets( line, sizeof(line), f ) == NULL ) {
    43         return FALSE;
    44     }
    45     track_count = strtoul(line, NULL, 0);
    46     if( track_count == 0 || track_count > 99 ) {
    47         return FALSE;
    48     }
    49     return TRUE;
    50 }
    52 static gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f )
    53 {
    54     int i;
    55     uint32_t track_count;
    56     gdrom_disc_t disc;
    57     gdrom_image_t image;
    58     struct stat st;
    59     char line[512];
    60     int session = 0;
    61     gchar *dirname;
    63     fseek(f, 0, SEEK_SET);
    65     if( fgets( line, sizeof(line), f ) == NULL ) {
    66         return FALSE;
    67     }
    68     track_count = strtoul(line, NULL, 0);
    69     if( track_count == 0 || track_count > 99 ) {
    70         return NULL;
    71     }
    73     disc = gdrom_image_new(filename, f);
    74     if( disc == NULL ) {
    75         ERROR("Unable to allocate memory!");
    76         return NULL;
    77     }
    78     dirname = g_path_get_dirname(filename);
    79     image = (gdrom_image_t)disc;
    80     image->disc_type = IDE_DISC_GDROM;
    81     image->track_count = track_count;
    82     for( i=0; i<track_count; i++ ) {
    83         int track_no, start_lba, flags, size, offset;
    84         char filename[256];
    86         if( fgets( line, sizeof(line), f ) == NULL ) {
    87             gdrom_image_destroy_no_close(disc);
    88             return NULL;
    89         }
    90         sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
    91                 filename, &offset );
    92         if( start_lba >= 45000 ) {
    93             session = 1;
    94         }
    95         image->track[i].session = session;
    96         image->track[i].lba = start_lba + 150; // 2-second offset
    97         image->track[i].flags = (flags & 0x0F)<<4;
    98         image->track[i].sector_size = size;
    99         if( strcasecmp( filename, "none" ) == 0 ) {
   100             image->track[i].file = NULL;
   101             image->track[i].sector_count = 0;
   102             image->track[i].mode = GDROM_MODE1;
   103         } else {
   104             gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
   105             image->track[i].file = fopen( pathname, "ro" );
   106             g_free(pathname);
   107             if( image->track[i].file == NULL ) {
   108                 gdrom_image_destroy_no_close(disc);
   109                 g_free(dirname);
   110                 return NULL;
   111             }
   112             fstat( fileno(image->track[i].file), &st );
   113             image->track[i].sector_count = st.st_size / size;
   114             if( image->track[i].flags & TRACK_DATA ) {
   115                 /* Data track */
   116                 switch(size) {
   117                 case 2048: image->track[i].mode = GDROM_MODE1; break;
   118                 case 2336: image->track[i].mode = GDROM_SEMIRAW_MODE2; break;
   119                 case 2352: image->track[i].mode = GDROM_RAW_XA; break;
   120                 default:
   121                     gdrom_image_destroy_no_close(disc);
   122                     g_free(dirname);
   123                     return NULL;
   124                 }
   125             } else {
   126                 /* Audio track */
   127                 image->track[i].mode = GDROM_CDDA;
   128                 if( size != 2352 ) {
   129                     gdrom_image_destroy_no_close(disc);
   130                     g_free(dirname);
   131                     return NULL;
   132                 }
   133             }
   134         }
   135         image->track[i].offset = offset;
   136     }
   137     g_free(dirname);
   138     return disc;
   139 }
.