Search
lxdream.org :: lxdream/src/gdrom/cdi.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/cdi.c
changeset 1:eea311cfd33e
next31:495e480360d7
author nkeynes
date Sat Mar 13 00:03:32 2004 +0000 (17 years ago)
permissions -rw-r--r--
last change This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/gdrom/cdi.c Sat Mar 13 00:03:32 2004 +0000
1.3 @@ -0,0 +1,154 @@
1.4 +
1.5 +#include <stdlib.h>
1.6 +#include <stdio.h>
1.7 +#include <stdint.h>
1.8 +#include <fcntl.h>
1.9 +#include <errno.h>
1.10 +#include <sys/stat.h>
1.11 +#include "cdi.h"
1.12 +
1.13 +#define CDI_V2 0x80000004
1.14 +#define CDI_V3 0x80000005
1.15 +
1.16 +static char track_start_marker[20] = { 0,0,1,0,0,0,255,255,255,255,
1.17 + 0,0,1,0,0,0,255,255,255,255 };
1.18 +
1.19 +struct cdi_trailer {
1.20 + uint32_t cdi_version;
1.21 + uint32_t header_offset;
1.22 +};
1.23 +
1.24 +struct cdi_track {
1.25 + int file_posn;
1.26 + int length; /* bytes */
1.27 + int pregap; /* sectors */
1.28 + int mode;
1.29 + int sector_size;
1.30 + int session;
1.31 + struct cdi_track *next;
1.32 +};
1.33 +
1.34 +struct cdi_handle {
1.35 + int fd;
1.36 + uint16_t num_sessions;
1.37 + struct cdi_track *tracks;
1.38 +};
1.39 +
1.40 +
1.41 +
1.42 +struct cdi_track_data {
1.43 + char unknown[0x19];
1.44 + uint32_t pregap_length;
1.45 + uint32_t length;
1.46 + char unknown2[6];
1.47 + uint32_t mode;
1.48 + char unknown3[0x0c];
1.49 + uint32_t start_lba;
1.50 + uint32_t total_length;
1.51 + char unknown4[0x10];
1.52 + uint32_t sector_size;
1.53 + char unknown5[0x1D];
1.54 +} __attribute__((packed));
1.55 +
1.56 +cdi_t cdi_open( char *filename )
1.57 +{
1.58 +#define BAIL( x, ... ) { fprintf( stderr, x, __VA_ARGS__ ); if( fd != -1 ) close(fd); return NULL; }
1.59 +
1.60 + struct stat st;
1.61 + int fd = -1, i,j, tmp;
1.62 + int posn = 0, hdr;
1.63 + long len;
1.64 + struct cdi_trailer trail;
1.65 + struct cdi_handle cdi;
1.66 + uint16_t tracks;
1.67 + uint32_t new_fmt;
1.68 + char tmpc;
1.69 + char marker[20];
1.70 +
1.71 + fd = open( filename, O_RDONLY );
1.72 + if( fd == -1 )
1.73 + BAIL( "Unable to open file: %s (%s)\n", filename, strerror(errno) );
1.74 + fstat( fd, &st );
1.75 + if( st.st_size < 8 )
1.76 + BAIL( "File is too small to be a valid CDI image: %s\n", filename );
1.77 + len = lseek( fd, -8, SEEK_END );
1.78 + read( fd, &trail, sizeof(trail) );
1.79 + if( trail.header_offset > st.st_size ||
1.80 + trail.header_offset == 0 )
1.81 + BAIL( "Not a valid CDI image: %s\n", filename );
1.82 +
1.83 + if( trail.cdi_version == CDI_V2 ) trail.cdi_version = 2;
1.84 + else if( trail.cdi_version == CDI_V3 ) trail.cdi_version = 3;
1.85 + else BAIL( "Unknown CDI version code %08x in %s\n", trail.cdi_version,
1.86 + filename );
1.87 +
1.88 + lseek( fd, trail.header_offset, SEEK_SET );
1.89 + read( fd, &cdi.num_sessions, 2 );
1.90 +
1.91 +
1.92 + printf( "CDI version: %d\n", trail.cdi_version );
1.93 + printf( "Sessions: %d\n\n", cdi.num_sessions );
1.94 + for( i=0; i< cdi.num_sessions; i++ ) {
1.95 + read( fd, &tracks, 2 );
1.96 + printf( "Session %d - %d tracks:\n", i+1, tracks );
1.97 + for( j=0; j<tracks; j++ ) {
1.98 + struct cdi_track_data trk;
1.99 +
1.100 + read( fd, &new_fmt, 4 );
1.101 + if( new_fmt != 0 ) { /* Additional data 3.00.780+ ?? */
1.102 + printf( "Note: CDI image has 3.00.780+ flag set\n" );
1.103 + lseek( fd, 8, SEEK_CUR );
1.104 + }
1.105 + read( fd, marker, 20 );
1.106 + if( memcmp( marker, track_start_marker, 20) != 0 )
1.107 + BAIL( "Track start marker not found, error reading cdi\n",NULL );
1.108 + read( fd, &tmp, 4 );
1.109 + printf( "Unknown 4 bytes: %08x\n", tmp );
1.110 + read( fd, &tmpc, 1 );
1.111 + lseek( fd, (int)tmpc, SEEK_CUR ); /* skip over the filename */
1.112 + read( fd, &trk, sizeof(trk) );
1.113 + switch( trk.sector_size ) {
1.114 + case 0: trk.sector_size = 2048; hdr=0; break;
1.115 + case 1: trk.sector_size = 2336; hdr=8; break;
1.116 + case 2:
1.117 + trk.sector_size = 2352;
1.118 + if( trk.mode == 2 ) hdr=24;
1.119 + else hdr=16;
1.120 + break;
1.121 + default: BAIL( "Unknown sector size: %d\n", trk.sector_size );
1.122 + }
1.123 + posn += hdr;
1.124 + len = trk.length*trk.sector_size;
1.125 + printf( " Track %d\n", j+1 );
1.126 + printf( " Pregap: %08x\n", trk.pregap_length );
1.127 + printf( " Length: %08x\n", trk.length );
1.128 + printf( " Mode: %d\n", trk.mode );
1.129 + printf( " Sector size: %d\n", trk.sector_size );
1.130 + printf( " Start LBA: %08x\n", trk.start_lba );
1.131 + printf( " Total length: %08x\n", trk.total_length );
1.132 + printf( " ---\n" );
1.133 + printf( " File position: %08x\n", posn+trk.pregap_length*trk.sector_size );
1.134 + printf( " File length: %d\n", len );
1.135 + posn += trk.total_length*trk.sector_size;
1.136 + lseek( fd, 12, SEEK_CUR );
1.137 + if( new_fmt )
1.138 + lseek( fd, 78, SEEK_CUR );
1.139 + tmp = lseek( fd, 0, SEEK_CUR );
1.140 + printf( "(Header offset: %x)\n", tmp - trail.header_offset );
1.141 + }
1.142 + }
1.143 +
1.144 + return NULL;
1.145 +#undef BAIL(x, ...)
1.146 +}
1.147 +
1.148 +int main(int argc, char *argv[] )
1.149 +{
1.150 + int i;
1.151 +
1.152 + for( i=1; i<argc; i++ ) {
1.153 + cdi_open(argv[i]);
1.154 + }
1.155 + return 0;
1.156 +}
1.157 +
.