"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/libburn/sector.c" (30 Jan 2021, 22872 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "sector.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.2_vs_1.5.4.
1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
2
3 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
4 Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
5 Provided under GPL version 2 or later.
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "../config.h"
10 #endif
11
12 #include <stdio.h>
13
14 /* ts A61010 */
15 /* #include <a ssert.h> */
16
17 #include <unistd.h>
18 #include <string.h>
19 #include "error.h"
20 #include "options.h"
21 #include "transport.h"
22 #include "libburn.h"
23 #include "drive.h"
24 #include "sector.h"
25 #include "crc.h"
26 #include "debug.h"
27 #include "toc.h"
28 #include "write.h"
29
30 #include "libdax_msgs.h"
31 extern struct libdax_msgs *libdax_messenger;
32
33 #include "ecma130ab.h"
34
35
36 #ifdef Libburn_log_in_and_out_streaM
37 /* ts A61031 */
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #endif /* Libburn_log_in_and_out_streaM */
42
43 /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
44 #ifndef O_BINARY
45 #define O_BINARY 0
46 #endif
47
48 /*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
49
50 #define sector_common(X) d->alba++; d->rlba X;
51
52 static void uncook_subs(unsigned char *dest, unsigned char *source)
53 {
54 int i, j, code;
55
56 memset(dest, 0, 96);
57
58 for (i = 0; i < 12; i++) {
59 for (j = 0; j < 8; j++) {
60 for (code = 0; code < 8; code++) {
61 if (source[code * 12 + i] & 0x80)
62 dest[j + i * 8] |= (1 << (7 - code));
63 source[code * 12 + i] <<= 1;
64 }
65 }
66 }
67 }
68
69 /* @return >=0 : valid , <0 invalid */
70 int sector_get_outmode(enum burn_write_types write_type,
71 enum burn_block_types block_type)
72 {
73 /* ts A61103 : extended SAO condition to TAO */
74 if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO)
75 return 0;
76 else
77 switch (block_type) {
78 case BURN_BLOCK_RAW0:
79 return BURN_MODE_RAW;
80 case BURN_BLOCK_RAW16:
81 return BURN_MODE_RAW | BURN_SUBCODE_P16;
82 case BURN_BLOCK_RAW96P:
83 return BURN_MODE_RAW | BURN_SUBCODE_P96;
84 case BURN_BLOCK_RAW96R:
85 return BURN_MODE_RAW | BURN_SUBCODE_R96;
86 case BURN_BLOCK_MODE1:
87 return BURN_MODE1;
88 default:
89 return -1;
90 }
91
92 /* ts A61007 : now handled in burn_write_opts_set_write_type() */
93 /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
94 }
95
96 /* 0 means "same as inmode" */
97 static int get_outmode(struct burn_write_opts *o)
98 {
99 /* ts A61007 */
100 return sector_get_outmode(o->write_type, o->block_type);
101
102 /* -1 is prevented by check in burn_write_opts_set_write_type() */
103 /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
104 }
105
106
107 static void get_bytes(struct burn_track *track, int count, unsigned char *data)
108 {
109 int valid, shortage, curr, i, tr;
110
111 #ifdef Libburn_log_in_and_out_streaM
112 /* ts A61031 */
113 static int tee_fd= -1;
114 if(tee_fd==-1)
115 tee_fd= open("/tmp/libburn_sg_readin",
116 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
117 S_IRUSR | S_IWUSR);
118 #endif /* Libburn_log_in_and_out_streaM */
119
120
121 /* no track pointer means we're just generating 0s */
122 if (!track) {
123 memset(data, 0, count);
124 return;
125 }
126
127 /* first we use up any offset */
128 valid = track->offset - track->offsetcount;
129 if (valid > count)
130 valid = count;
131
132 if (valid) {
133 track->offsetcount += valid;
134 memset(data, 0, valid);
135 }
136 shortage = count - valid;
137
138 if (!shortage)
139 goto ex;
140
141 /* Next we use source data */
142 curr = valid;
143 if (!track->eos) {
144 if (track->source->read != NULL)
145 valid = track->source->read(track->source,
146 data + curr, count - curr);
147 else
148 valid = track->source->read_xt(track->source,
149 data + curr, count - curr);
150 } else valid = 0;
151
152 if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
153 track->eos = 1;
154 valid = 0;
155 }
156 track->sourcecount += valid;
157
158 #ifdef Libburn_log_in_and_out_streaM
159 /* ts A61031 */
160 if(tee_fd!=-1 && valid>0) {
161 write(tee_fd, data + curr, valid);
162 }
163 #endif /* Libburn_log_in_and_out_streaM */
164
165 curr += valid;
166 shortage = count - curr;
167
168 if (!shortage)
169 goto ex;
170
171 /* Before going to the next track, we run through any tail */
172
173 valid = track->tail - track->tailcount;
174 if (valid > count - curr)
175 valid = count - curr;
176
177 if (valid) {
178 track->tailcount += valid;
179 memset(data + curr, 0, valid);
180 }
181 curr += valid;
182 shortage -= valid;
183
184 if (!shortage)
185 goto ex;
186
187 /* ts A61031 - B10103 */
188 if (shortage >= count)
189 track->track_data_done = 1;
190 if (track->end_on_premature_eoi && shortage >= count &&
191 !track->open_ended) {
192 char msg[80];
193 off_t missing, inp_block_size, track_blocks;
194
195 inp_block_size = burn_sector_length(track->mode);
196 track_blocks = burn_track_get_sectors_2(track, 1);
197 missing = track_blocks * inp_block_size - track->sourcecount;
198 sprintf(msg,
199 "Premature end of input encountered. Missing: %.f bytes",
200 (double) missing);
201 libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
202 LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
203 msg, 0,0);
204 /* Memorize that premature end of input happened */
205 track->end_on_premature_eoi = 2;
206 }
207 if (track->open_ended || track->end_on_premature_eoi)
208 goto ex;
209
210 /* If we're still short, and there's a "next" pointer, we pull from that.
211 if that depletes, we'll just fill with 0s.
212 */
213 if (track->source->next) {
214 struct burn_source *src;
215 printf("pulling from next track\n");
216 src = track->source->next;
217 valid = src->read(src, data + curr, shortage);
218 if (valid > 0) {
219 shortage -= valid;
220 curr += valid;
221 }
222 }
223 ex:;
224 /* ts A61024 : general finalizing processing */
225 if(shortage)
226 memset(data + curr, 0, shortage); /* this is old icculus.org */
227 if (track->swap_source_bytes == 1) {
228 for (i = 1; i < count; i += 2) {
229 tr = data[i];
230 data[i] = data[i-1];
231 data[i-1] = tr;
232 }
233 }
234 }
235
236
237 /* ts B20113 : outsourced from get_sector() */
238 int sector_write_buffer(struct burn_drive *d,
239 struct burn_track *track, int flag)
240 {
241 int err, i;
242 struct buffer *out;
243
244 out = d->buffer;
245 if (out->sectors <= 0)
246 return 2;
247 err = d->write(d, d->nwa, out);
248 if (err == BE_CANCELLED)
249 return 0;
250
251 /* ts A61101 */
252 if(track != NULL) {
253 track->writecount += out->bytes;
254 track->written_sectors += out->sectors;
255
256 /* Determine current index */
257 for (i = d->progress.index; i + 1 < track->indices; i++) {
258 if (track->index[i + 1] > d->nwa + out->sectors)
259 break;
260 d->progress.index = i + 1;
261 }
262 }
263 /* ts A61119 */
264 d->progress.buffered_bytes += out->bytes;
265
266 d->nwa += out->sectors;
267 out->bytes = 0;
268 out->sectors = 0;
269 return 1;
270 }
271
272
273 /* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
274 and to count hand outs as well as reserved bytes */
275 /* ts A61101 : added parameter track for counting written bytes */
276 static unsigned char *get_sector(struct burn_write_opts *opts,
277 struct burn_track *track, int inmode)
278 {
279 struct burn_drive *d = opts->drive;
280 struct buffer *out = d->buffer;
281 int outmode, seclen, write_ret;
282 unsigned char *ret;
283
284 outmode = get_outmode(opts);
285 if (outmode == 0)
286 outmode = inmode;
287
288 /* ts A61009 : react on eventual failure of burn_sector_length()
289 (should not happen if API tested properly).
290 Ensures out->bytes >= out->sectors */
291 seclen = burn_sector_length(outmode);
292 if (seclen <= 0)
293 return NULL;
294 seclen += burn_subcode_length(outmode);
295
296 /* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
297 /* (there is enough buffer size reserve for track->cdxa_conversion) */
298 if (out->bytes + seclen > BUFFER_SIZE ||
299 (opts->obs > 0 && out->bytes + seclen > opts->obs)) {
300 write_ret = sector_write_buffer(d, track, 0);
301 if (write_ret <= 0)
302 return NULL;
303 }
304 ret = out->data + out->bytes;
305 out->bytes += seclen;
306 out->sectors++;
307
308 return ret;
309 }
310
311 /* ts A61031 */
312 /* Revoke the counting of the most recent sector handed out by get_sector() */
313 static void unget_sector(struct burn_write_opts *opts, int inmode)
314 {
315 struct burn_drive *d = opts->drive;
316 struct buffer *out = d->buffer;
317 int outmode;
318 int seclen;
319
320 outmode = get_outmode(opts);
321 if (outmode == 0)
322 outmode = inmode;
323
324 /* ts A61009 : react on eventual failure of burn_sector_length()
325 (should not happen if API tested properly).
326 Ensures out->bytes >= out->sectors */
327 seclen = burn_sector_length(outmode);
328 if (seclen <= 0)
329 return;
330 seclen += burn_subcode_length(outmode);
331
332 out->bytes -= seclen;
333 out->sectors--;
334 }
335
336
337 /* either inmode == outmode, or outmode == raw. anything else is bad news */
338 /* ts A61010 : changed type to int in order to propagate said bad news */
339 /** @return 1 is ok, <= 0 is failure */
340 static int convert_data(struct burn_write_opts *o, struct burn_track *track,
341 int inmode, unsigned char *data)
342 {
343 int outlen, inlen;
344 int offset = -1;
345 int outmode;
346
347 outmode = get_outmode(o);
348 if (outmode == 0)
349 outmode = inmode;
350
351 outlen = burn_sector_length(outmode);
352 inlen = burn_sector_length(inmode);
353
354 /* ts A61010 */
355 /* a ssert(outlen >= inlen); */
356 if (outlen < inlen || outlen < 0 || inlen < 0)
357 return 0;
358
359 if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
360 /* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
361 Table 24 Mode 2 Formed Sector Sub-header Format */
362 if (track != NULL)
363 if (track->cdxa_conversion == 1)
364 inlen += 8;
365
366 get_bytes(track, inlen, data);
367
368 if (track != NULL)
369 if (track->cdxa_conversion == 1)
370 memmove(data, data + 8, inlen - 8);
371 return 1;
372 }
373
374 /* ts A61010 */
375 /* a ssert(outmode & BURN_MODE_RAW); */
376 if (!(outmode & BURN_MODE_RAW))
377 return 0;
378
379 if (inmode & BURN_MODE1)
380 offset = 16;
381 if (inmode & BURN_MODE_RAW)
382 offset = 0;
383 if (inmode & BURN_AUDIO)
384 offset = 0;
385
386 /* ts A61010 */
387 /* a ssert(offset != -1); */
388 if (offset == -1)
389 return 0;
390
391 get_bytes(track, inlen, data + offset);
392 return 1;
393 }
394
395 static void convert_subs(struct burn_write_opts *o, int inmode,
396 unsigned char *subs, unsigned char *sector)
397 {
398 unsigned char *out;
399 int outmode;
400
401 outmode = get_outmode(o);
402 if (outmode == 0)
403 outmode = inmode;
404 sector += burn_sector_length(outmode);
405 /* XXX for sao with subs, we'd need something else... */
406
407 switch (o->block_type) {
408 case BURN_BLOCK_RAW96R:
409 uncook_subs(sector, subs);
410 break;
411
412 case BURN_BLOCK_RAW16:
413 memcpy(sector, subs + 12, 12);
414 out = sector + 12;
415 out[0] = 0;
416 out[1] = 0;
417 out[2] = 0;
418 /*XXX find a better way to deal with partially damaged P channels*/
419 if (subs[2] != 0)
420 out[3] = 0x80;
421 else
422 out[3] = 0;
423 out = sector + 10;
424
425 out[0] = ~out[0];
426 out[1] = ~out[1];
427 break;
428 /* ts A61119 : to silence compiler warnings */
429 default:;
430 }
431 }
432
433 static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
434 {
435 unsigned char *q;
436 int track;
437 int crc;
438 int min, sec, frame;
439
440 track = d->toc_temp / 3;
441 memset(data, 0, 96);
442 q = data + 12;
443
444 burn_lba_to_msf(d->rlba, &min, &sec, &frame);
445 /*XXX track numbers are BCD
446 a0 - 1st track ctrl
447 a1 - last track ctrl
448 a2 - lout ctrl
449 */
450 q[0] = (d->toc_entry[track].control << 4) + 1;
451 q[1] = 0;
452 if (d->toc_entry[track].point < 100)
453 q[2] = dec_to_bcd(d->toc_entry[track].point);
454 else
455 q[2] = d->toc_entry[track].point;
456 q[3] = dec_to_bcd(min);
457 q[4] = dec_to_bcd(sec);
458 q[5] = dec_to_bcd(frame);
459 q[6] = 0;
460 q[7] = dec_to_bcd(d->toc_entry[track].pmin);
461 q[8] = dec_to_bcd(d->toc_entry[track].psec);
462 q[9] = dec_to_bcd(d->toc_entry[track].pframe);
463
464 #ifdef Libburn_no_crc_C
465 crc = 0; /* dummy */
466 #else
467 crc = crc_ccitt(q, 10);
468 #endif
469
470 q[10] = crc >> 8;
471 q[11] = crc & 0xFF;
472 d->toc_temp++;
473 d->toc_temp %= (d->toc_entries * 3);
474 }
475
476 int sector_toc(struct burn_write_opts *o, int mode)
477 {
478 struct burn_drive *d = o->drive;
479 unsigned char *data;
480 unsigned char subs[96];
481
482 data = get_sector(o, NULL, mode);
483 if (data == NULL)
484 return 0;
485 /* ts A61010 */
486 if (convert_data(o, NULL, mode, data) <= 0)
487 return 0;
488 subcode_toc(d, mode, subs);
489 convert_subs(o, mode, subs, data);
490 if (sector_headers(o, data, mode, 1) <= 0)
491 return 0;
492 sector_common(++)
493 return 1;
494 }
495
496 int sector_pregap(struct burn_write_opts *o,
497 unsigned char tno, unsigned char control, int mode)
498 {
499 struct burn_drive *d = o->drive;
500 unsigned char *data;
501 unsigned char subs[96];
502
503 data = get_sector(o, NULL, mode);
504 if (data == NULL)
505 return 0;
506 /* ts A61010 */
507 if (convert_data(o, NULL, mode, data) <= 0)
508 return 0;
509 subcode_user(o, subs, tno, control, 0, NULL, 1);
510 convert_subs(o, mode, subs, data);
511 if (sector_headers(o, data, mode, 0) <= 0)
512 return 0;
513 sector_common(--)
514 return 1;
515 }
516
517 int sector_postgap(struct burn_write_opts *o,
518 unsigned char tno, unsigned char control, int mode)
519 {
520 struct burn_drive *d = o->drive;
521 unsigned char subs[96];
522 unsigned char *data;
523
524 data = get_sector(o, NULL, mode);
525 if (data == NULL)
526 return 0;
527 /* ts A61010 */
528 if (convert_data(o, NULL, mode, data) <= 0)
529 return 0;
530 /* use last index in track */
531 subcode_user(o, subs, tno, control, 1, NULL, 1);
532 convert_subs(o, mode, subs, data);
533 if (sector_headers(o, data, mode, 0) <= 0)
534 return 0;
535 sector_common(++)
536 return 1;
537 }
538
539 static void subcode_lout(struct burn_write_opts *o, unsigned char control,
540 unsigned char *data)
541 {
542 struct burn_drive *d = o->drive;
543 unsigned char *q;
544 int crc;
545 int rmin, min, rsec, sec, rframe, frame;
546
547 memset(data, 0, 96);
548 q = data + 12;
549
550 burn_lba_to_msf(d->alba, &min, &sec, &frame);
551 burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe);
552
553 if (((rmin == 0) && (rsec == 0) && (rframe == 0)) ||
554 ((rsec >= 2) && !((rframe / 19) % 2)))
555 memset(data, 0xFF, 12);
556 q[0] = (control << 4) + 1;
557 q[1] = 0xAA;
558 q[2] = 0x01;
559 q[3] = dec_to_bcd(rmin);
560 q[4] = dec_to_bcd(rsec);
561 q[5] = dec_to_bcd(rframe);
562 q[6] = 0;
563 q[7] = dec_to_bcd(min);
564 q[8] = dec_to_bcd(sec);
565 q[9] = dec_to_bcd(frame);
566
567 #ifdef Libburn_no_crc_C
568 crc = 0; /* dummy */
569 #else
570 crc = crc_ccitt(q, 10);
571 #endif
572
573 q[10] = crc >> 8;
574 q[11] = crc & 0xFF;
575 }
576
577 static char char_to_isrc(char c)
578 {
579 if (c >= '0' && c <= '9')
580 return c - '0';
581 if (c >= 'A' && c <= 'Z')
582 return 0x11 + (c - 'A');
583 if (c >= 'a' && c <= 'z')
584 return 0x11 + (c - 'a');
585
586 /* ts A61008 : obsoleted by test in burn_track_set_isrc() */
587 /* a ssert(0); */
588 return 0;
589 }
590
591 void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
592 unsigned char tno, unsigned char control,
593 unsigned char indx, struct isrc *isrc, int psub)
594 {
595 struct burn_drive *d = o->drive;
596 unsigned char *p, *q;
597 int crc;
598 int m, s, f, c, qmode; /* 1, 2 or 3 */
599
600 memset(subcodes, 0, 96);
601
602 p = subcodes;
603 if ((tno == 1) && (d->rlba == -150))
604 memset(p, 0xFF, 12);
605
606 if (psub)
607 memset(p, 0xFF, 12);
608 q = subcodes + 12;
609
610 qmode = 1;
611 /* every 1 in 10 we can do something different */
612 if (d->rlba % 10 == 0) {
613 /* each of these can occur 1 in 100 */
614 if ((d->rlba / 10) % 10 == 0) {
615 if (o->has_mediacatalog)
616 qmode = 2;
617 } else if ((d->rlba / 10) % 10 == 1) {
618 if (isrc && isrc->has_isrc)
619 qmode = 3;
620 }
621 }
622
623 /* ts A61010 : this cannot happen. Assert for fun ? */
624 /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */
625
626 switch (qmode) {
627 case 1:
628 q[1] = dec_to_bcd(tno); /* track number */
629 q[2] = dec_to_bcd(indx); /* index XXX read this shit
630 from the track array */
631 burn_lba_to_msf(d->rlba, &m, &s, &f);
632 q[3] = dec_to_bcd(m); /* rel min */
633 q[4] = dec_to_bcd(s); /* rel sec */
634 q[5] = dec_to_bcd(f); /* rel frame */
635 q[6] = 0; /* zero */
636 burn_lba_to_msf(d->alba, &m, &s, &f);
637 q[7] = dec_to_bcd(m); /* abs min */
638 q[8] = dec_to_bcd(s); /* abs sec */
639 q[9] = dec_to_bcd(f); /* abs frame */
640 break;
641 case 2:
642 /* media catalog number */
643 q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1];
644 q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3];
645 q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5];
646 q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7];
647 q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9];
648 q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11];
649 q[7] = o->mediacatalog[12] << 4;
650
651 q[8] = 0;
652 burn_lba_to_msf(d->alba, &m, &s, &f);
653 q[9] = dec_to_bcd(f); /* abs frame */
654 break;
655 case 3:
656 c = char_to_isrc(isrc->country[0]);
657 /* top 6 bits of [1] is the first country code */
658 q[1] = c << 2;
659 c = char_to_isrc(isrc->country[1]);
660 /* bottom 2 bits of [1] is part of the second country code */
661 q[1] += (c >> 4);
662 /* top 4 bits if [2] is the rest of the second country code */
663 q[2] = c << 4;
664
665 c = char_to_isrc(isrc->owner[0]);
666 /* bottom 4 bits of [2] is part of the first owner code */
667 q[2] += (c >> 2);
668 /* top 2 bits of [3] is the rest of the first owner code */
669 q[3] = c << 6;
670 c = char_to_isrc(isrc->owner[1]);
671 /* bottom 6 bits of [3] is the entire second owner code */
672 q[3] += c;
673 c = char_to_isrc(isrc->owner[2]);
674 /* top 6 bits of [4] are the third owner code */
675 q[4] = c << 2;
676
677 /* [5] is the year in 2 BCD numbers */
678 q[5] = dec_to_bcd(isrc->year % 100);
679 /* [6] is the first 2 digits in the serial */
680 q[6] = dec_to_bcd(isrc->serial % 100);
681 /* [7] is the next 2 digits in the serial */
682 q[7] = dec_to_bcd((isrc->serial / 100) % 100);
683 /* the top 4 bits of [8] is the last serial digit, the rest is
684 zeros */
685 q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4;
686 burn_lba_to_msf(d->alba, &m, &s, &f);
687 q[9] = dec_to_bcd(f); /* abs frame */
688 break;
689 }
690 q[0] = (control << 4) + qmode;
691
692
693 #ifdef Libburn_no_crc_C
694 crc = 0; /* dummy */
695 #else
696 crc = crc_ccitt(q, 10);
697 #endif
698
699 q[10] = crc >> 8;
700 q[11] = crc & 0xff;
701 }
702
703 int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
704 {
705 struct burn_drive *d = o->drive;
706 unsigned char subs[96];
707 unsigned char *data;
708
709 data = get_sector(o, NULL, mode);
710 if (!data)
711 return 0;
712 /* ts A61010 */
713 if (convert_data(o, NULL, mode, data) <= 0)
714 return 0;
715 subcode_lout(o, control, subs);
716 convert_subs(o, mode, subs, data);
717 if (sector_headers(o, data, mode, 0) <= 0)
718 return 0;
719 sector_common(++)
720 return 1;
721 }
722
723 int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
724 {
725 struct burn_drive *d = o->drive;
726 unsigned char subs[96];
727 unsigned char *data;
728
729 data = get_sector(o, t, t->mode);
730 if (data == NULL)
731 return 0;
732 /* ts A61010 */
733 if (convert_data(o, t, t->mode, data) <= 0)
734 return 0;
735
736 /* ts A61031 */
737 if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
738 unget_sector(o, t->mode);
739 return 2;
740 }
741
742 /* ts A61219 : allow track without .entry */
743 if (t->entry == NULL)
744 ;
745 else if (!t->source->read_sub)
746 subcode_user(o, subs, t->entry->point,
747 t->entry->control, 1, &t->isrc, psub);
748 else if (!t->source->read_sub(t->source, subs, 96))
749 subcode_user(o, subs, t->entry->point,
750 t->entry->control, 1, &t->isrc, psub);
751 convert_subs(o, t->mode, subs, data);
752
753 if (sector_headers(o, data, t->mode, 0) <= 0)
754 return 0;
755 sector_common(++)
756 return 1;
757 }
758
759 int burn_msf_to_lba(int m, int s, int f)
760 {
761 if (m < 90)
762 return (m * 60 + s) * 75 + f - 150;
763 else
764 return (m * 60 + s) * 75 + f - 450150;
765 }
766
767 void burn_lba_to_msf(int lba, int *m, int *s, int *f)
768 {
769 if (lba >= -150) {
770 *m = (lba + 150) / (60 * 75);
771 *s = (lba + 150 - *m * 60 * 75) / 75;
772 *f = lba + 150 - *m * 60 * 75 - *s * 75;
773 } else {
774 *m = (lba + 450150) / (60 * 75);
775 *s = (lba + 450150 - *m * 60 * 75) / 75;
776 *f = lba + 450150 - *m * 60 * 75 - *s * 75;
777 }
778 }
779
780 int dec_to_bcd(int d)
781 {
782 int top, bottom;
783
784 top = d / 10;
785 bottom = d - (top * 10);
786 return (top << 4) + bottom;
787 }
788
789 int sector_headers_is_ok(struct burn_write_opts *o, int mode)
790 {
791 if (mode & BURN_AUDIO) /* no headers for "audio" */
792 return 1;
793 if (o->write_type == BURN_WRITE_SAO)
794 return 1;
795
796 /* ts A61031 */
797 if (o->write_type == BURN_WRITE_TAO)
798 return 1;
799
800 if (mode & BURN_MODE1)
801 return 2;
802 return 0;
803 }
804
805 /* ts A90830 : changed return type to int
806 @return 0= failure
807 1= success
808 */
809 int sector_headers(struct burn_write_opts *o, unsigned char *out,
810 int mode, int leadin)
811 {
812
813 #ifdef Libburn_ecma130ab_includeD
814
815 struct burn_drive *d = o->drive;
816 unsigned int crc;
817 int min, sec, frame;
818 int modebyte = -1;
819 int ret;
820
821 ret = sector_headers_is_ok(o, mode);
822 if (ret != 2)
823 return !!ret;
824 modebyte = 1;
825
826 out[0] = 0;
827 memset(out + 1, 0xFF, 10); /* sync */
828 out[11] = 0;
829
830 if (leadin) {
831 burn_lba_to_msf(d->rlba, &min, &sec, &frame);
832 out[12] = dec_to_bcd(min) + 0xA0;
833 out[13] = dec_to_bcd(sec);
834 out[14] = dec_to_bcd(frame);
835 out[15] = modebyte;
836 } else {
837 burn_lba_to_msf(d->alba, &min, &sec, &frame);
838 out[12] = dec_to_bcd(min);
839 out[13] = dec_to_bcd(sec);
840 out[14] = dec_to_bcd(frame);
841 out[15] = modebyte;
842 }
843 if (mode & BURN_MODE1) {
844
845 #ifdef Libburn_no_crc_C
846 crc = 0; /* dummy */
847 #else
848 crc = crc_32(out, 2064);
849 #endif
850
851 out[2064] = crc & 0xFF;
852 crc >>= 8;
853 out[2065] = crc & 0xFF;
854 crc >>= 8;
855 out[2066] = crc & 0xFF;
856 crc >>= 8;
857 out[2067] = crc & 0xFF;
858 }
859 if (mode & BURN_MODE1) {
860 memset(out + 2068, 0, 8);
861 burn_rspc_parity_p(out);
862 burn_rspc_parity_q(out);
863 }
864 burn_ecma130_scramble(out);
865 return 1;
866
867 #else /* Libburn_ecma130ab_includeD */
868
869 int ret;
870
871 ret = sector_headers_is_ok(o, mode);
872 if (ret != 2)
873 return (!! ret);
874
875 /* ts A90830 : lec.c is copied from cdrdao.
876 I have no idea yet how lec.c implements the Reed-Solomon encoding
877 which is described in ECMA-130 for CD-ROM.
878 So this got removed for now.
879 */
880 libdax_msgs_submit(libdax_messenger, o->drive->global_index,
881 0x0002010a,
882 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
883 "Raw CD write modes are not supported", 0, 0);
884 return 0;
885
886 #endif /* ! Libburn_ecma130ab_includeD */
887
888 }
889
890 #if 0
891 void process_q(struct burn_drive *d, unsigned char *q)
892 {
893 unsigned char i[5];
894 int mode;
895
896 mode = q[0] & 0xF;
897 /* burn_print(12, "mode: %d : ", mode);*/
898 switch (mode) {
899 case 1:
900 /* burn_print(12, "tno = %d : ", q[1]);
901 burn_print(12, "index = %d\n", q[2]);
902 */
903 /* q[1] is the track number (starting at 1) q[2] is the index
904 number (starting at 0) */
905 #warning this is totally bogus
906 if (q[1] - 1 > 99)
907 break;
908 if (q[2] > d->toc->track[q[1] - 1].indices) {
909 burn_print(12, "new index at %d\n", d->alba);
910 d->toc->track[q[1] - 1].index[q[2]] = d->alba;
911 d->toc->track[q[1] - 1].indices++;
912 }
913 break;
914 case 2:
915 /* XXX do not ignore these */
916 break;
917 case 3:
918 /* burn_print(12, "ISRC data in mode 3 q\n");*/
919 i[0] = isrc[(q[1] << 2) >> 2];
920 /* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
921 burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
922 */
923 break;
924 default:
925
926 /* ts A61009 : if reactivated then without Assert */
927 a ssert(0);
928 }
929 }
930 #endif
931
932 /* this needs more info. subs in the data? control/adr? */
933
934 /* ts A61119 : One should not use unofficial compiler extensions.
935 >>> Some day this function needs to be implemented. At least for now
936 the result does not match the "mode" of cdrecord -toc.
937 */
938 /*
939 #warning sector_identify needs to be written
940 */
941 int sector_identify(unsigned char *data)
942 {
943
944 /*
945 burn_ecma130_scramble(data);
946 check mode byte for 1 or 2
947 test parity to see if it's a valid sector
948 if invalid, return BURN_MODE_AUDIO;
949 else return mode byte (what about mode 2 formless? heh)
950 */
951
952 return BURN_MODE1;
953 }