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