6 #define CHECK 0 /* don't bother checking bin for validity... */
\r
8 //----------------Wave Stuff---------------------/
\r
9 typedef unsigned char BYTE1 ;
\r
10 typedef unsigned short int BYTE2 ;
\r
11 typedef unsigned long int BYTE4 ;
\r
13 typedef struct wavHdr {
\r
18 BYTE4 formatsize; // 16 byte format specifier
\r
19 BYTE2 format; // Windows PCM
\r
20 BYTE2 channels; // 2 channels
\r
21 BYTE4 samplerate; // 44,100 Samples/sec
\r
22 BYTE4 avgbyterate; // 176,400 Bytes/sec
\r
23 BYTE2 samplebytes; // 4 bytes/sample
\r
24 BYTE2 channelbits; // 16 bits/channel
\r
29 #define HEADBYTES 36
\r
30 #define WINDOWS_PCM 0x0001
\r
31 //-------------------------------------------------/
\r
33 /* G L O B A L D E F I N E S */
\r
34 #define byte unsigned char
\r
35 #define SIZERAW 2352
\r
36 #define SIZEISO_MODE1 2048
\r
37 #define SIZEISO_MODE2_RAW 2352
\r
38 #define SIZEISO_MODE2_FORM1 2048
\r
39 #define SIZEISO_MODE2_FORM2 2336
\r
43 #define MODE1_2352 10
\r
44 #define MODE2_2352 20
\r
45 #define MODE1_2048 30
\r
46 #define MODE2_2336 40
\r
48 #define RAWDATA FF // using this for leftover data when truncating for non-overburn
\r
50 #define PROG_INTERVAL 1024
\r
53 // got this from easycd pro by looking at a blank disk so it may be off...
\r
54 #define CD74_MAX_SECTORS 334873 // 653.75 Mb
\r
57 unsigned long int Index(char m, char s, char f)
\r
59 unsigned long int temp;
\r
62 temp = (((m>>4)*10) + (m&0xf)) * 60;
\r
63 temp = ( temp + (((s>>4)*10) + (s&0xf))) * 75;
\r
64 temp = temp + (((f>>4)*10) + (f&0xf));
\r
66 // printf("\n%d%d %d%d %d%d = %06d", m>>4, m&f, s>>4, s&f, f>>4, f&f, temp);
\r
71 void unIndex(unsigned long int index, char *ptr)
\r
75 f = (char) (index % 75);
\r
76 s = (char) ((index/75) % 60);
\r
77 m = (char) (index/(75*60));
\r
78 sprintf(ptr, "%d%d:%d%d:%d%d", m/10, m%10, s/10, s%10, f/10, f%10);
\r
86 char sBinFilename[256];
\r
87 char sOutFilename[256];
\r
89 unsigned long int writepos = 0; // for inplace conversions...
\r
92 #define OUTBUF_SIZE 4*1024*1024
\r
93 #define INBUF_SIZE 4*1024*1024
\r
94 unsigned char OUTBUF[OUTBUF_SIZE];
\r
95 unsigned int OUTBUF_IDX = 0;
\r
96 unsigned char INBUF[INBUF_SIZE];
\r
97 unsigned int INBUF_RIDX = 0;
\r
98 unsigned int INBUF_WIDX = 0;
\r
102 typedef struct track
\r
104 unsigned short mode;
\r
105 unsigned long idx0;
\r
106 unsigned long idx1;
\r
107 unsigned char num[3];
\r
108 unsigned char name[80];
\r
109 unsigned long offset0;
\r
110 unsigned long offset1;
\r
111 unsigned long size; /* track size in bytes */
\r
114 buffered_fread(unsigned char *array, unsigned int size) {
\r
117 if(INBUF_WIDX == 0) {
\r
118 INBUF_WIDX += fread( INBUF, 1, (INBUF_SIZE/size)*size, fdBinFile );
\r
120 if(INBUF_WIDX == 0) return 0; // read failed.
\r
122 for(i = 0; i< size; i++)
\r
125 array[i] = INBUF[INBUF_RIDX++];
\r
126 if((INBUF_RIDX == INBUF_WIDX) && (i < (size -1))) {
\r
127 printf(" Warning: Premature EOF\n");
\r
128 while(i++ < size) { array[i] == 0; }/* zero fill the rest */
\r
133 if(INBUF_RIDX == INBUF_WIDX) {
\r
139 return 1; // read passed
\r
143 void buffered_fwrite(unsigned char *array, unsigned int size) {
\r
145 unsigned long int readpos;
\r
147 if(OUTBUF_IDX+size >= OUTBUF_SIZE) {
\r
149 if(fdOutFile == fdBinFile) {
\r
150 readpos = ftell(fdOutFile);
\r
151 if(0 != fseek(fdOutFile, writepos, SEEK_SET)) {
\r
152 perror("\nbin2iso(fseek)"); exit(1);
\r
156 // printf("\nWriting \n");
\r
157 if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {
\r
158 perror("\nbin2iso(fwrite)");
\r
160 // remove(sOutFilename);
\r
163 if( 1 != fwrite( array, size, 1, fdOutFile )) {
\r
164 perror("\nbin2iso(fwrite)");
\r
166 // remove(sOutFilename);
\r
169 // printf("\nWrote %d bytes \n", OUTBUF_IDX+size);
\r
172 if(fdOutFile == fdBinFile) {
\r
173 writepos = ftell(fdOutFile);
\r
174 if(0 != fseek(fdOutFile, readpos, SEEK_SET)) {
\r
175 perror("\nbin2iso(fseek)"); exit(1);
\r
181 for(idx = 0; idx < size; idx++) {
\r
182 OUTBUF[OUTBUF_IDX + idx] = array[idx];
\r
190 void flush_buffers(void)
\r
192 unsigned long int readpos;
\r
194 if(fdOutFile == fdBinFile) {
\r
195 readpos = ftell(fdOutFile);
\r
196 if(0 != fseek(fdOutFile, writepos, SEEK_SET)) {
\r
197 perror("\nbin2iso(fseek)"); exit(1);
\r
201 if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {
\r
202 perror("\nbin2iso(fwrite)");
\r
204 // remove(sOutFilename);
\r
208 // printf("\nWrote %d bytes \n", OUTBUF_IDX);
\r
213 if(fdOutFile == fdBinFile) {
\r
214 writepos = ftell(fdOutFile);
\r
215 if(0 != fseek(fdOutFile, readpos, SEEK_SET)) {
\r
216 perror("\nbin2iso(fseek)"); exit(1);
\r
225 // presumes Line is preloaded with the "current" line of the file
\r
226 int getTrackinfo(char *Line, tTrack *track)
\r
238 if (strncmp(&Line[2], "TRACK ", 6)==0)
\r
240 strncpy(track->num, &Line[8], 2); track->num[2] = '\0';
\r
242 track->mode = UNKNOWN;
\r
243 if(strncmp(&Line[11], "AUDIO", 5)==0) track->mode = AUDIO;
\r
244 if(strncmp(&Line[11], "MODE1/2352", 10)==0) track->mode = MODE1_2352;
\r
245 if(strncmp(&Line[11], "MODE1/2048", 10)==0) track->mode = MODE1_2048;
\r
246 if(strncmp(&Line[11], "MODE2/2352", 10)==0) track->mode = MODE2_2352;
\r
247 if(strncmp(&Line[11], "MODE2/2336", 10)==0) track->mode = MODE2_2336;
\r
252 strcpy(track->name, sBinFilename);
\r
253 track->name[strlen(sBinFilename)-4] = '\0';
\r
254 strcat(track->name, "-");
\r
255 strcat(track->name, track->num);
\r
257 if( (track->mode == MODE1_2352) ||
\r
258 (track->mode == MODE1_2048) ||
\r
259 (track->mode == MODE2_2352) ||
\r
260 (track->mode == MODE2_2336) )
\r
262 strcat(track->name, ".iso");
\r
263 } else if(track->mode == AUDIO) {
\r
264 strcat(track->name, ".wav");
\r
266 printf("Track %d Unsupported mode\n", track->num);
\r
270 // Get the track indexes
\r
272 if(! fgets( Line, 256, fdCueFile ) ) { break; }
\r
274 if (strncmp(&Line[2], "TRACK ", 6)==0)
\r
276 break; // next track starting
\r
279 if (strncmp(&Line[4], "INDEX ", 6)==0)
\r
281 strncpy(inum, &Line[10], 2); inum[2] = '\0';
\r
282 min = ((Line[13]-'0')<<4) | Line[14]-'0';
\r
283 sec = ((Line[16]-'0')<<4) | Line[17]-'0';
\r
284 block = ((Line[19]-'0')<<4) | Line[20]-'0';
\r
287 if(strcmp(inum, "00")==0) track->idx0 = Index(min, sec, block);
\r
288 else if(strcmp(inum, "01")==0) track->idx1 = Index(min, sec, block);
\r
289 else { printf("Unexpected Index number: %s\n", inum); exit(1); }
\r
292 else if (strncmp(&Line[4], "PREGAP ", 7)==0) { ; /* ignore, handled below */ }
\r
293 else if (strncmp(&Line[4], "FLAGS ", 6)==0) { ; /* ignore */ }
\r
294 else { printf("Unexpected cuefile line: %s\n", Line); }
\r
296 if(track->idx0 == -1) track->idx0 = track->idx1;
\r
297 if(track->idx1 == -1) track->idx1 = track->idx0;
\r
302 void dotrack(short mode, long preidx, long startidx, long endidx, unsigned long offset)
\r
304 unsigned char buf[SIZERAW+100];
\r
305 unsigned long blockswritten = 0;
\r
306 unsigned int uiLastIndex;
\r
308 unsigned int uiCurrentIndex;
\r
310 unsigned int write = 1;
\r
312 tWavHead wavhead = { "RIFF",
\r
316 16, // 16 byte format specifier
\r
317 WINDOWS_PCM, // format
\r
319 44100, // 44,100 Samples/sec
\r
320 176400, // 176,400 Bytes/sec
\r
321 4, // 4 bytes/sample
\r
322 16, // 16 bits/channel
\r
327 uiLastIndex = startidx-1;
\r
328 // Input -- process -- Output
\r
329 if(startidx != 0) printf("\nNote: PreGap = %d frames\n", startidx-preidx);
\r
330 else printf("\nNote: PreGap = %d frames\n", OFFSET); // cd standard: starting offset
\r
331 // - of course this isn't true for bootable cd's...
\r
333 if(sOutFilename[0] != '\0') {
\r
334 printf("Creating %s (%06d,%06d) ", sOutFilename, startidx, endidx-1);
\r
336 printf("Converting (%06d,%06d) ", startidx, endidx-1);
\r
344 printf("Mode1/2048");
\r
347 printf("Mode2/2352");
\r
351 printf("Mode2/2352");
\r
353 printf("Mode1/2048");
\r
356 printf("Mode1/2048");
\r
359 printf("Huh? What's going on?");
\r
364 if(sOutFilename[0] != '\0') {
\r
365 if(NULL == (fdOutFile = fopen (sOutFilename, "wb"))) {
\r
366 perror("bin2iso(fopen)");
\r
368 // printf("\nOpened File %s: %d\n", sOutFilename, fdOutFile);
\r
371 fdOutFile = fdBinFile;
\r
373 if (fdOutFile == NULL) { printf (" Unable to create %s\n", sOutFilename); exit (1); }
\r
375 if(0 != fseek(fdBinFile, offset, SEEK_SET)) {
\r
376 perror("\nbin2iso(fseek)"); exit(1);
\r
380 if(mode == AUDIO) {
\r
381 if( 1 != fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile ) ) { // write placeholder
\r
382 perror("\nbin2iso(fwrite)");
\r
384 // remove(sOutFilename);
\r
390 memset( &buf[0], '\0', sizeof( buf ) );
\r
391 if(mode == MODE2_2336) {
\r
392 unsigned int M = 0, S = 2, F = 0;
\r
393 while( buffered_fread( &buf[16], SIZEISO_MODE2_FORM2) ) {
\r
394 //setup headed area (probably not necessary though...
\r
396 memset( &buf[1], 0xFF, sizeof(buf[0])*10 );
\r
403 if((++F&0xF) == 0xA) F += 6;
\r
405 if(F == 0x75) { S++; F = 0; }
\r
406 if((S&0xF) == 0xA) S += 6;
\r
408 if(S == 0x60) { M++; S = 0; }
\r
409 if((M&0xF) == 0xA) M += 6;
\r
410 // printf("\n%x:%x:%x", M, S, F);
\r
412 buffered_fwrite( buf, SIZERAW );
\r
414 memset( &buf[0], '\0', sizeof( buf ) );
\r
415 if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }
\r
416 if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }
\r
418 } else if (mode == MODE1_2048) {
\r
419 while( buffered_fread( buf, SIZEISO_MODE1) ) {
\r
420 buffered_fwrite( buf, SIZEISO_MODE1 );
\r
422 if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }
\r
423 if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }
\r
426 while( buffered_fread( buf, SIZERAW) ) {
\r
430 buffered_fwrite( buf, SIZERAW );
\r
436 // should put a crc check in here...
\r
438 if( buf[15] != MODE1)
\r
440 printf("\nWarning: Mode Error in bin file!\n");
\r
441 printf(" %02x:%02x:%02x : mode %02x\n", buf[12], buf[13], buf[14], buf[15] );
\r
445 uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;
\r
447 if(uiCurrentIndex != uiLastIndex+1)
\r
449 printf("\nWarning: Frame Error in bin file!\n");
\r
450 printf("Last %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET)/75)/60, ((uiLastIndex+OFFSET)/75)%60, (uiLastIndex+OFFSET)%75, uiLastIndex );
\r
451 printf("Current %02x:%02x:%02x (%d)\n", buf[12], buf[13], buf[14], uiCurrentIndex );
\r
452 printf("Expecting %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET+1)/75)/60, ((uiLastIndex+OFFSET+1)/75)%60, (uiLastIndex+OFFSET+1)%75, uiLastIndex+1 );
\r
457 buffered_fwrite( &buf[16], SIZEISO_MODE1 );
\r
460 uiLastIndex = uiCurrentIndex;
\r
465 if( (buf[15]&0xf) != MODE2)
\r
467 printf("\nWarning: Mode Error in bin file!\n");
\r
468 printf(" %02x:%02x:%02x : mode %02x\n", buf[12], buf[13], buf[14], buf[15] );
\r
472 uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;
\r
474 if(uiCurrentIndex != uiLastIndex+1)
\r
476 printf("\nWarning: Frame Error in bin file!\n");
\r
477 printf("Last %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET)/75)/60, ((uiLastIndex+OFFSET)/75)%60, (uiLastIndex+OFFSET)%75, uiLastIndex );
\r
478 printf("Current %02x:%02x:%02x (%d)\n", buf[12], buf[13], buf[14], uiCurrentIndex );
\r
479 printf("Expecting %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET+1)/75)/60, ((uiLastIndex+OFFSET+1)/75)%60, (uiLastIndex+OFFSET+1)%75, uiLastIndex+1 );
\r
483 if(mode2to1) buffered_fwrite( &buf[16+8], SIZEISO_MODE1 );
\r
484 else if(write) buffered_fwrite( &buf[0], SIZEISO_MODE2_RAW );
\r
487 uiLastIndex = uiCurrentIndex;
\r
491 printf("Unkown Mode\n"); exit(1);
\r
495 memset( &buf[0], '\0', sizeof( buf ) );
\r
496 if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }
\r
497 if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }
\r
500 flush_buffers(); // flushes write buffer
\r
501 // and clears read buffer.
\r
502 if(mode == AUDIO) {
\r
503 wavhead.blocksize = blockswritten*SIZERAW;
\r
504 wavhead.bytestoend = wavhead.blocksize + HEADBYTES;
\r
505 // rewind to the beginning
\r
506 if(0 != fseek(fdOutFile, 0, SEEK_SET)) {
\r
507 perror("\nbin2iso(fseek)"); exit(1);
\r
511 fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile );
\r
518 void doCueFile(void) {
\r
520 unsigned long int binIndex = 0;
\r
521 unsigned long int trackIndex = 0;
\r
522 const int gapThreshold = 20; // look for 0.266 sec gap
\r
523 const int valueThreshold = 800; // look for samples < 700
\r
529 char mode[12] = "AUDIO";
\r
530 char index0[9] = "00:00:00";
\r
531 char index1[9] = "00:00:00";
\r
532 unsigned char buf[SIZERAW+100];
\r
534 printf( "FILE %s BINARY\n", sBinFilename);
\r
535 fprintf(fdCueFile, "FILE %s BINARY\n", sBinFilename);
\r
536 memset( buf, '\0', sizeof( buf ) );
\r
537 while( fread( buf, 1, SIZERAW, fdBinFile ) ) {
\r
538 if(trackIndex == 0) {
\r
539 if ( (buf[0] == 0x00) &&
\r
540 (buf[1] == 0xFF) &&
\r
541 (buf[2] == 0xFF) &&
\r
542 (buf[3] == 0xFF) &&
\r
543 (buf[4] == 0xFF) &&
\r
544 (buf[5] == 0xFF) &&
\r
545 (buf[6] == 0xFF) &&
\r
546 (buf[7] == 0xFF) &&
\r
547 (buf[8] == 0xFF) &&
\r
548 (buf[9] == 0xFF) &&
\r
549 (buf[10] == 0xFF) &&
\r
552 sprintf(mode, "MODE%d/2352", buf[15]);
\r
554 sprintf(mode, "AUDIO");
\r
557 if(binIndex == 0) {
\r
558 printf( " TRACK %02d %s\n", track, mode);
\r
559 fprintf(fdCueFile, " TRACK %02d %s\n", track, mode);
\r
560 printf( " INDEX 01 %s\n", index0);
\r
561 fprintf(fdCueFile, " INDEX 01 %s\n", index0);
\r
564 for(i = 0; i < SIZERAW; i+=2) {
\r
566 value = ((value << 8) | buf[i]);
\r
567 // printf("%f %i\n",(1.0/75)*binIndex, value);
\r
568 if(abs(value) > valueThreshold) {
\r
573 // if(i == SIZERAW) printf("%f ~blank~\n", (1.0/75)*binIndex);
\r
574 if(blank == 1) count++;
\r
575 else if (gapon == 1) {
\r
577 unIndex(binIndex-count, index0);
\r
579 unIndex(binIndex, index1);
\r
580 printf( " TRACK %02d %s\n", track, mode);
\r
581 fprintf(fdCueFile, " TRACK %02d %s\n", track, mode);
\r
582 printf( " INDEX 00 %s\n", index0);
\r
583 fprintf(fdCueFile, " INDEX 00 %s\n", index0);
\r
584 printf( " INDEX 01 %s\n", index1);
\r
585 fprintf(fdCueFile, " INDEX 01 %s\n", index1);
\r
588 if((count > gapThreshold) && (gapon == 0)) {
\r
589 gapon = 1; track++;
\r
593 memset( buf, '\0', sizeof( buf ) );
\r
599 // return 0 to when no data found, 1 when there is.
\r
600 int checkGaps(FILE *fdBinFile, tTrack tracks[], int nTracks) {
\r
602 unsigned long int j;
\r
603 unsigned char buf[SIZERAW];
\r
609 if(nTracks == 2) { return 0; }; // don't need to bother with single track images
\r
611 printf("Checking gap data:\n");
\r
613 for (i = 0; i < nTracks; i++) {
\r
614 if((tracks[i].offset0 != tracks[i].offset1) && (tracks[i-1].mode == AUDIO)) {
\r
615 if(0 != fseek(fdBinFile, tracks[i].offset0, SEEK_SET)) {
\r
616 perror("\nbin2iso(fseek)"); exit(1);
\r
619 for(j = tracks[i].idx0; j < tracks[i].idx1; j++) {
\r
620 if(0 == fread( buf, SIZERAW, 1, fdBinFile ) ) {
\r
621 perror("bin2iso(fread)");
\r
624 for(k = 0; k < SIZERAW; k+=2) {
\r
626 value = ((value << 8) | buf[k]);
\r
630 // printf("%10d: %2x\n", count ,value );
\r
635 printf(" Track%02d - %d values of Non-Zero gap data encountered\n", i-1, count);
\r
636 if((count > SIZERAW/2/2) && (writegap == 0)) {
\r
637 printf(" -->Threashold reached\n"); writegap = 1;
\r
645 /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */
\r
647 int main(int argc, char **argv) {
\r
648 unsigned long int count = 0;
\r
649 // int printon = 0;
\r
654 // int writegap = -1; // auto detect pregap data action by default.
\r
655 int writegap = 1; // keep pregap data by default.
\r
656 int no_overburn = 0;
\r
657 int createCue = 0;
\r
658 char sTrack[3] = "00";
\r
659 int doOneTrack = 0;
\r
665 tTrack tracks[100];
\r
670 sOutFilename[0] = '\0';
\r
672 /* Tell them what I am. */
\r
673 printf ("\n%s, %s", __DATE__, __TIME__);
\r
674 printf ("\nbin2iso V1.9b - Converts RAW format (.bin) files to ISO/WAV format");
\r
675 printf ("\n Bob Doiron, ICQ#280251 \n");
\r
676 printf ("\nCheck for updates at http://users.andara.com/~doiron\n\n");
\r
678 printf("Usage: bin2iso <cuefile> [<output dir>] [-[a]wg] [-t XX] [-i] [-nob]\n");
\r
679 printf("or : bin2iso <cuefile> -c <binfile>\n");
\r
681 printf("Where:\n");
\r
682 printf(" <cuefile> - the .cue file that belongs to the .bin file to \n");
\r
683 printf(" be converted\n");
\r
684 printf(" <output dir> - the output directory (defaults to current dir) \n");
\r
685 printf(" -nwg - indicates that audio data found in the track \n");
\r
686 printf(" 'gaps' shouldn't be appended to the audio tracks\n");
\r
687 printf(" -awg - looks for non-zero data in the 'gaps', if found\n");
\r
688 printf(" then gaps are appended to audio tracks. Looks \n");
\r
689 printf(" for more than 1/2 of a sector of non-zero values\n");
\r
690 printf(" (%d values), \n", SIZERAW/2/2);
\r
691 printf(" -t XX - Extracts the XX'th track. \n");
\r
692 printf(" -i - Performs the conversion 'in place'. Meaning it \n");
\r
693 printf(" truncates the binfile after each track is \n");
\r
694 printf(" created to minimize diskspace requirements. \n");
\r
695 printf(" [not valid with -t] \n");
\r
696 printf(" -nob - Doesn't use overburn data past %ld sectors. \n", CD74_MAX_SECTORS);
\r
697 printf(" This of course presumes that the data is not \n");
\r
698 printf(" useful. \n");
\r
699 printf(" -c - Attempts to create a <cuefile> from an existing\n");
\r
700 printf(" <binfile> \n");
\r
704 strcpy(sOutdir, "./"); // default path
\r
707 for (i=2; i < argc; i++) {
\r
708 if (argv[i][0] == '-') {
\r
709 /* if (strncmp(&(argv[i][1]), "wg", 2)==0) {
\r
713 if (strncmp(&(argv[i][1]), "awg", 3)==0) {
\r
715 printf("Note: Auto-detecting pregap data\n");
\r
716 } else if (strncmp(&(argv[i][1]), "nwg", 3)==0) {
\r
718 } else if (strncmp(&(argv[i][1]), "m2to1", 5)==0) {
\r
720 printf("Note: Converting Mode2 ISO to Mode1\n");
\r
721 } else if (strncmp(&(argv[i][1]), "t", 1)==0) {
\r
722 strcpy(sTrack, argv[i+1]);
\r
725 } else if (strncmp(&(argv[i][1]), "i", 1)==0) {
\r
726 if(doOneTrack == 1) { printf("Invalid combination of options...\n"); exit(1); }
\r
727 printf("Bin file will be truncated after each track created\n");
\r
729 } else if (strncmp(&(argv[i][1]), "c", 1)==0) {
\r
731 strcpy(sBinFilename, argv[i+1]);
\r
733 } else if (strncmp(&(argv[i][1]), "nob", 3)==0) {
\r
737 strcpy(sOutdir, argv[2]);
\r
741 if(createCue == 1) {
\r
742 fdBinFile = fopen (sBinFilename, "rb");
\r
743 if (fdBinFile == NULL) {
\r
744 printf ("Unable to open %s\n", sBinFilename);
\r
747 fdCueFile = fopen (argv[1], "w");
\r
748 if (fdCueFile == NULL) {
\r
749 printf ("Unable to create %s\n", argv[1]);
\r
753 if((strcmp(&sBinFilename[strlen(sBinFilename)-4], ".wav")==0) ||
\r
754 (strcmp(&sBinFilename[strlen(sBinFilename)-4], ".WAV")==0) ) {
\r
755 printf(".wav binfile - Skipping wav header\n");
\r
756 fread( sLine, 1, sizeof(tWavHead), fdBinFile );
\r
762 fdCueFile = fopen (argv[1], "r");
\r
763 if (fdCueFile == NULL) {
\r
764 printf ("Unable to open %s\n", argv[1]);
\r
768 // get bin filename from cuefile... why? why not.
\r
769 if(! fgets( sLine, 256, fdCueFile ) ) {
\r
770 printf ("Error Reading Cuefile\n");
\r
773 if (strncmp(sLine, "FILE ", 5)==0) {
\r
776 q = 0; // track open and closed quotes
\r
778 sBinFilename[j] = sLine[5+i];
\r
781 if ((sBinFilename[j-1] == '\\') || (sBinFilename[j-1] == '/')) { j = 0; } //strip out path info
\r
782 if (sBinFilename[j-1] == '"') { j--; q++;} // strip out quotes
\r
783 } while ((sLine[5+i-1] != ' ') || (q == 1));
\r
784 sBinFilename[j] = '\0';
\r
785 //bug?? Why did a trailing space show up??
\r
786 while(sBinFilename[--j] == ' ') sBinFilename[j] = '\0';
\r
788 // do not need to convert to lower case on unix system
\r
789 // strlwr(sBinFilename);
\r
792 printf ("Error: Filename not found on first line of cuefile.\n", argv[1]);
\r
796 // Open the bin file
\r
797 if(doInPlace == 1) {
\r
798 fdBinFile = fopen (sBinFilename, "rb+");
\r
800 fdBinFile = fopen (sBinFilename, "rb");
\r
802 if (fdBinFile == NULL) {
\r
803 printf ("Unable to open %s\n", sBinFilename);
\r
804 perror("\nbin2iso(fopen)");
\r
809 if(! fgets( sLine, 256, fdCueFile ) ) {
\r
810 printf ("Error Reading Cuefile\n");
\r
814 if(strlen(sOutdir) > 0) {
\r
815 if((sOutdir[strlen(sOutdir)-1] != '/' ) && (sOutdir[strlen(sOutdir)-1] != ':' ) ) {
\r
816 strcat(sOutdir, "/");
\r
820 while(!feof(fdCueFile)) {
\r
821 getTrackinfo(sLine, &tracks[nTracks++]);
\r
823 tracks[nTracks].idx0 = tracks[nTracks].idx1 = -1;
\r
825 switch (tracks[0].mode) {
\r
827 tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE1;
\r
830 tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE2_FORM2;
\r
832 default: // AUDIO, MODE1_2352, MODE2_2352:
\r
833 tracks[0].offset0 = tracks[0].idx0*SIZERAW;
\r
839 if(0 != fseek(fdBinFile, 0, SEEK_END)) {
\r
840 perror("\nbin2iso(fseek)"); exit(1);
\r
843 tracks[nTracks].offset0 = tracks[nTracks].offset1 = ftell(fdBinFile);
\r
845 for(i = 0; i < nTracks; i++) {
\r
846 switch (tracks[i].mode) {
\r
848 tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZEISO_MODE1;
\r
849 if(tracks[i+1].idx0 != -1)
\r
850 tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZEISO_MODE1;
\r
852 tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZEISO_MODE1 + tracks[i].idx1;
\r
853 if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZEISO_MODE1) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");
\r
857 tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZEISO_MODE2_FORM2;
\r
858 if(tracks[i+1].idx0 != -1)
\r
859 tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZEISO_MODE2_FORM2;
\r
861 tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZEISO_MODE2_FORM2 + tracks[i].idx1;
\r
862 if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZEISO_MODE2_FORM2) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");
\r
865 default: // AUDIO, MODE1_2352, MODE2_2352:
\r
866 tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZERAW;
\r
867 if(tracks[i+1].idx0 != -1)
\r
868 tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZERAW;
\r
870 tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZERAW + tracks[i].idx1;
\r
871 if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZERAW) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");
\r
877 // if not allowing overburn, then create a new track to hold extra data...
\r
878 if(no_overburn == 1) {
\r
880 if(tracks[i].idx0 > CD74_MAX_SECTORS) {
\r
881 tracks[i+1] = tracks[nTracks];
\r
882 strcpy(tracks[i].name, "obdatatemp.bin");
\r
883 tracks[i].idx0 = CD74_MAX_SECTORS;
\r
884 tracks[i].idx1 = CD74_MAX_SECTORS;
\r
885 switch (tracks[i-1].mode) {
\r
887 tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE1;
\r
890 tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE2_FORM2;
\r
892 default: // AUDIO, MODE1_2352, MODE2_2352:
\r
893 tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZERAW;
\r
896 tracks[i].offset1 = tracks[i].offset0;
\r
897 tracks[i].mode = tracks[i-1].mode;
\r
904 for(i = 0; i < nTracks; i++) {
\r
905 switch (tracks[i].mode) {
\r
907 tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZERAW ) * SIZEISO_MODE1;
\r
910 tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZEISO_MODE2_FORM2 ) * SIZERAW;
\r
912 default: // MODE1_2048, MODE2_2352, AUDIO
\r
913 tracks[i].size = tracks[i+1].offset1 - tracks[i].offset1;
\r
918 if(writegap == -1) { writegap = checkGaps(fdBinFile, tracks, nTracks); }
\r
921 printf("Note: Appending pregap data to end of audio tracks\n");
\r
923 printf("Note: Discarding pregap data\n");
\r
926 for(i = 0; i <= nTracks-1; i++) {
\r
927 printf("%s (%3d Mb) - sectors %06ld:%06ld (offset %09ld:%09ld)\n",
\r
929 tracks[i].size/(1024*1024),
\r
931 ( ((writegap == 0) || (tracks[i].mode != AUDIO)) ? tracks[i+1].idx0 : tracks[i+1].idx1)-1,
\r
932 tracks[i].offset1,
\r
933 ( ((writegap == 0) || (tracks[i].mode != AUDIO)) ? tracks[i+1].offset0 : tracks[i+1].offset1)-1
\r
938 if( (((mode2to1 != 1) && (tracks[0].mode == MODE2_2352)) || (tracks[0].mode == MODE1_2048)) && (nTracks == 1) ) {
\r
939 if(tracks[0].mode == MODE2_2352) { printf("Mode2/2352"); }
\r
940 if(tracks[0].mode == MODE1_2048) { printf("Mode1/2048"); }
\r
941 printf(" single track bin file indicated by cue file\n");
\r
943 if( 0 != rename(sBinFilename, tracks[0].name) ) {
\r
944 perror("\nbin2iso(rename)");
\r
947 printf("%s renamed to %s\n", sBinFilename, tracks[0].name);
\r
952 for(i=nTracks-1; i>=0; i--) {
\r
953 trackA = tracks[i];
\r
954 trackB = tracks[i+1];
\r
955 // audio can't be done in the bin file due to header.
\r
956 // 2336 can't either because it's expanded to 2352
\r
957 if((doInPlace == 1) && (i == 0) && (trackA.mode != AUDIO) && (trackA.mode != MODE2_2336) ) {
\r
958 sOutFilename[0] = '\0';
\r
960 strcpy(sOutFilename, sOutdir);
\r
961 strcat(sOutFilename, trackA.name);
\r
963 if ( ((doOneTrack == 1) && strcmp(trackA.num, sTrack)==0) || (doOneTrack == 0) ) {
\r
965 if(!((i == 0) && ((trackA.mode == MODE2_2352)||(trackA.mode == MODE1_2048)) && (doInPlace == 1) )){
\r
966 if (!writegap || (trackA.mode != AUDIO)) { // when not Audio, don't append.
\r
967 dotrack(trackA.mode, trackA.idx0, trackA.idx1, trackB.idx0, trackA.offset1);
\r
969 /* if(trackA.idx0 == 0) // handles first track with pregap.
\r
970 dotrack(trackA.mode, 0, trackA.idx1, trackB.idx1, trackA.offset1);
\r
973 dotrack(trackA.mode, trackA.idx1, trackA.idx1, trackB.idx1, trackA.offset1);
\r
977 fclose(fdBinFile); // just close bin file. Already MODE1_2048 or MODE2_2352
\r
979 if( (doOneTrack == 0) && (doInPlace == 1) ) {
\r
980 if( (i != 0) || ( (i == 0) && ((trackA.mode == AUDIO)||(trackA.mode == MODE2_2336)) ) ) {
\r
981 printf("Truncating bin file to %ld bytes\n", trackA.offset1);
\r
982 if( -1 == ftruncate(fileno(fdBinFile), trackA.offset1) ) {
\r
983 perror("\nbin2iso(_chsize)");
\r
987 printf("Renaming %s to %s\n", sBinFilename, trackA.name);
\r
989 if( 0 != rename(sBinFilename, trackA.name) ) {
\r
990 perror("\nbin2iso(rename)");
\r
994 // fix writepos for case when simply truncating...
\r
995 if((trackA.mode == MODE2_2352) || (trackA.mode == MODE1_2048)){ writepos = trackB.offset0; }
\r
997 printf("Truncating to %ld bytes\n", writepos);
\r
999 fdBinFile = fopen(trackA.name, "rb+"); // gets closed in doTrack...
\r
1000 if(fdBinFile == NULL) { perror("bin2iso(fopen)"); exit(1); }
\r
1002 if( -1 == ftruncate(fileno(fdBinFile), writepos) ) {
\r
1003 perror("\nbin2iso(_chsize)");
\r
1010 fclose(fdCueFile);
\r
1011 fclose(fdBinFile);
\r