--- /dev/null
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#define DEBUG 0\r
+#define CHECK 0 /* don't bother checking bin for validity... */\r
+\r
+//----------------Wave Stuff---------------------/\r
+typedef unsigned char BYTE1 ;\r
+typedef unsigned short int BYTE2 ;\r
+typedef unsigned long int BYTE4 ;\r
+\r
+typedef struct wavHdr {\r
+ BYTE1 riff[4];\r
+ BYTE4 bytestoend;\r
+ BYTE1 wavetxt[4];\r
+ BYTE1 fmttxt[4];\r
+ BYTE4 formatsize; // 16 byte format specifier\r
+ BYTE2 format; // Windows PCM\r
+ BYTE2 channels; // 2 channels \r
+ BYTE4 samplerate; // 44,100 Samples/sec\r
+ BYTE4 avgbyterate; // 176,400 Bytes/sec\r
+ BYTE2 samplebytes; // 4 bytes/sample\r
+ BYTE2 channelbits; // 16 bits/channel\r
+ BYTE1 datatxt[4];\r
+ BYTE4 blocksize;\r
+} tWavHead;\r
+\r
+#define HEADBYTES 36\r
+#define WINDOWS_PCM 0x0001\r
+//-------------------------------------------------/\r
+\r
+/* G L O B A L D E F I N E S */\r
+#define byte unsigned char\r
+#define SIZERAW 2352\r
+#define SIZEISO_MODE1 2048\r
+#define SIZEISO_MODE2_RAW 2352\r
+#define SIZEISO_MODE2_FORM1 2048\r
+#define SIZEISO_MODE2_FORM2 2336\r
+#define AUDIO 0\r
+#define MODE1 1\r
+#define MODE2 2\r
+#define MODE1_2352 10\r
+#define MODE2_2352 20\r
+#define MODE1_2048 30\r
+#define MODE2_2336 40\r
+\r
+#define RAWDATA FF // using this for leftover data when truncating for non-overburn\r
+\r
+#define PROG_INTERVAL 1024\r
+#define UNKNOWN -1\r
+#define OFFSET 150 \r
+// got this from easycd pro by looking at a blank disk so it may be off...\r
+#define CD74_MAX_SECTORS 334873 // 653.75 Mb \r
+ \r
+\r
+unsigned long int Index(char m, char s, char f)\r
+{\r
+ unsigned long int temp;\r
+\r
+\r
+ temp = (((m>>4)*10) + (m&0xf)) * 60;\r
+ temp = ( temp + (((s>>4)*10) + (s&0xf))) * 75;\r
+ temp = temp + (((f>>4)*10) + (f&0xf));\r
+ \r
+// printf("\n%d%d %d%d %d%d = %06d", m>>4, m&f, s>>4, s&f, f>>4, f&f, temp);\r
+ \r
+ return temp;\r
+}\r
+\r
+void unIndex(unsigned long int index, char *ptr)\r
+{\r
+ char m, s, f;\r
+\r
+ f = (char) (index % 75);\r
+ s = (char) ((index/75) % 60);\r
+ m = (char) (index/(75*60));\r
+ sprintf(ptr, "%d%d:%d%d:%d%d", m/10, m%10, s/10, s%10, f/10, f%10);\r
+\r
+}\r
+\r
+// global variables\r
+FILE* fdBinFile;\r
+FILE* fdCueFile;\r
+FILE* fdOutFile;\r
+char sBinFilename[256];\r
+char sOutFilename[256];\r
+\r
+unsigned long int writepos = 0; // for inplace conversions...\r
+\r
+ \r
+#define OUTBUF_SIZE 4*1024*1024\r
+#define INBUF_SIZE 4*1024*1024\r
+unsigned char OUTBUF[OUTBUF_SIZE]; \r
+unsigned int OUTBUF_IDX = 0;\r
+unsigned char INBUF[INBUF_SIZE]; \r
+unsigned int INBUF_RIDX = 0;\r
+unsigned int INBUF_WIDX = 0;\r
+\r
+int mode2to1 = 0;\r
+\r
+typedef struct track\r
+{\r
+ unsigned short mode;\r
+ unsigned long idx0;\r
+ unsigned long idx1;\r
+ unsigned char num[3];\r
+ unsigned char name[80];\r
+ unsigned long offset0;\r
+ unsigned long offset1;\r
+ unsigned long size; /* track size in bytes */\r
+} tTrack;\r
+\r
+buffered_fread(unsigned char *array, unsigned int size) {\r
+ unsigned int i;\r
+ \r
+ if(INBUF_WIDX == 0) { \r
+ INBUF_WIDX += fread( INBUF, 1, (INBUF_SIZE/size)*size, fdBinFile );\r
+ }\r
+ if(INBUF_WIDX == 0) return 0; // read failed.\r
+ \r
+ for(i = 0; i< size; i++) \r
+ {\r
+\r
+ array[i] = INBUF[INBUF_RIDX++];\r
+ if((INBUF_RIDX == INBUF_WIDX) && (i < (size -1))) {\r
+ printf(" Warning: Premature EOF\n");\r
+ while(i++ < size) { array[i] == 0; }/* zero fill the rest */\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(INBUF_RIDX == INBUF_WIDX) {\r
+ INBUF_RIDX = 0; \r
+ INBUF_WIDX = 0; \r
+ }\r
+\r
+\r
+ return 1; // read passed\r
+ \r
+}\r
+\r
+void buffered_fwrite(unsigned char *array, unsigned int size) {\r
+ unsigned int idx;\r
+ unsigned long int readpos;\r
+ \r
+ if(OUTBUF_IDX+size >= OUTBUF_SIZE) { \r
+\r
+ if(fdOutFile == fdBinFile) {\r
+ readpos = ftell(fdOutFile);\r
+ if(0 != fseek(fdOutFile, writepos, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+ }\r
+\r
+ // printf("\nWriting \n");\r
+ if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {\r
+ perror("\nbin2iso(fwrite)");\r
+ fclose(fdOutFile);\r
+ // remove(sOutFilename);\r
+ exit(1);\r
+ }\r
+ if( 1 != fwrite( array, size, 1, fdOutFile )) {\r
+ perror("\nbin2iso(fwrite)");\r
+ fclose(fdOutFile);\r
+ // remove(sOutFilename);\r
+ exit(1);\r
+ }\r
+// printf("\nWrote %d bytes \n", OUTBUF_IDX+size);\r
+ OUTBUF_IDX = 0;\r
+\r
+ if(fdOutFile == fdBinFile) {\r
+ writepos = ftell(fdOutFile);\r
+ if(0 != fseek(fdOutFile, readpos, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+ }\r
+\r
+\r
+ } else {\r
+ for(idx = 0; idx < size; idx++) {\r
+ OUTBUF[OUTBUF_IDX + idx] = array[idx];\r
+ }\r
+ OUTBUF_IDX+=size;\r
+ }\r
+ \r
+}\r
+\r
+\r
+void flush_buffers(void)\r
+{\r
+ unsigned long int readpos;\r
+\r
+ if(fdOutFile == fdBinFile) {\r
+ readpos = ftell(fdOutFile);\r
+ if(0 != fseek(fdOutFile, writepos, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+ }\r
+\r
+ if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {\r
+ perror("\nbin2iso(fwrite)");\r
+ fclose(fdOutFile);\r
+ // remove(sOutFilename);\r
+ exit(1);\r
+ }\r
+\r
+// printf("\nWrote %d bytes \n", OUTBUF_IDX);\r
+ OUTBUF_IDX = 0;\r
+ INBUF_RIDX = 0;\r
+ INBUF_WIDX = 0;\r
+\r
+ if(fdOutFile == fdBinFile) {\r
+ writepos = ftell(fdOutFile);\r
+ if(0 != fseek(fdOutFile, readpos, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+ }\r
+\r
+\r
+}\r
+\r
+\r
+\r
+// presumes Line is preloaded with the "current" line of the file\r
+int getTrackinfo(char *Line, tTrack *track)\r
+{\r
+// char tnum[3];\r
+ char inum[3];\r
+ char min;\r
+ char sec;\r
+ char block;\r
+ \r
+ track->idx0 = -1;\r
+ track->idx1 = -1;\r
+ \r
+ // Get the 'mode'\r
+ if (strncmp(&Line[2], "TRACK ", 6)==0) \r
+ {\r
+ strncpy(track->num, &Line[8], 2); track->num[2] = '\0';\r
+\r
+ track->mode = UNKNOWN;\r
+ if(strncmp(&Line[11], "AUDIO", 5)==0) track->mode = AUDIO;\r
+ if(strncmp(&Line[11], "MODE1/2352", 10)==0) track->mode = MODE1_2352;\r
+ if(strncmp(&Line[11], "MODE1/2048", 10)==0) track->mode = MODE1_2048;\r
+ if(strncmp(&Line[11], "MODE2/2352", 10)==0) track->mode = MODE2_2352;\r
+ if(strncmp(&Line[11], "MODE2/2336", 10)==0) track->mode = MODE2_2336;\r
+ }\r
+ else return(1);\r
+ \r
+ // Set the name\r
+ strcpy(track->name, sBinFilename);\r
+ track->name[strlen(sBinFilename)-4] = '\0';\r
+ strcat(track->name, "-");\r
+ strcat(track->name, track->num);\r
+\r
+ if( (track->mode == MODE1_2352) || \r
+ (track->mode == MODE1_2048) || \r
+ (track->mode == MODE2_2352) || \r
+ (track->mode == MODE2_2336) )\r
+ {\r
+ strcat(track->name, ".iso");\r
+ } else if(track->mode == AUDIO) {\r
+ strcat(track->name, ".wav");\r
+ } else {\r
+ printf("Track %d Unsupported mode\n", track->num);\r
+ return(1);\r
+ }\r
+\r
+ // Get the track indexes\r
+ while(1) {\r
+ if(! fgets( Line, 256, fdCueFile ) ) { break; }\r
+\r
+ if (strncmp(&Line[2], "TRACK ", 6)==0) \r
+ { \r
+ break; // next track starting\r
+ }\r
+\r
+ if (strncmp(&Line[4], "INDEX ", 6)==0) \r
+ {\r
+ strncpy(inum, &Line[10], 2); inum[2] = '\0';\r
+ min = ((Line[13]-'0')<<4) | Line[14]-'0';\r
+ sec = ((Line[16]-'0')<<4) | Line[17]-'0';\r
+ block = ((Line[19]-'0')<<4) | Line[20]-'0';\r
+ \r
+ \r
+ if(strcmp(inum, "00")==0) track->idx0 = Index(min, sec, block);\r
+ else if(strcmp(inum, "01")==0) track->idx1 = Index(min, sec, block);\r
+ else { printf("Unexpected Index number: %s\n", inum); exit(1); } \r
+ \r
+ }\r
+ else if (strncmp(&Line[4], "PREGAP ", 7)==0) { ; /* ignore, handled below */ }\r
+ else if (strncmp(&Line[4], "FLAGS ", 6)==0) { ; /* ignore */ }\r
+ else { printf("Unexpected cuefile line: %s\n", Line); }\r
+ }\r
+ if(track->idx0 == -1) track->idx0 = track->idx1;\r
+ if(track->idx1 == -1) track->idx1 = track->idx0;\r
+ return(0);\r
+} \r
+\r
+\r
+void dotrack(short mode, long preidx, long startidx, long endidx, unsigned long offset) \r
+{\r
+ unsigned char buf[SIZERAW+100];\r
+ unsigned long blockswritten = 0;\r
+ unsigned int uiLastIndex;\r
+#if CHECK\r
+ unsigned int uiCurrentIndex;\r
+#endif\r
+ unsigned int write = 1;\r
+ \r
+ tWavHead wavhead = { "RIFF", \r
+ 0, \r
+ "WAVE", \r
+ "fmt ", \r
+ 16, // 16 byte format specifier\r
+ WINDOWS_PCM, // format\r
+ 2, // 2 Channels \r
+ 44100, // 44,100 Samples/sec \r
+ 176400, // 176,400 Bytes/sec\r
+ 4, // 4 bytes/sample\r
+ 16, // 16 bits/channel\r
+ "data", \r
+ 0 };\r
+ \r
+ \r
+ uiLastIndex = startidx-1;\r
+ // Input -- process -- Output \r
+ if(startidx != 0) printf("\nNote: PreGap = %d frames\n", startidx-preidx);\r
+ else printf("\nNote: PreGap = %d frames\n", OFFSET); // cd standard: starting offset\r
+ // - of course this isn't true for bootable cd's...\r
+\r
+ if(sOutFilename[0] != '\0') {\r
+ printf("Creating %s (%06d,%06d) ", sOutFilename, startidx, endidx-1);\r
+ } else {\r
+ printf("Converting (%06d,%06d) ", startidx, endidx-1);\r
+ }\r
+ switch(mode)\r
+ {\r
+ case AUDIO:\r
+ printf("Audio");\r
+ break; \r
+ case MODE1_2352:\r
+ printf("Mode1/2048");\r
+ break;\r
+ case MODE2_2336:\r
+ printf("Mode2/2352");\r
+ break;\r
+ case MODE2_2352:\r
+ if(mode2to1 != 1) \r
+ printf("Mode2/2352");\r
+ else \r
+ printf("Mode1/2048");\r
+ break;\r
+ case MODE1_2048:\r
+ printf("Mode1/2048");\r
+ break;\r
+ default:\r
+ printf("Huh? What's going on?");\r
+ exit(1);\r
+ }\r
+ printf(" : ");\r
+ \r
+ if(sOutFilename[0] != '\0') {\r
+ if(NULL == (fdOutFile = fopen (sOutFilename, "wb"))) {\r
+ perror("bin2iso(fopen)");\r
+ }\r
+// printf("\nOpened File %s: %d\n", sOutFilename, fdOutFile);\r
+\r
+ } else {\r
+ fdOutFile = fdBinFile;\r
+ }\r
+ if (fdOutFile == NULL) { printf (" Unable to create %s\n", sOutFilename); exit (1); }\r
+ \r
+ if(0 != fseek(fdBinFile, offset, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+\r
+#if (DEBUG == 0)\r
+ if(mode == AUDIO) {\r
+ if( 1 != fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile ) ) { // write placeholder\r
+ perror("\nbin2iso(fwrite)");\r
+ fclose(fdOutFile);\r
+ // remove(sOutFilename);\r
+ exit(1);\r
+ }\r
+ }\r
+#endif \r
+ \r
+ memset( &buf[0], '\0', sizeof( buf ) );\r
+ if(mode == MODE2_2336) {\r
+ unsigned int M = 0, S = 2, F = 0;\r
+ while( buffered_fread( &buf[16], SIZEISO_MODE2_FORM2) ) {\r
+ //setup headed area (probably not necessary though...\r
+ //buf[0] = 0;\r
+ memset( &buf[1], 0xFF, sizeof(buf[0])*10 );\r
+ //buf[11] = 0;\r
+ buf[12] = M;\r
+ buf[13] = S;\r
+ buf[14] = F;\r
+ buf[15] = MODE2;\r
+ \r
+ if((++F&0xF) == 0xA) F += 6;\r
+\r
+ if(F == 0x75) { S++; F = 0; } \r
+ if((S&0xF) == 0xA) S += 6;\r
+ \r
+ if(S == 0x60) { M++; S = 0; }\r
+ if((M&0xF) == 0xA) M += 6;\r
+// printf("\n%x:%x:%x", M, S, F);\r
+ \r
+ buffered_fwrite( buf, SIZERAW ); \r
+ uiLastIndex++;\r
+ memset( &buf[0], '\0', sizeof( buf ) );\r
+ if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }\r
+ if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }\r
+ }\r
+ } else if (mode == MODE1_2048) {\r
+ while( buffered_fread( buf, SIZEISO_MODE1) ) { \r
+ buffered_fwrite( buf, SIZEISO_MODE1 ); \r
+ uiLastIndex++;\r
+ if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }\r
+ if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }\r
+ }\r
+ } else {\r
+ while( buffered_fread( buf, SIZERAW) ) {\r
+ switch(mode) {\r
+ case AUDIO:\r
+#if (DEBUG == 0)\r
+ buffered_fwrite( buf, SIZERAW );\r
+#endif \r
+ uiLastIndex++;\r
+ blockswritten++;\r
+ break;\r
+ case MODE1_2352:\r
+ // should put a crc check in here...\r
+#if CHECK\r
+ if( buf[15] != MODE1) \r
+ { \r
+ printf("\nWarning: Mode Error in bin file!\n"); \r
+ printf(" %02x:%02x:%02x : mode %02x\n", buf[12], buf[13], buf[14], buf[15] ); \r
+ //exit(1);\r
+ }\r
+ \r
+ uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;\r
+ \r
+ if(uiCurrentIndex != uiLastIndex+1)\r
+ { \r
+ printf("\nWarning: Frame Error in bin file!\n"); \r
+ printf("Last %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET)/75)/60, ((uiLastIndex+OFFSET)/75)%60, (uiLastIndex+OFFSET)%75, uiLastIndex ); \r
+ printf("Current %02x:%02x:%02x (%d)\n", buf[12], buf[13], buf[14], uiCurrentIndex ); \r
+ printf("Expecting %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET+1)/75)/60, ((uiLastIndex+OFFSET+1)/75)%60, (uiLastIndex+OFFSET+1)%75, uiLastIndex+1 ); \r
+ \r
+ }\r
+#endif\r
+#if (DEBUG == 0)\r
+ buffered_fwrite( &buf[16], SIZEISO_MODE1 );\r
+#endif\r
+#if CHECK\r
+ uiLastIndex = uiCurrentIndex;\r
+#endif\r
+ break;\r
+ case MODE2_2352:\r
+#if CHECK\r
+ if( (buf[15]&0xf) != MODE2) \r
+ { \r
+ printf("\nWarning: Mode Error in bin file!\n"); \r
+ printf(" %02x:%02x:%02x : mode %02x\n", buf[12], buf[13], buf[14], buf[15] ); \r
+ //exit(1);\r
+ }\r
+\r
+ uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;\r
+\r
+ if(uiCurrentIndex != uiLastIndex+1)\r
+ { \r
+ printf("\nWarning: Frame Error in bin file!\n"); \r
+ printf("Last %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET)/75)/60, ((uiLastIndex+OFFSET)/75)%60, (uiLastIndex+OFFSET)%75, uiLastIndex ); \r
+ printf("Current %02x:%02x:%02x (%d)\n", buf[12], buf[13], buf[14], uiCurrentIndex ); \r
+ printf("Expecting %02d:%02d:%02d (%d)\n", ((uiLastIndex+OFFSET+1)/75)/60, ((uiLastIndex+OFFSET+1)/75)%60, (uiLastIndex+OFFSET+1)%75, uiLastIndex+1 ); \r
+ }\r
+#endif\r
+#if (DEBUG == 0)\r
+ if(mode2to1) buffered_fwrite( &buf[16+8], SIZEISO_MODE1 );\r
+ else if(write) buffered_fwrite( &buf[0], SIZEISO_MODE2_RAW );\r
+#endif\r
+#if CHECK\r
+ uiLastIndex = uiCurrentIndex;\r
+#endif\r
+ break;\r
+ default:\r
+ printf("Unkown Mode\n"); exit(1);\r
+ break;\r
+ } \r
+ \r
+ memset( &buf[0], '\0', sizeof( buf ) );\r
+ if (startidx%PROG_INTERVAL == 0) { printf("\b\b\b\b\b\b%06d", startidx); }\r
+ if (++startidx == endidx) { printf("\b\b\b\b\b\bComplete\n"); break; }\r
+ }\r
+ }\r
+ flush_buffers(); // flushes write buffer\r
+ // and clears read buffer.\r
+ if(mode == AUDIO) {\r
+ wavhead.blocksize = blockswritten*SIZERAW;\r
+ wavhead.bytestoend = wavhead.blocksize + HEADBYTES;\r
+ // rewind to the beginning\r
+ if(0 != fseek(fdOutFile, 0, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ } \r
+\r
+#if (DEBUG == 0)\r
+ fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile );\r
+#endif\r
+ } \r
+ fclose(fdOutFile);\r
+}\r
+\r
+\r
+void doCueFile(void) {\r
+ int track = 1;\r
+ unsigned long int binIndex = 0;\r
+ unsigned long int trackIndex = 0;\r
+ const int gapThreshold = 20; // look for 0.266 sec gap\r
+ const int valueThreshold = 800; // look for samples < 700\r
+ int count = 0;\r
+ int i, blank;\r
+ int gapon = 0;\r
+ short value;\r
+ \r
+ char mode[12] = "AUDIO";\r
+ char index0[9] = "00:00:00";\r
+ char index1[9] = "00:00:00";\r
+ unsigned char buf[SIZERAW+100];\r
+ \r
+ printf( "FILE %s BINARY\n", sBinFilename);\r
+ fprintf(fdCueFile, "FILE %s BINARY\n", sBinFilename);\r
+ memset( buf, '\0', sizeof( buf ) );\r
+ while( fread( buf, 1, SIZERAW, fdBinFile ) ) {\r
+ if(trackIndex == 0) {\r
+ if ( (buf[0] == 0x00) &&\r
+ (buf[1] == 0xFF) &&\r
+ (buf[2] == 0xFF) &&\r
+ (buf[3] == 0xFF) &&\r
+ (buf[4] == 0xFF) &&\r
+ (buf[5] == 0xFF) &&\r
+ (buf[6] == 0xFF) &&\r
+ (buf[7] == 0xFF) &&\r
+ (buf[8] == 0xFF) &&\r
+ (buf[9] == 0xFF) &&\r
+ (buf[10] == 0xFF) &&\r
+ (buf[11] == 0x00) \r
+ ) {\r
+ sprintf(mode, "MODE%d/2352", buf[15]);\r
+ } else { \r
+ sprintf(mode, "AUDIO"); \r
+ }\r
+ } \r
+ if(binIndex == 0) {\r
+ printf( " TRACK %02d %s\n", track, mode);\r
+ fprintf(fdCueFile, " TRACK %02d %s\n", track, mode);\r
+ printf( " INDEX 01 %s\n", index0);\r
+ fprintf(fdCueFile, " INDEX 01 %s\n", index0);\r
+ }\r
+ blank = 1;\r
+ for(i = 0; i < SIZERAW; i+=2) {\r
+ value = buf[i+1];\r
+ value = ((value << 8) | buf[i]);\r
+// printf("%f %i\n",(1.0/75)*binIndex, value);\r
+ if(abs(value) > valueThreshold) {\r
+ blank = 0;\r
+ break;\r
+ }\r
+ }\r
+// if(i == SIZERAW) printf("%f ~blank~\n", (1.0/75)*binIndex);\r
+ if(blank == 1) count++;\r
+ else if (gapon == 1) {\r
+ gapon = 0; \r
+ unIndex(binIndex-count, index0);\r
+ count = 0;\r
+ unIndex(binIndex, index1);\r
+ printf( " TRACK %02d %s\n", track, mode);\r
+ fprintf(fdCueFile, " TRACK %02d %s\n", track, mode);\r
+ printf( " INDEX 00 %s\n", index0);\r
+ fprintf(fdCueFile, " INDEX 00 %s\n", index0);\r
+ printf( " INDEX 01 %s\n", index1);\r
+ fprintf(fdCueFile, " INDEX 01 %s\n", index1);\r
+ }\r
+ \r
+ if((count > gapThreshold) && (gapon == 0)) {\r
+ gapon = 1; track++;\r
+ trackIndex = -1;\r
+ } \r
+ \r
+ memset( buf, '\0', sizeof( buf ) );\r
+ binIndex++; \r
+ trackIndex++;\r
+ }\r
+}\r
+\r
+// return 0 to when no data found, 1 when there is.\r
+int checkGaps(FILE *fdBinFile, tTrack tracks[], int nTracks) {\r
+ int i, k;\r
+ unsigned long int j;\r
+ unsigned char buf[SIZERAW];\r
+ int c = 0;\r
+ int writegap = 0;\r
+ short value;\r
+ int count;\r
+\r
+ if(nTracks == 2) { return 0; }; // don't need to bother with single track images\r
+\r
+ printf("Checking gap data:\n");\r
+\r
+ for (i = 0; i < nTracks; i++) {\r
+ if((tracks[i].offset0 != tracks[i].offset1) && (tracks[i-1].mode == AUDIO)) {\r
+ if(0 != fseek(fdBinFile, tracks[i].offset0, SEEK_SET)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ }\r
+ count = 0;\r
+ for(j = tracks[i].idx0; j < tracks[i].idx1; j++) {\r
+ if(0 == fread( buf, SIZERAW, 1, fdBinFile ) ) {\r
+ perror("bin2iso(fread)");\r
+ exit(1);\r
+ }\r
+ for(k = 0; k < SIZERAW; k+=2) {\r
+ value = buf[k+1];\r
+ value = ((value << 8) | buf[k]);\r
+ if(value != 0) { \r
+ count++;\r
+\r
+ // printf("%10d: %2x\n", count ,value );\r
+ }\r
+ }\r
+ }\r
+ if(count != 0) {\r
+ printf(" Track%02d - %d values of Non-Zero gap data encountered\n", i-1, count);\r
+ if((count > SIZERAW/2/2) && (writegap == 0)) {\r
+ printf(" -->Threashold reached\n"); writegap = 1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return writegap; \r
+} \r
+\r
+/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */\r
+\r
+int main(int argc, char **argv) {\r
+ unsigned long int count = 0;\r
+// int printon = 0;\r
+\r
+ char sLine[256];\r
+ int i,j,q;\r
+ \r
+// int writegap = -1; // auto detect pregap data action by default. \r
+ int writegap = 1; // keep pregap data by default. \r
+ int no_overburn = 0; \r
+ int createCue = 0; \r
+ char sTrack[3] = "00"; \r
+ int doOneTrack = 0;\r
+ int doInPlace = 0;\r
+ \r
+ tTrack trackA;\r
+ tTrack trackB;\r
+ \r
+ tTrack tracks[100];\r
+ int nTracks = 0;\r
+ \r
+ char sOutdir[192];\r
+\r
+ sOutFilename[0] = '\0';\r
+\r
+ /* Tell them what I am. */\r
+ printf ("\n%s, %s", __DATE__, __TIME__);\r
+ printf ("\nbin2iso V1.9b - Converts RAW format (.bin) files to ISO/WAV format"); \r
+ printf ("\n Bob Doiron, ICQ#280251 \n");\r
+ printf ("\nCheck for updates at http://users.andara.com/~doiron\n\n");\r
+ if(argc < 2) {\r
+ printf("Usage: bin2iso <cuefile> [<output dir>] [-[a]wg] [-t XX] [-i] [-nob]\n");\r
+ printf("or : bin2iso <cuefile> -c <binfile>\n");\r
+ printf("\n");\r
+ printf("Where:\n");\r
+ printf(" <cuefile> - the .cue file that belongs to the .bin file to \n");\r
+ printf(" be converted\n");\r
+ printf(" <output dir> - the output directory (defaults to current dir) \n");\r
+ printf(" -nwg - indicates that audio data found in the track \n");\r
+ printf(" 'gaps' shouldn't be appended to the audio tracks\n");\r
+ printf(" -awg - looks for non-zero data in the 'gaps', if found\n");\r
+ printf(" then gaps are appended to audio tracks. Looks \n");\r
+ printf(" for more than 1/2 of a sector of non-zero values\n");\r
+ printf(" (%d values), \n", SIZERAW/2/2);\r
+ printf(" -t XX - Extracts the XX'th track. \n");\r
+ printf(" -i - Performs the conversion 'in place'. Meaning it \n");\r
+ printf(" truncates the binfile after each track is \n");\r
+ printf(" created to minimize diskspace requirements. \n");\r
+ printf(" [not valid with -t] \n");\r
+ printf(" -nob - Doesn't use overburn data past %ld sectors. \n", CD74_MAX_SECTORS);\r
+ printf(" This of course presumes that the data is not \n");\r
+ printf(" useful. \n");\r
+ printf(" -c - Attempts to create a <cuefile> from an existing\n");\r
+ printf(" <binfile> \n");\r
+ exit (1);\r
+ }\r
+\r
+ strcpy(sOutdir, "./"); // default path\r
+\r
+ printf("\n");\r
+ for (i=2; i < argc; i++) {\r
+ if (argv[i][0] == '-') {\r
+ /* if (strncmp(&(argv[i][1]), "wg", 2)==0) {\r
+ writegap = 1; \r
+ } else */ \r
+ \r
+ if (strncmp(&(argv[i][1]), "awg", 3)==0) {\r
+ writegap = -1; \r
+ printf("Note: Auto-detecting pregap data\n"); \r
+ } else if (strncmp(&(argv[i][1]), "nwg", 3)==0) {\r
+ writegap = 0; \r
+ } else if (strncmp(&(argv[i][1]), "m2to1", 5)==0) {\r
+ mode2to1 = 1;\r
+ printf("Note: Converting Mode2 ISO to Mode1\n");\r
+ } else if (strncmp(&(argv[i][1]), "t", 1)==0) {\r
+ strcpy(sTrack, argv[i+1]);\r
+ doOneTrack = 1;\r
+ i++;\r
+ } else if (strncmp(&(argv[i][1]), "i", 1)==0) {\r
+ if(doOneTrack == 1) { printf("Invalid combination of options...\n"); exit(1); }\r
+ printf("Bin file will be truncated after each track created\n");\r
+ doInPlace = 1;\r
+ } else if (strncmp(&(argv[i][1]), "c", 1)==0) {\r
+ createCue = 1;\r
+ strcpy(sBinFilename, argv[i+1]);\r
+ i++;\r
+ } else if (strncmp(&(argv[i][1]), "nob", 3)==0) {\r
+ no_overburn = 1;\r
+ }\r
+ } else {\r
+ strcpy(sOutdir, argv[2]);\r
+ }\r
+ }\r
+ \r
+ if(createCue == 1) {\r
+ fdBinFile = fopen (sBinFilename, "rb");\r
+ if (fdBinFile == NULL) {\r
+ printf ("Unable to open %s\n", sBinFilename);\r
+ exit (1);\r
+ } \r
+ fdCueFile = fopen (argv[1], "w");\r
+ if (fdCueFile == NULL) {\r
+ printf ("Unable to create %s\n", argv[1]);\r
+ exit (1);\r
+ } \r
+\r
+ if((strcmp(&sBinFilename[strlen(sBinFilename)-4], ".wav")==0) ||\r
+ (strcmp(&sBinFilename[strlen(sBinFilename)-4], ".WAV")==0) ) {\r
+ printf(".wav binfile - Skipping wav header\n");\r
+ fread( sLine, 1, sizeof(tWavHead), fdBinFile );\r
+ }\r
+\r
+ doCueFile();\r
+\r
+ } else { \r
+ fdCueFile = fopen (argv[1], "r"); \r
+ if (fdCueFile == NULL) {\r
+ printf ("Unable to open %s\n", argv[1]);\r
+ exit (1);\r
+ } \r
+\r
+ // get bin filename from cuefile... why? why not.\r
+ if(! fgets( sLine, 256, fdCueFile ) ) {\r
+ printf ("Error Reading Cuefile\n");\r
+ exit (1);\r
+ }\r
+ if (strncmp(sLine, "FILE ", 5)==0) {\r
+ i = 0;\r
+ j = 0;\r
+ q = 0; // track open and closed quotes\r
+ do { \r
+ sBinFilename[j] = sLine[5+i]; \r
+ i++;\r
+ j++;\r
+ if ((sBinFilename[j-1] == '\\') || (sBinFilename[j-1] == '/')) { j = 0; } //strip out path info\r
+ if (sBinFilename[j-1] == '"') { j--; q++;} // strip out quotes\r
+ } while ((sLine[5+i-1] != ' ') || (q == 1));\r
+ sBinFilename[j] = '\0';\r
+ //bug?? Why did a trailing space show up??\r
+ while(sBinFilename[--j] == ' ') sBinFilename[j] = '\0';\r
+\r
+// do not need to convert to lower case on unix system\r
+// strlwr(sBinFilename);\r
+\r
+ } else {\r
+ printf ("Error: Filename not found on first line of cuefile.\n", argv[1]);\r
+ exit (1);\r
+ }\r
+ \r
+ // Open the bin file\r
+ if(doInPlace == 1) {\r
+ fdBinFile = fopen (sBinFilename, "rb+");\r
+ } else {\r
+ fdBinFile = fopen (sBinFilename, "rb");\r
+ }\r
+ if (fdBinFile == NULL) {\r
+ printf ("Unable to open %s\n", sBinFilename);\r
+ perror("\nbin2iso(fopen)");\r
+ exit(1);\r
+ }\r
+\r
+ // Get next line\r
+ if(! fgets( sLine, 256, fdCueFile ) ) {\r
+ printf ("Error Reading Cuefile\n");\r
+ exit (1);\r
+ } \r
+ \r
+ if(strlen(sOutdir) > 0) {\r
+ if((sOutdir[strlen(sOutdir)-1] != '/' ) && (sOutdir[strlen(sOutdir)-1] != ':' ) ) {\r
+ strcat(sOutdir, "/");\r
+ }\r
+ }\r
+ \r
+ while(!feof(fdCueFile)) {\r
+ getTrackinfo(sLine, &tracks[nTracks++]);\r
+ }\r
+ tracks[nTracks].idx0 = tracks[nTracks].idx1 = -1;\r
+\r
+ switch (tracks[0].mode) {\r
+ case MODE1_2048:\r
+ tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE1;\r
+ break;\r
+ case MODE2_2336:\r
+ tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE2_FORM2;\r
+ break;\r
+ default: // AUDIO, MODE1_2352, MODE2_2352:\r
+ tracks[0].offset0 = tracks[0].idx0*SIZERAW;\r
+ break;\r
+ } \r
+ /* set offsets */\r
+\r
+ \r
+ if(0 != fseek(fdBinFile, 0, SEEK_END)) { \r
+ perror("\nbin2iso(fseek)"); exit(1);\r
+ }\r
+\r
+ tracks[nTracks].offset0 = tracks[nTracks].offset1 = ftell(fdBinFile);\r
+\r
+ for(i = 0; i < nTracks; i++) {\r
+ switch (tracks[i].mode) {\r
+ case MODE1_2048:\r
+ tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZEISO_MODE1;\r
+ if(tracks[i+1].idx0 != -1)\r
+ tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZEISO_MODE1;\r
+ else {\r
+ tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZEISO_MODE1 + tracks[i].idx1;\r
+ if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZEISO_MODE1) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");\r
+ }\r
+ break;\r
+ case MODE2_2336:\r
+ tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZEISO_MODE2_FORM2;\r
+ if(tracks[i+1].idx0 != -1)\r
+ tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZEISO_MODE2_FORM2;\r
+ else {\r
+ tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZEISO_MODE2_FORM2 + tracks[i].idx1;\r
+ if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZEISO_MODE2_FORM2) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");\r
+ }\r
+ break;\r
+ default: // AUDIO, MODE1_2352, MODE2_2352:\r
+ tracks[i].offset1 = tracks[i].offset0 + (tracks[i].idx1-tracks[i].idx0)*SIZERAW;\r
+ if(tracks[i+1].idx0 != -1)\r
+ tracks[i+1].offset0 = tracks[i].offset1 + (tracks[i+1].idx0 - tracks[i].idx1)*SIZERAW;\r
+ else {\r
+ tracks[i+1].idx0 = tracks[i+1].idx1 = (tracks[i+1].offset0 - tracks[i].offset1)/SIZERAW + tracks[i].idx1;\r
+ if(((tracks[i+1].offset0 - tracks[i].offset1)%SIZERAW) != 0) printf("Warning: Bin file has invalid byte count for cuefile.\n");\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ // if not allowing overburn, then create a new track to hold extra data...\r
+ if(no_overburn == 1) {\r
+ i = nTracks;\r
+ if(tracks[i].idx0 > CD74_MAX_SECTORS) {\r
+ tracks[i+1] = tracks[nTracks];\r
+ strcpy(tracks[i].name, "obdatatemp.bin");\r
+ tracks[i].idx0 = CD74_MAX_SECTORS;\r
+ tracks[i].idx1 = CD74_MAX_SECTORS;\r
+ switch (tracks[i-1].mode) {\r
+ case MODE1_2048:\r
+ tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE1;\r
+ break;\r
+ case MODE2_2336:\r
+ tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE2_FORM2;\r
+ break;\r
+ default: // AUDIO, MODE1_2352, MODE2_2352:\r
+ tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZERAW;\r
+ break;\r
+ }\r
+ tracks[i].offset1 = tracks[i].offset0;\r
+ tracks[i].mode = tracks[i-1].mode;\r
+ nTracks++;\r
+ }\r
+ }\r
+\r
+ \r
+ /* set sizes */\r
+ for(i = 0; i < nTracks; i++) {\r
+ switch (tracks[i].mode) {\r
+ case MODE1_2352:\r
+ tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZERAW ) * SIZEISO_MODE1;\r
+ break;\r
+ case MODE2_2336:\r
+ tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZEISO_MODE2_FORM2 ) * SIZERAW;\r
+ break;\r
+ default: // MODE1_2048, MODE2_2352, AUDIO\r
+ tracks[i].size = tracks[i+1].offset1 - tracks[i].offset1;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(writegap == -1) { writegap = checkGaps(fdBinFile, tracks, nTracks); }\r
+\r
+ if(writegap == 1) \r
+ printf("Note: Appending pregap data to end of audio tracks\n");\r
+ else \r
+ printf("Note: Discarding pregap data\n");\r
+\r
+ printf("\n");\r
+ for(i = 0; i <= nTracks-1; i++) {\r
+ printf("%s (%3d Mb) - sectors %06ld:%06ld (offset %09ld:%09ld)\n", \r
+ tracks[i].name, \r
+ tracks[i].size/(1024*1024), \r
+ tracks[i].idx1, \r
+ ( ((writegap == 0) || (tracks[i].mode != AUDIO)) ? tracks[i+1].idx0 : tracks[i+1].idx1)-1, \r
+ tracks[i].offset1, \r
+ ( ((writegap == 0) || (tracks[i].mode != AUDIO)) ? tracks[i+1].offset0 : tracks[i+1].offset1)-1 \r
+ );\r
+ }\r
+ printf("\n");\r
+\r
+ if( (((mode2to1 != 1) && (tracks[0].mode == MODE2_2352)) || (tracks[0].mode == MODE1_2048)) && (nTracks == 1) ) {\r
+ if(tracks[0].mode == MODE2_2352) { printf("Mode2/2352"); }\r
+ if(tracks[0].mode == MODE1_2048) { printf("Mode1/2048"); }\r
+ printf(" single track bin file indicated by cue file\n"); \r
+ fclose(fdBinFile);\r
+ if( 0 != rename(sBinFilename, tracks[0].name) ) {\r
+ perror("\nbin2iso(rename)");\r
+ exit(1);\r
+ }\r
+ printf("%s renamed to %s\n", sBinFilename, tracks[0].name);\r
+ fclose(fdCueFile);\r
+ return(0);\r
+ }\r
+\r
+ for(i=nTracks-1; i>=0; i--) {\r
+ trackA = tracks[i]; \r
+ trackB = tracks[i+1];\r
+ // audio can't be done in the bin file due to header.\r
+ // 2336 can't either because it's expanded to 2352\r
+ if((doInPlace == 1) && (i == 0) && (trackA.mode != AUDIO) && (trackA.mode != MODE2_2336) ) {\r
+ sOutFilename[0] = '\0';\r
+ } else {\r
+ strcpy(sOutFilename, sOutdir); \r
+ strcat(sOutFilename, trackA.name);\r
+ }\r
+ if ( ((doOneTrack == 1) && strcmp(trackA.num, sTrack)==0) || (doOneTrack == 0) ) {\r
+\r
+ if(!((i == 0) && ((trackA.mode == MODE2_2352)||(trackA.mode == MODE1_2048)) && (doInPlace == 1) )){\r
+ if (!writegap || (trackA.mode != AUDIO)) { // when not Audio, don't append.\r
+ dotrack(trackA.mode, trackA.idx0, trackA.idx1, trackB.idx0, trackA.offset1);\r
+ } else {\r
+ /* if(trackA.idx0 == 0) // handles first track with pregap.\r
+ dotrack(trackA.mode, 0, trackA.idx1, trackB.idx1, trackA.offset1);\r
+ else\r
+ */\r
+ dotrack(trackA.mode, trackA.idx1, trackA.idx1, trackB.idx1, trackA.offset1);\r
+ }\r
+ }\r
+ } /*else {\r
+ fclose(fdBinFile); // just close bin file. Already MODE1_2048 or MODE2_2352\r
+ }*/\r
+ if( (doOneTrack == 0) && (doInPlace == 1) ) {\r
+ if( (i != 0) || ( (i == 0) && ((trackA.mode == AUDIO)||(trackA.mode == MODE2_2336)) ) ) {\r
+ printf("Truncating bin file to %ld bytes\n", trackA.offset1);\r
+ if( -1 == ftruncate(fileno(fdBinFile), trackA.offset1) ) {\r
+ perror("\nbin2iso(_chsize)");\r
+ exit(1);\r
+ }\r
+ } else {\r
+ printf("Renaming %s to %s\n", sBinFilename, trackA.name);\r
+ fclose(fdBinFile);\r
+ if( 0 != rename(sBinFilename, trackA.name) ) {\r
+ perror("\nbin2iso(rename)");\r
+ exit(1);\r
+ }\r
+ \r
+ // fix writepos for case when simply truncating...\r
+ if((trackA.mode == MODE2_2352) || (trackA.mode == MODE1_2048)){ writepos = trackB.offset0; }\r
+\r
+ printf("Truncating to %ld bytes\n", writepos);\r
+ \r
+ fdBinFile = fopen(trackA.name, "rb+"); // gets closed in doTrack...\r
+ if(fdBinFile == NULL) { perror("bin2iso(fopen)"); exit(1); }\r
+\r
+ if( -1 == ftruncate(fileno(fdBinFile), writepos) ) {\r
+ perror("\nbin2iso(_chsize)");\r
+ exit(1);\r
+ }\r
+ }\r
+ }\r
+ } \r
+ }\r
+ fclose(fdCueFile);\r
+ fclose(fdBinFile);\r
+ return(0); \r
+}\r
+\r
+\r
+\r