]>
Commit | Line | Data |
---|---|---|
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 | |
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 |