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