1 /* @(#)edc_ecc.c 1.31 13/04/28 Copyright 1998-2013 Heiko Eissfeldt, Joerg Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)edc_ecc.c 1.31 13/04/28 Copyright 1998-2013 Heiko Eissfeldt, Joerg Schilling";
6 #endif
7
8 /*
9 * Copyright 1998-2002,2008 by Heiko Eissfeldt
10 * Copyright 2002-2013 by Joerg Schilling
11 *
12 * This file contains protected intellectual property.
13 *
14 * reed-solomon encoder / decoder for compact discs.
15 *
16 */
17 /*
18 * The contents of this file are subject to the terms of the
19 * Common Development and Distribution License, Version 1.0 only
20 * (the "License"). You may not use this file except in compliance
21 * with the License.
22 *
23 * See the file CDDL.Schily.txt in this distribution for details.
24 * A copy of the CDDL is also available via the Internet at
25 * http://www.opensource.org/licenses/cddl1.txt
26 *
27 * When distributing Covered Code, include this CDDL HEADER in each
28 * file and include the License file CDDL.Schily.txt from this distribution.
29 */
30
31 #include <schily/stdio.h>
32 #include <schily/align.h>
33 #include <schily/utypes.h>
34 #include <schily/stdlib.h>
35 #include <schily/string.h>
36 #include "ecc.h"
37
38 #ifndef HAVE_MEMMOVE
39 #include <schily/libport.h> /* Define missing prototypes */
40 /*#define memmove(dst, src, size) movebytes((src), (dst), (size))*/
41 #define memmove(d, s, n) bcopy((s), (d), (n))
42 #endif
43
44 /*
45 * The functions do_decode_L1(), do_decode_L2(), decode_L1_P(), decode_L1_Q()
46 * are currently static and limited to debug mode (#ifdef MAIN).
47 * After they are ready, they will be made public without #ifdef MAIN.
48 */
49 #ifdef MAIN
50 /* these prototypes will become public when the function are implemented */
51 static int do_decode_L2 __PR((unsigned char in[(L2_RAW+L2_Q+L2_P)],
52 unsigned char out[L2_RAW]));
53
54 static int do_decode_L1 __PR((unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
55 unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
56 int delay1, int delay2, int delay3, int scramble));
57 #endif
58
59
60 /* ------------- tables generated by gen_encodes --------------*/
61
62 #include "scramble_table"
63
64 #define DO4(a) a; a; a; a;
65 #define DO13(a) a; a; a; a; a; a; a; a; a; a; a; a; a;
66
67 /*
68 * Scrambles 2352 - 12 = 2340 bytes
69 */
70 int scramble_L2 __PR((unsigned char *inout));
71
72 int
scramble_L2(inout)73 scramble_L2(inout)
74 unsigned char *inout;
75 {
76 #ifndef EDC_SCRAMBLE_NOSWAP
77 unsigned int *f = (unsigned int *)inout;
78 #endif
79
80 if (!xaligned(inout + 12, sizeof (UInt32_t)-1)) {
81
82 Uchar *r = inout + 12;
83 const Uchar *s = yellowbook_scrambler;
84 register int i;
85
86 for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof (unsigned char)/4; --i >= 0; ) {
87 DO4(*r++ ^= *s++);
88 }
89
90 } else {
91 UInt32_t *r = (UInt32_t *) (inout + 12);
92 const UInt32_t *s = yellowbook_scrambler_uint32;
93 register int i;
94
95 for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof (UInt32_t)/13; --i >= 0; ) {
96 DO13(*r++ ^= *s++);
97 }
98 }
99
100 #ifndef EDC_SCRAMBLE_NOSWAP
101
102 /* generate F1 frames */
103 for (i = 2352/sizeof (unsigned int); i; i--) {
104 *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
105 }
106 #endif
107
108 return (0);
109 }
110
111 #include "l2sq_table"
112
113 int encode_L2_Q __PR((unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]));
114
115 int
encode_L2_Q(inout)116 encode_L2_Q(inout)
117 unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q];
118 {
119 unsigned char *dps;
120 unsigned char *dp;
121 unsigned char *Q;
122 register int i;
123 int j;
124
125 Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
126
127 dps = inout;
128 for (j = 0; j < 26; j++) {
129 register unsigned short a;
130 register unsigned short b;
131 a = b = 0;
132
133 dp = dps;
134 for (i = 0; i < 43; i++) {
135
136 /* LSB */
137 a ^= L2sq[i][*dp++];
138
139 /* MSB */
140 b ^= L2sq[i][*dp];
141
142 dp += 2*44-1;
143 if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) {
144 dp -= (4 + L2_RAW + 4 + 8 + L2_P);
145 }
146 }
147 Q[0] = a >> 8;
148 Q[26*2] = a;
149 Q[1] = b >> 8;
150 Q[26*2+1] = b;
151
152 Q += 2;
153 dps += 2*43;
154 }
155 return (0);
156 }
157
158 int encode_L2_P __PR((unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]));
159
160 int
encode_L2_P(inout)161 encode_L2_P(inout)
162 unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P];
163 {
164 unsigned char *dp;
165 unsigned char *P;
166 register int i;
167 int j;
168
169 P = inout + 4 + L2_RAW + 4 + 8;
170
171 for (j = 0; j < 43; j++) {
172 register unsigned short a;
173 register unsigned short b;
174
175 a = b = 0;
176 dp = inout;
177 for (i = 19; i < 43; i++) {
178
179 /* LSB */
180 a ^= L2sq[i][*dp++];
181
182 /* MSB */
183 b ^= L2sq[i][*dp];
184
185 dp += 2*43 -1;
186 }
187 P[0] = a >> 8;
188 P[43*2] = a;
189 P[1] = b >> 8;
190 P[43*2+1] = b;
191
192 P += 2;
193 inout += 2;
194 }
195 return (0);
196 }
197
198 static unsigned char bin2bcd __PR((unsigned p));
199
200 static unsigned char
bin2bcd(p)201 bin2bcd(p)
202 unsigned p;
203 {
204 return ((p/10)<<4)|(p%10);
205 }
206
207 static int build_address __PR((unsigned char inout[], int sectortype, unsigned address));
208
209 static int
build_address(inout,sectortype,address)210 build_address(inout, sectortype, address)
211 unsigned char inout[];
212 int sectortype;
213 unsigned address;
214 {
215 inout[12] = bin2bcd(address / (60*75));
216 inout[13] = bin2bcd((address / 75) % 60);
217 inout[14] = bin2bcd(address % 75);
218 if (sectortype == MODE_0)
219 inout[15] = 0;
220 else if (sectortype == MODE_1)
221 inout[15] = 1;
222 else if (sectortype == MODE_2)
223 inout[15] = 2;
224 else if (sectortype == MODE_2_FORM_1)
225 inout[15] = 2;
226 else if (sectortype == MODE_2_FORM_2)
227 inout[15] = 2;
228 else
229 return (-1);
230 return (0);
231 }
232
233 #include "crctable.out"
234
235 /*
236 * Called with 2064, 2056 or 2332 byte difference - all dividable by 4.
237 */
238 unsigned int build_edc __PR((unsigned char inout[], int from, int upto));
239
240 unsigned int
build_edc(inout,from,upto)241 build_edc(inout, from, upto)
242 unsigned char inout[];
243 int from;
244 int upto;
245 {
246 unsigned char *p = inout+from;
247 unsigned int result = 0;
248
249 upto -= from-1;
250 upto /= 4;
251 while (--upto >= 0) {
252 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
253 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
254 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
255 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
256 }
257 return (result);
258 }
259
260 /* Layer 2 Product code en/decoder */
261 int do_encode_L2 __PR((unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address));
262
263 int
do_encode_L2(inout,sectortype,address)264 do_encode_L2(inout, sectortype, address)
265 unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)];
266 int sectortype;
267 unsigned address;
268 {
269 unsigned int result;
270
271 /* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */
272 #define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377"
273
274 /* supply initial sync pattern */
275 memcpy(inout, SYNCPATTERN, sizeof (SYNCPATTERN));
276
277 if (sectortype == MODE_0) {
278 memset(inout + sizeof (SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
279 build_address(inout, sectortype, address);
280 return (0);
281 }
282
283 switch (sectortype) {
284
285 case MODE_1:
286 build_address(inout, sectortype, address);
287 result = build_edc(inout, 0, 16+2048-1);
288 inout[2064+0] = result >> 0L;
289 inout[2064+1] = result >> 8L;
290 inout[2064+2] = result >> 16L;
291 inout[2064+3] = result >> 24L;
292 memset(inout+2064+4, 0, 8);
293 encode_L2_P(inout+12);
294 encode_L2_Q(inout+12);
295 break;
296 case MODE_2:
297 build_address(inout, sectortype, address);
298 break;
299 case MODE_2_FORM_1:
300 result = build_edc(inout, 16, 16+8+2048-1);
301 inout[2072+0] = result >> 0L;
302 inout[2072+1] = result >> 8L;
303 inout[2072+2] = result >> 16L;
304 inout[2072+3] = result >> 24L;
305
306 /* clear header for P/Q parity calculation */
307 inout[12] = 0;
308 inout[12+1] = 0;
309 inout[12+2] = 0;
310 inout[12+3] = 0;
311 encode_L2_P(inout+12);
312 encode_L2_Q(inout+12);
313 build_address(inout, sectortype, address);
314 break;
315 case MODE_2_FORM_2:
316 build_address(inout, sectortype, address);
317 result = build_edc(inout, 16, 16+8+2324-1);
318 inout[2348+0] = result >> 0L;
319 inout[2348+1] = result >> 8L;
320 inout[2348+2] = result >> 16L;
321 inout[2348+3] = result >> 24L;
322 break;
323 default:
324 return (-1);
325 }
326
327 return (0);
328 }
329
330
331 /*--------------------------------------------------------------------------*/
332 #include "encoder_tables"
333
334 static int encode_L1_Q __PR((unsigned char inout[L1_RAW + L1_Q]));
335
336 static int
encode_L1_Q(inout)337 encode_L1_Q(inout)
338 unsigned char inout[L1_RAW + L1_Q];
339 {
340 unsigned char *Q;
341 int i;
342
343 memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2);
344 Q = inout + L1_RAW/2;
345
346 memset(Q, 0, L1_Q);
347 for (i = 0; i < L1_RAW; i++) {
348 unsigned char data;
349
350 if (i == L1_RAW/2) {
351 inout += L1_Q;
352 }
353 data = inout[i];
354 if (data != 0) {
355 unsigned char base = rs_l12_log[data];
356
357 Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
358 Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
359 Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
360 Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
361 }
362 }
363 return (0);
364 }
365
366 static int encode_L1_P __PR((unsigned char inout[L1_RAW + L1_Q + L1_P]));
367
368 static int
encode_L1_P(inout)369 encode_L1_P(inout)
370 unsigned char inout[L1_RAW + L1_Q + L1_P];
371 {
372 unsigned char *P;
373 int i;
374
375 P = inout + L1_RAW + L1_Q;
376
377 memset(P, 0, L1_P);
378 for (i = 0; i < L1_RAW + L1_Q + L1_P; i++) {
379 unsigned char data;
380
381 data = inout[i];
382 if (data != 0) {
383 unsigned char base = rs_l12_log[data];
384
385 P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
386 P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
387 P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
388 P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
389 }
390 }
391 return (0);
392 }
393
394 #ifdef MAIN /* Make public (non-static) if completely implemented */
395
396 static int decode_L1_Q __PR((unsigned char inout[L1_RAW + L1_Q]));
397
398 static int
decode_L1_Q(inout)399 decode_L1_Q(inout)
400 unsigned char inout[L1_RAW + L1_Q];
401 {
402 return (0);
403 }
404
405 static int decode_L1_P __PR((unsigned char in[L1_RAW + L1_Q + L1_P]));
406
407 static int
decode_L1_P(in)408 decode_L1_P(in)
409 unsigned char in[L1_RAW + L1_Q + L1_P];
410 {
411 return (0);
412 }
413 #endif /* MAIN */
414
415 int decode_L2_Q __PR((unsigned char inout[4 + L2_RAW + 12 + L2_Q]));
416
417 int
decode_L2_Q(inout)418 decode_L2_Q(inout)
419 unsigned char inout[4 + L2_RAW + 12 + L2_Q];
420 {
421 return (0);
422 }
423
424 int decode_L2_P __PR((unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]));
425
426 int
decode_L2_P(inout)427 decode_L2_P(inout)
428 unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P];
429 {
430 return (0);
431 }
432
433 static int encode_LSUB_Q __PR((unsigned char inout[LSUB_RAW + LSUB_Q]));
434
435 static int
encode_LSUB_Q(inout)436 encode_LSUB_Q(inout)
437 unsigned char inout[LSUB_RAW + LSUB_Q];
438 {
439 unsigned char *Q;
440 int i;
441
442 memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW);
443 Q = inout + LSUB_QRAW;
444
445 memset(Q, 0, LSUB_Q);
446
447 for (i = 0; i < LSUB_QRAW; i++) {
448 unsigned char data;
449
450 data = inout[i] & 0x3f;
451 if (data != 0) {
452 unsigned char base = rs_sub_rw_log[data];
453
454 Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
455 Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
456 }
457 }
458 return (0);
459 }
460
461
462 static int encode_LSUB_P __PR((unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]));
463
464 static int
encode_LSUB_P(inout)465 encode_LSUB_P(inout)
466 unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P];
467 {
468 unsigned char *P;
469 int i;
470
471 P = inout + LSUB_RAW + LSUB_Q;
472
473 memset(P, 0, LSUB_P);
474 for (i = 0; i < LSUB_RAW + LSUB_Q; i++) {
475 unsigned char data;
476
477 data = inout[i] & 0x3f;
478 if (data != 0) {
479 unsigned char base = rs_sub_rw_log[data];
480
481 P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
482 P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
483 P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
484 P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
485 }
486 }
487 return (0);
488 }
489
490 int decode_LSUB_Q __PR((unsigned char inout[LSUB_QRAW + LSUB_Q]));
491
492 int
decode_LSUB_Q(inout)493 decode_LSUB_Q(inout)
494 unsigned char inout[LSUB_QRAW + LSUB_Q];
495 {
496 unsigned char Q[LSUB_Q];
497 int i;
498
499 memset(Q, 0, LSUB_Q);
500 for (i = LSUB_QRAW + LSUB_Q -1; i >= 0; i--) {
501 unsigned char data;
502
503 data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f;
504 if (data != 0) {
505 unsigned char base = rs_sub_rw_log[data];
506
507 Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
508 Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
509 }
510 }
511 return (Q[0] != 0 || Q[1] != 0);
512 }
513
514 int decode_LSUB_P __PR((unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]));
515
516 int
decode_LSUB_P(inout)517 decode_LSUB_P(inout)
518 unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P];
519 {
520 unsigned char P[LSUB_P];
521 int i;
522
523 memset(P, 0, LSUB_P);
524 for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i >= 0; i--) {
525 unsigned char data;
526
527 data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f;
528 if (data != 0) {
529 unsigned char base = rs_sub_rw_log[data];
530
531 P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
532 P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
533 P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
534 P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
535 }
536 }
537 return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0);
538 }
539
540 /* Layer 1 CIRC en/decoder */
541 #define MAX_L1_DEL1 2
542 static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];
543 #define MAX_L1_DEL2 108
544 static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];
545 #define MAX_L1_DEL3 1
546 static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P];
547 static unsigned l1_del_index;
548
549 int do_encode_L1 __PR((unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
550 unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
551 int delay1, int delay2, int delay3, int permute));
552
553 int
do_encode_L1(in,out,delay1,delay2,delay3,permute)554 do_encode_L1(in, out, delay1, delay2, delay3, permute)
555 unsigned char in[L1_RAW*FRAMES_PER_SECTOR];
556 unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
557 int delay1;
558 int delay2;
559 int delay3;
560 int permute;
561 {
562 int i;
563
564 for (i = 0; i < FRAMES_PER_SECTOR; i++) {
565 int j;
566 unsigned char t;
567
568 if (in != out)
569 memcpy(out, in, L1_RAW);
570
571 if (delay1) {
572 /* shift through delay line 1 */
573 for (j = 0; j < L1_RAW; j++) {
574 if (((j/4) % MAX_L1_DEL1) == 0) {
575 t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
576 l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j];
577 out[j] = t;
578 }
579 }
580 }
581
582 if (permute) {
583 /* permute */
584 t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18];
585 out[18] = out[6]; out [6] = t;
586 t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19];
587 out[19] = out[7]; out [7] = t;
588 t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14];
589 out[14] = out[12]; out [12] = t;
590 t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15];
591 out[15] = out[13]; out [13] = t;
592 }
593
594 /* build Q parity */
595 encode_L1_Q(out);
596
597 if (delay2) {
598 /* shift through delay line 2 */
599 for (j = 0; j < L1_RAW+L1_Q; j++) {
600 if (j != 0) {
601 t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
602 l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j];
603 out[j] = t;
604 }
605 }
606 }
607
608 /* build P parity */
609 encode_L1_P(out);
610
611 if (delay3) {
612 /* shift through delay line 3 */
613 for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
614 if (((j) & MAX_L1_DEL3) == 0) {
615 t = l1_delay_line3[0][j];
616 l1_delay_line3[0][j] = out[j];
617 out[j] = t;
618 }
619 }
620 }
621
622 /* invert Q and P parity */
623 for (j = 0; j < L1_Q; j++)
624 out[j+12] = ~out[j+12];
625 for (j = 0; j < L1_P; j++)
626 out[j+28] = ~out[j+28];
627
628 l1_del_index++;
629 out += L1_RAW+L1_Q+L1_P;
630 in += L1_RAW;
631 }
632 return (0);
633 }
634
635 #ifdef MAIN /* Make public (non-static) if completely implemented */
636
637 static /* XXX should be non static XXX*/
638
639 int
do_decode_L1(in,out,delay1,delay2,delay3,permute)640 do_decode_L1(in, out, delay1, delay2, delay3, permute)
641 unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
642 unsigned char out[L1_RAW*FRAMES_PER_SECTOR];
643 int delay1;
644 int delay2;
645 int delay3;
646 int permute;
647 {
648 int i;
649
650 for (i = 0; i < FRAMES_PER_SECTOR; i++) {
651 int j;
652 unsigned char t;
653
654 if (delay3) {
655 /* shift through delay line 3 */
656 for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
657 if (((j) & MAX_L1_DEL3) != 0) {
658 t = l1_delay_line3[0][j];
659 l1_delay_line3[0][j] = in[j];
660 in[j] = t;
661 }
662 }
663 }
664
665 /* invert Q and P parity */
666 for (j = 0; j < L1_Q; j++)
667 in[j+12] = ~in[j+12];
668 for (j = 0; j < L1_P; j++)
669 in[j+28] = ~in[j+28];
670
671 /* build P parity */
672 decode_L1_P(in);
673
674 if (delay2) {
675 /* shift through delay line 2 */
676 for (j = 0; j < L1_RAW+L1_Q; j++) {
677 if (j != L1_RAW+L1_Q-1) {
678 t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
679 l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j];
680 in[j] = t;
681 }
682 }
683 }
684
685 /* build Q parity */
686 decode_L1_Q(in);
687
688 if (permute) {
689 /* permute */
690 t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10];
691 in[10] = in[8]; in [8] = t;
692 t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11];
693 in[11] = in[9]; in [9] = t;
694 t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20];
695 in[20] = in[16]; in [16] = t;
696 t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21];
697 in[21] = in[17]; in [17] = t;
698 }
699
700 if (delay1) {
701 /* shift through delay line 1 */
702 for (j = 0; j < L1_RAW; j++) {
703 if (((j/4) % MAX_L1_DEL1) != 0) {
704 t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
705 l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j];
706 in[j] = t;
707 }
708 }
709 }
710
711 if (in != out)
712 memcpy(out, in, (L1_RAW));
713
714 l1_del_index++;
715 in += L1_RAW+L1_Q+L1_P;
716 out += L1_RAW;
717 }
718 return (0);
719 }
720
721 static int
do_decode_L2(in,out)722 do_decode_L2(in, out)
723 unsigned char in[(L2_RAW+L2_Q+L2_P)];
724 unsigned char out[L2_RAW];
725 {
726 return (0);
727 }
728 #endif /* MAIN */
729
730
731 #define MAX_SUB_DEL 8
732 static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P];
733 static unsigned sub_del_index;
734
735 /* R-W Subchannel en/decoder */
736
737 int do_encode_sub __PR((unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
738 unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
739 int delay1, int permute));
740
741 int
do_encode_sub(in,out,delay1,permute)742 do_encode_sub(in, out, delay1, permute)
743 unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME];
744 unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME];
745 int delay1;
746 int permute;
747 {
748 int i;
749
750 if (in == out)
751 return (-1);
752
753 for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
754 int j;
755 unsigned char t;
756
757 memcpy(out, in, (LSUB_RAW));
758
759 /* build Q parity */
760 encode_LSUB_Q(out);
761
762 /* build P parity */
763 encode_LSUB_P(out);
764
765 if (permute) {
766 /* permute */
767 t = out[1]; out[1] = out[18]; out[18] = t;
768 t = out[2]; out[2] = out[ 5]; out[ 5] = t;
769 t = out[3]; out[3] = out[23]; out[23] = t;
770 }
771
772 if (delay1) {
773 /* shift through delay_line */
774 for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
775 if ((j % MAX_SUB_DEL) != 0) {
776 t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
777 sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j];
778 out[j] = t;
779 }
780 }
781 }
782 sub_del_index++;
783 out += LSUB_RAW+LSUB_Q+LSUB_P;
784 in += LSUB_RAW;
785 }
786 return (0);
787 }
788
789 int
790 do_decode_sub __PR((
791 unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
792 unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
793 int delay1, int permute));
794
795 int
do_decode_sub(in,out,delay1,permute)796 do_decode_sub(in, out, delay1, permute)
797 unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME];
798 unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME];
799 int delay1;
800 int permute;
801 {
802 int i;
803
804 if (in == out)
805 return (-1);
806
807 for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
808 int j;
809 unsigned char t;
810
811 if (delay1) {
812 /* shift through delay_line */
813 for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
814 if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) {
815 t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
816 sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j];
817 in[j] = t;
818 }
819 }
820 }
821
822 if (permute) {
823 /* permute */
824 t = in[1]; in[1] = in[18]; in[18] = t;
825 t = in[2]; in[2] = in[ 5]; in[ 5] = t;
826 t = in[3]; in[3] = in[23]; in[23] = t;
827 }
828
829 /* build P parity */
830 decode_LSUB_P(in);
831
832 /* build Q parity */
833 decode_LSUB_Q(in);
834
835 memcpy(out, in, LSUB_QRAW);
836 memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW);
837
838 sub_del_index++;
839 in += LSUB_RAW+LSUB_Q+LSUB_P;
840 out += LSUB_RAW;
841 }
842 return (0);
843 }
844
845 static int sectortype = MODE_0;
846
847 int get_sector_type __PR((void));
848
849 int
get_sector_type()850 get_sector_type()
851 {
852 return (sectortype);
853 }
854
855 int set_sector_type __PR((int st));
856
857 int
set_sector_type(st)858 set_sector_type(st)
859 int st;
860 {
861 switch (st) {
862
863 case MODE_0:
864 case MODE_1:
865 case MODE_2:
866 case MODE_2_FORM_1:
867 case MODE_2_FORM_2:
868 sectortype = st;
869 return (0);
870 default:
871 return (-1);
872 }
873 }
874
875 /* ------------- --------------*/
876 #ifdef MAIN
877
878 #define DO_L1 1
879 #define DO_L2 2
880 #define DO_SUB 4
881
882 static const unsigned sect_size[8][2] = {
883 /* nothing */
884 {0, 0},
885 /* Layer 1 decode/encode */
886 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
887 /* Layer 2 decode/encode */
888 { 16+L2_RAW+12+L2_Q+L2_P, L2_RAW},
889 /* Layer 1 and 2 decode/encode */
890 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
891 /* Subchannel decode/encode */
892 { (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
893 LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME},
894 /* Layer 1 and subchannel decode/encode */
895 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
896 (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
897 LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
898 L1_RAW*FRAMES_PER_SECTOR},
899 /* Layer 2 and subchannel decode/encode */
900 { L2_RAW+L2_Q+L2_P +
901 (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
902 LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
903 L2_RAW},
904 /* Layer 1, 2 and subchannel decode/encode */
905 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
906 (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
907 LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
908 L1_RAW*FRAMES_PER_SECTOR},
909 };
910
911 int main __PR((int argc, char **argv));
912
913 int
main(argc,argv)914 main(argc, argv)
915 int argc;
916 char **argv;
917 {
918 int encode = 1;
919 int mask = DO_L2;
920 FILE *infp;
921 FILE *outfp;
922 unsigned address = 0;
923 unsigned char *l1_inbuf;
924 unsigned char *l1_outbuf;
925 unsigned char *l2_inbuf;
926 unsigned char *l2_outbuf;
927 unsigned char *sub_inbuf;
928 unsigned char *sub_outbuf;
929 unsigned char *last_outbuf;
930 unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
931 (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
932 unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
933 (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
934 unsigned load_offset;
935
936 l1_inbuf = l2_inbuf = sub_inbuf = inbuf;
937 l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf;
938
939 infp = fopen("sectors_in", "rb");
940 outfp = fopen("sectors_out", "wb");
941
942 sectortype = MODE_1;
943 address = 0 + 75*2;
944
945 switch (sectortype) {
946
947 case MODE_1:
948 case MODE_2:
949 load_offset = 16;
950 break;
951 case MODE_2_FORM_1:
952 case MODE_2_FORM_2:
953 load_offset = 24;
954 break;
955 default:
956 load_offset = 0;
957 }
958 while (1) {
959
960 if (1 != fread(inbuf+load_offset,
961 sect_size[mask][encode], 1, infp)) {
962 perror("");
963 break;
964 }
965 if (encode == 1) {
966 if (mask & DO_L2) {
967 switch (sectortype) {
968
969 case MODE_0:
970 break;
971 case MODE_1:
972 break;
973 case MODE_2:
974 if (1 !=
975 fread(inbuf+load_offset+
976 sect_size[mask][encode],
977 2336 - sect_size[mask][encode],
978 1, infp)) { perror(""); break; }
979 break;
980 case MODE_2_FORM_1:
981 break;
982 case MODE_2_FORM_2:
983 if (1 !=
984 fread(inbuf+load_offset+
985 sect_size[mask][encode],
986 2324 - sect_size[mask][encode],
987 1, infp)) { perror(""); break; }
988 break;
989 default:
990 if (1 !=
991 fread(inbuf+load_offset+
992 sect_size[mask][encode],
993 2448 - sect_size[mask][encode],
994 1, infp)) { perror(""); break; }
995 memset(inbuf, 0, 16);
996 /*memset(inbuf+16+2048,0,12+272);*/
997 break;
998 }
999 do_encode_L2(l2_inbuf, MODE_1, address);
1000 if (0) scramble_L2(l2_inbuf);
1001 last_outbuf = l1_inbuf = l2_inbuf;
1002 l1_outbuf = l2_inbuf;
1003 sub_inbuf = l2_inbuf + L2_RAW;
1004 sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P;
1005 }
1006 if (mask & DO_L1) {
1007 do_encode_L1(l1_inbuf, l1_outbuf, 1, 1, 1, 1);
1008 last_outbuf = l1_outbuf;
1009 sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR;
1010 sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1011 }
1012 if (mask & DO_SUB) {
1013 do_encode_sub(sub_inbuf, sub_outbuf, 0, 0);
1014 }
1015 } else {
1016 if (mask & DO_L1) {
1017 do_decode_L1(l1_inbuf, l1_outbuf, 1, 1, 1, 1);
1018 last_outbuf = l2_inbuf = l1_outbuf;
1019 l2_outbuf = l1_inbuf;
1020 sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1021 sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR;
1022 }
1023 if (mask & DO_L2) {
1024 do_decode_L2(l2_inbuf, l2_outbuf);
1025 last_outbuf = l2_outbuf;
1026 sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P;
1027 sub_outbuf = l2_outbuf + L2_RAW;
1028 }
1029 if (mask & DO_SUB) {
1030 do_decode_sub(sub_inbuf, sub_outbuf, 1, 1);
1031 }
1032 }
1033 if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) {
1034 perror("");
1035 break;
1036 }
1037 address++;
1038 }
1039 #if 0
1040 /* flush the data from the delay lines with zeroed sectors, if necessary */
1041 #endif
1042 fclose(infp);
1043 fclose(outfp);
1044
1045 return (0);
1046 }
1047 #endif
1048