]> git.pld-linux.org Git - packages/bin2iso.git/blob - bin2iso19b_linux.c
- rpmldflags
[packages/bin2iso.git] / bin2iso19b_linux.c
1 #include <stdio.h>\r
2 #include <string.h>\r
3 #include <stdlib.h>\r
4 \r
5 #define DEBUG 0\r
6 #define CHECK 0 /* don't bother checking bin for validity... */\r
7 \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
12 \r
13 typedef struct wavHdr {\r
14    BYTE1 riff[4];\r
15    BYTE4 bytestoend;\r
16    BYTE1 wavetxt[4];\r
17    BYTE1 fmttxt[4];\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
25    BYTE1 datatxt[4];\r
26    BYTE4 blocksize;\r
27 } tWavHead;\r
28 \r
29 #define HEADBYTES 36\r
30 #define WINDOWS_PCM 0x0001\r
31 //-------------------------------------------------/\r
32 \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
40 #define AUDIO 0\r
41 #define MODE1 1\r
42 #define MODE2 2\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
47 \r
48 #define RAWDATA FF       // using this for leftover data when truncating for non-overburn\r
49 \r
50 #define PROG_INTERVAL 1024\r
51 #define UNKNOWN -1\r
52 #define OFFSET 150                    \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
55          \r
56 \r
57 unsigned long int Index(char m, char s, char f)\r
58 {\r
59   unsigned long int temp;\r
60 \r
61 \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
65   \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
67   \r
68   return temp;\r
69 }\r
70 \r
71 void unIndex(unsigned long int index, char *ptr)\r
72 {\r
73   char m, s, f;\r
74 \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
79 \r
80 }\r
81 \r
82 // global variables\r
83 FILE* fdBinFile;\r
84 FILE* fdCueFile;\r
85 FILE* fdOutFile;\r
86 char sBinFilename[256];\r
87 char sOutFilename[256];\r
88 \r
89 unsigned long int writepos = 0; // for inplace conversions...\r
90 \r
91    \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
99 \r
100 int mode2to1 = 0;\r
101 \r
102 typedef struct track\r
103 {\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
112 } tTrack;\r
113 \r
114 buffered_fread(unsigned char *array, unsigned int size) {\r
115    unsigned int i;\r
116    \r
117    if(INBUF_WIDX == 0) {    \r
118       INBUF_WIDX += fread( INBUF, 1, (INBUF_SIZE/size)*size, fdBinFile );\r
119    }\r
120    if(INBUF_WIDX == 0) return 0; // read failed.\r
121    \r
122    for(i = 0; i< size; i++) \r
123    {\r
124 \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
129          break;\r
130       }\r
131    }\r
132 \r
133    if(INBUF_RIDX == INBUF_WIDX) {\r
134       INBUF_RIDX = 0;   \r
135       INBUF_WIDX = 0;   \r
136    }\r
137 \r
138 \r
139    return 1; // read passed\r
140      \r
141 }\r
142 \r
143 void buffered_fwrite(unsigned char *array, unsigned int size) {\r
144    unsigned int idx;\r
145    unsigned long int readpos;\r
146      \r
147    if(OUTBUF_IDX+size >= OUTBUF_SIZE) {     \r
148 \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
153          }         \r
154       }\r
155 \r
156       //      printf("\nWriting            \n");\r
157       if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {\r
158          perror("\nbin2iso(fwrite)");\r
159          fclose(fdOutFile);\r
160          // remove(sOutFilename);\r
161          exit(1);\r
162       }\r
163       if( 1 != fwrite( array, size, 1, fdOutFile )) {\r
164          perror("\nbin2iso(fwrite)");\r
165          fclose(fdOutFile);\r
166          // remove(sOutFilename);\r
167          exit(1);\r
168       }\r
169 //      printf("\nWrote %d bytes            \n", OUTBUF_IDX+size);\r
170       OUTBUF_IDX = 0;\r
171 \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
176          }         \r
177      }\r
178 \r
179 \r
180    } else {\r
181       for(idx = 0; idx < size; idx++) {\r
182          OUTBUF[OUTBUF_IDX + idx] = array[idx];\r
183       }\r
184       OUTBUF_IDX+=size;\r
185    }\r
186      \r
187 }\r
188 \r
189 \r
190 void flush_buffers(void)\r
191 {\r
192    unsigned long int readpos;\r
193 \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
198       }         \r
199    }\r
200 \r
201    if( 1 != fwrite( OUTBUF, OUTBUF_IDX, 1, fdOutFile )) {\r
202       perror("\nbin2iso(fwrite)");\r
203       fclose(fdOutFile);\r
204       // remove(sOutFilename);\r
205       exit(1);\r
206    }\r
207 \r
208 //   printf("\nWrote %d bytes          \n", OUTBUF_IDX);\r
209    OUTBUF_IDX = 0;\r
210    INBUF_RIDX = 0;\r
211    INBUF_WIDX = 0;\r
212 \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
217       }         \r
218    }\r
219 \r
220 \r
221 }\r
222 \r
223 \r
224 \r
225 // presumes Line is preloaded with the "current" line of the file\r
226 int getTrackinfo(char *Line, tTrack *track)\r
227 {\r
228 //   char tnum[3];\r
229    char inum[3];\r
230    char min;\r
231    char sec;\r
232    char block;\r
233    \r
234    track->idx0 = -1;\r
235    track->idx1 = -1;\r
236    \r
237    // Get the 'mode'\r
238    if (strncmp(&Line[2], "TRACK ", 6)==0) \r
239    {\r
240       strncpy(track->num, &Line[8], 2); track->num[2] = '\0';\r
241 \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
248    }\r
249    else return(1);\r
250    \r
251    // Set the name\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
256 \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
261    {\r
262       strcat(track->name, ".iso");\r
263    } else if(track->mode == AUDIO) {\r
264       strcat(track->name, ".wav");\r
265    } else {\r
266       printf("Track %d Unsupported mode\n", track->num);\r
267       return(1);\r
268    }\r
269 \r
270    // Get the track indexes\r
271    while(1) {\r
272       if(! fgets( Line, 256, fdCueFile ) ) { break; }\r
273 \r
274       if (strncmp(&Line[2], "TRACK ", 6)==0) \r
275       {  \r
276          break; // next track starting\r
277       }\r
278 \r
279       if (strncmp(&Line[4], "INDEX ", 6)==0) \r
280       {\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
285          \r
286          \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
290            \r
291       }\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
295    }\r
296    if(track->idx0 == -1) track->idx0 = track->idx1;\r
297    if(track->idx1 == -1) track->idx1 = track->idx0;\r
298    return(0);\r
299\r
300 \r
301 \r
302 void dotrack(short mode, long preidx, long startidx, long endidx, unsigned long offset) \r
303 {\r
304    unsigned char buf[SIZERAW+100];\r
305    unsigned long blockswritten = 0;\r
306    unsigned int uiLastIndex;\r
307 #if CHECK\r
308    unsigned int uiCurrentIndex;\r
309 #endif\r
310    unsigned int write = 1;\r
311    \r
312    tWavHead wavhead = { "RIFF", \r
313                              0,      \r
314                         "WAVE", \r
315                         "fmt ", \r
316                             16,       // 16 byte format specifier\r
317                    WINDOWS_PCM,       // format\r
318                              2,       // 2 Channels \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
323                         "data",  \r
324                              0 };\r
325                              \r
326    \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
332 \r
333    if(sOutFilename[0] != '\0') {\r
334       printf("Creating %s (%06d,%06d) ", sOutFilename, startidx, endidx-1);\r
335    } else {\r
336       printf("Converting (%06d,%06d) ", startidx, endidx-1);\r
337    }\r
338    switch(mode)\r
339    {\r
340       case AUDIO:\r
341          printf("Audio");\r
342          break;            \r
343       case MODE1_2352:\r
344          printf("Mode1/2048");\r
345          break;\r
346       case MODE2_2336:\r
347          printf("Mode2/2352");\r
348          break;\r
349       case MODE2_2352:\r
350          if(mode2to1 != 1) \r
351             printf("Mode2/2352");\r
352          else \r
353             printf("Mode1/2048");\r
354          break;\r
355       case MODE1_2048:\r
356          printf("Mode1/2048");\r
357          break;\r
358       default:\r
359            printf("Huh? What's going on?");\r
360            exit(1);\r
361    }\r
362    printf(" :       ");\r
363    \r
364    if(sOutFilename[0] != '\0') {\r
365       if(NULL == (fdOutFile = fopen (sOutFilename, "wb"))) {\r
366          perror("bin2iso(fopen)");\r
367       }\r
368 // printf("\nOpened File %s: %d\n", sOutFilename, fdOutFile);\r
369 \r
370    } else {\r
371       fdOutFile = fdBinFile;\r
372    }\r
373    if (fdOutFile == NULL)   { printf ("    Unable to create %s\n", sOutFilename); exit (1); }\r
374    \r
375    if(0 != fseek(fdBinFile, offset, SEEK_SET)) { \r
376       perror("\nbin2iso(fseek)"); exit(1);\r
377    }         \r
378 \r
379 #if (DEBUG == 0)\r
380    if(mode == AUDIO) {\r
381       if( 1 != fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile ) ) { // write placeholder\r
382          perror("\nbin2iso(fwrite)");\r
383          fclose(fdOutFile);\r
384          // remove(sOutFilename);\r
385          exit(1);\r
386       }\r
387    }\r
388 #endif \r
389          \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
395          //buf[0] = 0;\r
396          memset( &buf[1], 0xFF, sizeof(buf[0])*10 );\r
397          //buf[11] = 0;\r
398          buf[12] = M;\r
399          buf[13] = S;\r
400          buf[14] = F;\r
401          buf[15] = MODE2;\r
402          \r
403          if((++F&0xF) == 0xA) F += 6;\r
404 \r
405          if(F == 0x75) { S++; F = 0; } \r
406          if((S&0xF) == 0xA) S += 6;\r
407   \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
411          \r
412          buffered_fwrite( buf, SIZERAW );   \r
413          uiLastIndex++;\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
417       }\r
418    } else if (mode == MODE1_2048) {\r
419       while( buffered_fread( buf, SIZEISO_MODE1) ) {         \r
420          buffered_fwrite( buf, SIZEISO_MODE1 );   \r
421          uiLastIndex++;\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
424       }\r
425    } else {\r
426       while( buffered_fread( buf, SIZERAW) ) {\r
427          switch(mode) {\r
428             case AUDIO:\r
429 #if (DEBUG == 0)\r
430                buffered_fwrite( buf, SIZERAW );\r
431 #endif        \r
432                uiLastIndex++;\r
433                blockswritten++;\r
434                break;\r
435             case MODE1_2352:\r
436                // should put a crc check in here...\r
437 #if CHECK\r
438                if( buf[15] != MODE1) \r
439                { \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
442                   //exit(1);\r
443                }\r
444              \r
445                uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;\r
446               \r
447                if(uiCurrentIndex != uiLastIndex+1)\r
448                { \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
453                 \r
454                }\r
455 #endif\r
456 #if (DEBUG == 0)\r
457                buffered_fwrite( &buf[16], SIZEISO_MODE1 );\r
458 #endif\r
459 #if CHECK\r
460                uiLastIndex = uiCurrentIndex;\r
461 #endif\r
462                break;\r
463             case MODE2_2352:\r
464 #if CHECK\r
465                if( (buf[15]&0xf) != MODE2) \r
466                { \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
469                   //exit(1);\r
470                }\r
471 \r
472                uiCurrentIndex = Index(buf[12], buf[13], buf[14]) - OFFSET;\r
473 \r
474                if(uiCurrentIndex != uiLastIndex+1)\r
475                { \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
480                }\r
481 #endif\r
482 #if (DEBUG == 0)\r
483                if(mode2to1) buffered_fwrite( &buf[16+8], SIZEISO_MODE1 );\r
484                else if(write) buffered_fwrite( &buf[0], SIZEISO_MODE2_RAW );\r
485 #endif\r
486 #if CHECK\r
487                uiLastIndex = uiCurrentIndex;\r
488 #endif\r
489                break;\r
490             default:\r
491                printf("Unkown Mode\n"); exit(1);\r
492                break;\r
493          }         \r
494             \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
498       }\r
499    }\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
508       }         \r
509 \r
510 #if (DEBUG == 0)\r
511       fwrite( &wavhead, sizeof(wavhead), 1, fdOutFile );\r
512 #endif\r
513    }      \r
514    fclose(fdOutFile);\r
515 }\r
516 \r
517 \r
518 void doCueFile(void) {\r
519    int track = 1;\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
524    int count = 0;\r
525    int i, blank;\r
526    int gapon = 0;\r
527    short value;\r
528       \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
533     \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
550               (buf[11] == 0x00) \r
551             ) {\r
552             sprintf(mode, "MODE%d/2352", buf[15]);\r
553          } else { \r
554             sprintf(mode, "AUDIO"); \r
555          }\r
556       } \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
562       }\r
563       blank = 1;\r
564       for(i = 0; i < SIZERAW; i+=2) {\r
565          value = buf[i+1];\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
569             blank = 0;\r
570             break;\r
571          }\r
572       }\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
576          gapon = 0; \r
577          unIndex(binIndex-count, index0);\r
578          count = 0;\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
586       }\r
587       \r
588       if((count > gapThreshold) && (gapon == 0)) {\r
589          gapon = 1; track++;\r
590          trackIndex = -1;\r
591       } \r
592       \r
593       memset( buf, '\0', sizeof( buf ) );\r
594       binIndex++;      \r
595       trackIndex++;\r
596    }\r
597 }\r
598 \r
599 // return 0 to when no data found, 1 when there is.\r
600 int checkGaps(FILE *fdBinFile, tTrack tracks[], int nTracks) {\r
601    int i, k;\r
602    unsigned long int j;\r
603    unsigned char buf[SIZERAW];\r
604    int c = 0;\r
605    int writegap = 0;\r
606    short value;\r
607    int count;\r
608 \r
609    if(nTracks == 2) { return 0; }; // don't need to bother with single track images\r
610 \r
611    printf("Checking gap data:\n");\r
612 \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
617          }\r
618          count = 0;\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
622                exit(1);\r
623             }\r
624             for(k = 0; k < SIZERAW; k+=2) {\r
625                value = buf[k+1];\r
626                value = ((value << 8) | buf[k]);\r
627                if(value != 0) { \r
628                   count++;\r
629 \r
630                 // printf("%10d: %2x\n", count ,value );\r
631                }\r
632             }\r
633          }\r
634          if(count != 0) {\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
638             }\r
639          }\r
640       }\r
641    }\r
642    return writegap; \r
643 }   \r
644 \r
645 /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */\r
646 \r
647 int   main(int argc, char **argv) {\r
648    unsigned long int count = 0;\r
649 //   int printon = 0;\r
650 \r
651    char sLine[256];\r
652    int i,j,q;\r
653    \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
660    int doInPlace = 0;\r
661          \r
662    tTrack trackA;\r
663    tTrack trackB;\r
664    \r
665    tTrack tracks[100];\r
666    int nTracks = 0;\r
667    \r
668    char sOutdir[192];\r
669 \r
670    sOutFilename[0] = '\0';\r
671 \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
677    if(argc < 2) {\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
680       printf("\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
701       exit (1);\r
702    }\r
703 \r
704    strcpy(sOutdir, "./"); // default path\r
705 \r
706    printf("\n");\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
710             writegap = 1; \r
711          } else */ \r
712          \r
713          if (strncmp(&(argv[i][1]), "awg", 3)==0) {\r
714             writegap = -1; \r
715             printf("Note: Auto-detecting pregap data\n");         \r
716          } else if (strncmp(&(argv[i][1]), "nwg", 3)==0) {\r
717             writegap = 0;          \r
718          } else if (strncmp(&(argv[i][1]), "m2to1", 5)==0) {\r
719             mode2to1 = 1;\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
723             doOneTrack = 1;\r
724             i++;\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
728             doInPlace = 1;\r
729          } else if (strncmp(&(argv[i][1]), "c", 1)==0) {\r
730             createCue = 1;\r
731             strcpy(sBinFilename, argv[i+1]);\r
732             i++;\r
733          } else if (strncmp(&(argv[i][1]), "nob", 3)==0) {\r
734             no_overburn = 1;\r
735          }\r
736       } else {\r
737          strcpy(sOutdir, argv[2]);\r
738       }\r
739    }\r
740    \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
745          exit (1);\r
746       } \r
747       fdCueFile = fopen (argv[1], "w");\r
748       if (fdCueFile == NULL) {\r
749          printf ("Unable to create %s\n", argv[1]);\r
750          exit (1);\r
751       } \r
752 \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
757       }\r
758 \r
759       doCueFile();\r
760 \r
761    } else {   \r
762       fdCueFile = fopen (argv[1], "r");      \r
763       if (fdCueFile == NULL) {\r
764          printf ("Unable to open %s\n", argv[1]);\r
765          exit (1);\r
766       } \r
767 \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
771          exit (1);\r
772       }\r
773       if (strncmp(sLine, "FILE ", 5)==0) {\r
774          i = 0;\r
775          j = 0;\r
776          q = 0; // track open and closed quotes\r
777          do { \r
778             sBinFilename[j] = sLine[5+i]; \r
779             i++;\r
780             j++;\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
787 \r
788 // do not need to convert to lower case on unix system\r
789 //         strlwr(sBinFilename);\r
790 \r
791       } else {\r
792          printf ("Error: Filename not found on first line of cuefile.\n", argv[1]);\r
793          exit (1);\r
794       }\r
795    \r
796       // Open the bin file\r
797       if(doInPlace == 1) {\r
798          fdBinFile = fopen (sBinFilename, "rb+");\r
799       } else {\r
800          fdBinFile = fopen (sBinFilename, "rb");\r
801       }\r
802       if (fdBinFile == NULL) {\r
803          printf ("Unable to open %s\n", sBinFilename);\r
804          perror("\nbin2iso(fopen)");\r
805          exit(1);\r
806       }\r
807 \r
808       // Get next line\r
809       if(! fgets( sLine, 256, fdCueFile ) ) {\r
810          printf ("Error Reading Cuefile\n");\r
811          exit (1);\r
812       } \r
813    \r
814       if(strlen(sOutdir) > 0) {\r
815          if((sOutdir[strlen(sOutdir)-1] != '/' ) && (sOutdir[strlen(sOutdir)-1] != ':' ) ) {\r
816             strcat(sOutdir, "/");\r
817          }\r
818       }\r
819    \r
820       while(!feof(fdCueFile)) {\r
821          getTrackinfo(sLine, &tracks[nTracks++]);\r
822       }\r
823       tracks[nTracks].idx0 = tracks[nTracks].idx1 = -1;\r
824 \r
825       switch (tracks[0].mode) {\r
826          case MODE1_2048:\r
827             tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE1;\r
828             break;\r
829          case MODE2_2336:\r
830             tracks[0].offset0 = tracks[0].idx0*SIZEISO_MODE2_FORM2;\r
831             break;\r
832          default:  // AUDIO, MODE1_2352, MODE2_2352:\r
833             tracks[0].offset0 = tracks[0].idx0*SIZERAW;\r
834             break;\r
835       }               \r
836       /* set offsets */\r
837 \r
838       \r
839       if(0 != fseek(fdBinFile, 0, SEEK_END)) { \r
840          perror("\nbin2iso(fseek)"); exit(1);\r
841       }\r
842 \r
843       tracks[nTracks].offset0 = tracks[nTracks].offset1 = ftell(fdBinFile);\r
844 \r
845       for(i = 0; i < nTracks; i++) {\r
846          switch (tracks[i].mode) {\r
847             case MODE1_2048:\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
851                else {\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
854                }\r
855                break;\r
856             case MODE2_2336:\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
860                else {\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
863                }\r
864                break;\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
869                else {\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
872                }\r
873                break;\r
874          }\r
875       }\r
876 \r
877       // if not allowing overburn, then create a new track to hold extra data...\r
878       if(no_overburn == 1) {\r
879          i = nTracks;\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
886                case MODE1_2048:\r
887                   tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE1;\r
888                   break;\r
889                case MODE2_2336:\r
890                   tracks[i].offset0 = tracks[i-1].offset1 + (tracks[i].idx0 - tracks[i-1].idx1)*SIZEISO_MODE2_FORM2;\r
891                   break;\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
894                   break;\r
895             }\r
896             tracks[i].offset1 = tracks[i].offset0;\r
897             tracks[i].mode = tracks[i-1].mode;\r
898             nTracks++;\r
899          }\r
900       }\r
901 \r
902       \r
903       /* set sizes */\r
904       for(i = 0; i < nTracks; i++) {\r
905          switch (tracks[i].mode) {\r
906             case MODE1_2352:\r
907                tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZERAW ) * SIZEISO_MODE1;\r
908                break;\r
909             case MODE2_2336:\r
910                tracks[i].size = ((tracks[i+1].offset1 - tracks[i].offset1) / SIZEISO_MODE2_FORM2 ) * SIZERAW;\r
911                break;\r
912             default: // MODE1_2048, MODE2_2352, AUDIO\r
913               tracks[i].size = tracks[i+1].offset1 - tracks[i].offset1;\r
914               break;\r
915          }\r
916       }\r
917 \r
918       if(writegap == -1)  { writegap = checkGaps(fdBinFile, tracks, nTracks); }\r
919 \r
920       if(writegap == 1) \r
921          printf("Note: Appending pregap data to end of audio tracks\n");\r
922       else \r
923          printf("Note: Discarding pregap data\n");\r
924 \r
925       printf("\n");\r
926       for(i = 0; i <= nTracks-1; i++) {\r
927          printf("%s (%3d Mb) - sectors %06ld:%06ld (offset %09ld:%09ld)\n", \r
928             tracks[i].name, \r
929             tracks[i].size/(1024*1024), \r
930             tracks[i].idx1, \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
934          );\r
935       }\r
936       printf("\n");\r
937 \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
942          fclose(fdBinFile);\r
943          if( 0 != rename(sBinFilename, tracks[0].name) ) {\r
944             perror("\nbin2iso(rename)");\r
945             exit(1);\r
946          }\r
947          printf("%s renamed to %s\n", sBinFilename, tracks[0].name);\r
948          fclose(fdCueFile);\r
949          return(0);\r
950       }\r
951 \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
959          } else {\r
960             strcpy(sOutFilename, sOutdir); \r
961             strcat(sOutFilename, trackA.name);\r
962          }\r
963          if ( ((doOneTrack == 1) && strcmp(trackA.num, sTrack)==0) || (doOneTrack == 0) ) {\r
964 \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
968                } else {\r
969                   /* if(trackA.idx0 == 0) // handles first track with pregap.\r
970                      dotrack(trackA.mode,           0, trackA.idx1, trackB.idx1, trackA.offset1);\r
971                   else\r
972                   */\r
973                   dotrack(trackA.mode, trackA.idx1, trackA.idx1, trackB.idx1, trackA.offset1);\r
974                }\r
975             }\r
976          } /*else {\r
977             fclose(fdBinFile); // just close bin file. Already MODE1_2048 or MODE2_2352\r
978          }*/\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
984                   exit(1);\r
985                }\r
986             } else {\r
987                printf("Renaming %s to %s\n", sBinFilename, trackA.name);\r
988                fclose(fdBinFile);\r
989                if( 0 != rename(sBinFilename, trackA.name) ) {\r
990                   perror("\nbin2iso(rename)");\r
991                   exit(1);\r
992                }\r
993             \r
994                // fix writepos for case when simply truncating...\r
995                if((trackA.mode == MODE2_2352) || (trackA.mode == MODE1_2048)){ writepos = trackB.offset0; }\r
996 \r
997                printf("Truncating to %ld bytes\n", writepos);\r
998             \r
999                fdBinFile = fopen(trackA.name, "rb+"); // gets closed in doTrack...\r
1000                if(fdBinFile == NULL) { perror("bin2iso(fopen)"); exit(1); }\r
1001 \r
1002                if( -1 == ftruncate(fileno(fdBinFile), writepos) ) {\r
1003                   perror("\nbin2iso(_chsize)");\r
1004                   exit(1);\r
1005                }\r
1006             }\r
1007          }\r
1008       }   \r
1009    }\r
1010    fclose(fdCueFile);\r
1011    fclose(fdBinFile);\r
1012    return(0);  \r
1013 }\r
1014 \r
1015 \r
1016 \r
This page took 0.160737 seconds and 3 git commands to generate.