]> git.pld-linux.org Git - packages/bin2iso.git/blame - bin2iso19b_linux.c
- rpmldflags
[packages/bin2iso.git] / bin2iso19b_linux.c
CommitLineData
38c62f33
AM
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
9typedef unsigned char BYTE1 ;\r
10typedef unsigned short int BYTE2 ;\r
11typedef unsigned long int BYTE4 ;\r
12\r
13typedef 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
57unsigned 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
71void 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
83FILE* fdBinFile;\r
84FILE* fdCueFile;\r
85FILE* fdOutFile;\r
86char sBinFilename[256];\r
87char sOutFilename[256];\r
88\r
89unsigned 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
94unsigned char OUTBUF[OUTBUF_SIZE]; \r
95unsigned int OUTBUF_IDX = 0;\r
96unsigned char INBUF[INBUF_SIZE]; \r
97unsigned int INBUF_RIDX = 0;\r
98unsigned int INBUF_WIDX = 0;\r
99\r
100int mode2to1 = 0;\r
101\r
102typedef 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
114buffered_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
143void 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
190void 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
226int 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
302void 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
518void 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
600int 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
647int 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.385558 seconds and 4 git commands to generate.