diff options
Diffstat (limited to 'libedc/edc_ecc.c')
-rw-r--r-- | libedc/edc_ecc.c | 983 |
1 files changed, 983 insertions, 0 deletions
diff --git a/libedc/edc_ecc.c b/libedc/edc_ecc.c new file mode 100644 index 0000000..f98d4c5 --- /dev/null +++ b/libedc/edc_ecc.c @@ -0,0 +1,983 @@ +/* + * This file has been modified for the cdrkit suite. + * + * The behaviour and appearence of the program code below can differ to a major + * extent from the version distributed by the original author(s). + * + * For details, see Changelog file distributed with the cdrkit package. If you + * received this file from another source then ask the distributing person for + * a log of modifications. + * + */ + +/* @(#)edc_ecc.c 1.21 03/04/04 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */ + +/* + * Copyright 1998-2002 by Heiko Eissfeldt + * Copyright 2002 by Joerg Schilling + * + * This file contains protected intellectual property. + * + * reed-solomon encoder / decoder for compact discs. + * + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <mconfig.h> +#include <stdio.h> +#include <align.h> +#include <utypes.h> +#include <stdxlib.h> +#include <strdefs.h> +#include "ecc.h" + +#ifndef HAVE_MEMMOVE +/*#define memmove(dst, src, size) movebytes((src), (dst), (size))*/ +#define memmove(d, s, n) bcopy ((s), (d), (n)) +#endif + +/* these prototypes will become public when the function are implemented */ +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]); + +static int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int scramble); + + +/* ------------- tables generated by gen_encodes --------------*/ + +#include "scramble_table" + +#define DO4(a) a;a;a;a; +#define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a; + +/* + * Scrambles 2352 - 12 = 2340 bytes + */ +int scramble_L2(unsigned char *inout); + +int scramble_L2(unsigned char *inout) +{ +#ifndef EDC_SCRAMBLE_NOSWAP + unsigned int *f = (unsigned int *)inout; +#endif + + if (!xaligned(inout + 12, sizeof(UInt32_t)-1)) { + + Uchar *r = inout + 12; + const Uchar *s = yellowbook_scrambler; + register int i; + + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) { + DO4(*r++ ^= *s++); + } + + } else { + UInt32_t *r = (UInt32_t *) (inout + 12); + const UInt32_t *s = yellowbook_scrambler_uint32; + register int i; + + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(UInt32_t)/13; --i >= 0;) { + DO13(*r++ ^= *s++); + } + } + +#ifndef EDC_SCRAMBLE_NOSWAP + + /* generate F1 frames */ + for (i = 2352/sizeof(unsigned int); i; i--) { + *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8); + } +#endif + + return (0); +} + +#include "l2sq_table" + +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]); + +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]) +{ + unsigned char *dps; + unsigned char *dp; + unsigned char *Q; + register int i; + int j; + + Q = inout + 4 + L2_RAW + 4 + 8 + L2_P; + + dps = inout; + for (j = 0; j < 26; j++) { + register unsigned short a; + register unsigned short b; + a = b = 0; + + dp = dps; + for (i = 0; i < 43; i++) { + + /* LSB */ + a ^= L2sq[i][*dp++]; + + /* MSB */ + b ^= L2sq[i][*dp]; + + dp += 2*44-1; + if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) { + dp -= (4 + L2_RAW + 4 + 8 + L2_P); + } + } + Q[0] = a >> 8; + Q[26*2] = a; + Q[1] = b >> 8; + Q[26*2+1] = b; + + Q += 2; + dps += 2*43; + } + return (0); +} + +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]); + +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]) +{ + unsigned char *dp; + unsigned char *P; + register int i; + int j; + + P = inout + 4 + L2_RAW + 4 + 8; + + for (j = 0; j < 43; j++) { + register unsigned short a; + register unsigned short b; + + a = b = 0; + dp = inout; + for (i = 19; i < 43; i++) { + + /* LSB */ + a ^= L2sq[i][*dp++]; + + /* MSB */ + b ^= L2sq[i][*dp]; + + dp += 2*43 -1; + } + P[0] = a >> 8; + P[43*2] = a; + P[1] = b >> 8; + P[43*2+1] = b; + + P += 2; + inout += 2; + } + return (0); +} + +static unsigned char bin2bcd(unsigned p); + +static unsigned char bin2bcd(unsigned p) +{ + return ((p/10)<<4)|(p%10); +} + +static int build_address(unsigned char inout[], int sectortype, unsigned address); + +static int +build_address(unsigned char inout[], int sectortype, unsigned address) +{ + inout[12] = bin2bcd(address / (60*75)); + inout[13] = bin2bcd((address / 75) % 60); + inout[14] = bin2bcd(address % 75); + if (sectortype == MODE_0) + inout[15] = 0; + else if (sectortype == MODE_1) + inout[15] = 1; + else if (sectortype == MODE_2) + inout[15] = 2; + else if (sectortype == MODE_2_FORM_1) + inout[15] = 2; + else if (sectortype == MODE_2_FORM_2) + inout[15] = 2; + else + return (-1); + return (0); +} + +#include "crctable.out" + +/* + * Called with 2064, 2056 or 2332 byte difference - all dividable by 4. + */ +unsigned int build_edc(unsigned char inout[], int from, int upto); + +unsigned int build_edc(unsigned char inout[], int from, int upto) +{ + unsigned char *p = inout+from; + unsigned int result = 0; + + upto -= from-1; + upto /= 4; + while (--upto >= 0) { + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + } + return (result); +} + +/* Layer 2 Product code en/decoder */ +int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], + int sectortype, unsigned address); + +int +do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], + int sectortype, unsigned address) +{ + unsigned int result; + +/* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */ +#define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377" + + /* supply initial sync pattern */ + memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN)); + + if (sectortype == MODE_0) { + memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q); + build_address(inout, sectortype, address); + return (0); + } + + switch (sectortype) { + + case MODE_1: + build_address(inout, sectortype, address); + result = build_edc(inout, 0, 16+2048-1); + inout[2064+0] = result >> 0L; + inout[2064+1] = result >> 8L; + inout[2064+2] = result >> 16L; + inout[2064+3] = result >> 24L; + memset(inout+2064+4, 0, 8); + encode_L2_P(inout+12); + encode_L2_Q(inout+12); + break; + case MODE_2: + build_address(inout, sectortype, address); + break; + case MODE_2_FORM_1: + result = build_edc(inout, 16, 16+8+2048-1); + inout[2072+0] = result >> 0L; + inout[2072+1] = result >> 8L; + inout[2072+2] = result >> 16L; + inout[2072+3] = result >> 24L; + + /* clear header for P/Q parity calculation */ + inout[12] = 0; + inout[12+1] = 0; + inout[12+2] = 0; + inout[12+3] = 0; + encode_L2_P(inout+12); + encode_L2_Q(inout+12); + build_address(inout, sectortype, address); + break; + case MODE_2_FORM_2: + build_address(inout, sectortype, address); + result = build_edc(inout, 16, 16+8+2324-1); + inout[2348+0] = result >> 0L; + inout[2348+1] = result >> 8L; + inout[2348+2] = result >> 16L; + inout[2348+3] = result >> 24L; + break; + default: + return (-1); + } + + return (0); +} + + +/*--------------------------------------------------------------------------*/ +#include "encoder_tables" + +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); + +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) +{ + unsigned char *Q; + int i; + + memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2); + Q = inout + L1_RAW/2; + + memset(Q, 0, L1_Q); + for (i = 0; i < L1_RAW + L1_Q; i++) { + unsigned char data; + + if (i == L1_RAW/2) i += L1_Q; + data = inout[i]; + if (data != 0) { + unsigned char base = rs_l12_log[data]; + + Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + } + } + return (0); +} + +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]); + +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]) +{ + unsigned char *P; + int i; + + P = inout + L1_RAW + L1_Q; + + memset(P, 0, L1_P); + for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) { + unsigned char data; + + data = inout[i]; + if (data != 0) { + unsigned char base = rs_l12_log[data]; + + P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + } + } + return (0); +} + +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); + +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) +{ + return (0); +} + +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]); + +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]) +{ + return (0); +} + +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]); + +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]) +{ + return (0); +} + +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]); + +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]) +{ + return (0); +} + +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]); + +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]) +{ + unsigned char *Q; + int i; + + memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW); + Q = inout + LSUB_QRAW; + + memset(Q, 0, LSUB_Q); + + for (i = 0; i < LSUB_QRAW; i++) { + unsigned char data; + + data = inout[i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (0); +} + + +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); + +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) +{ + unsigned char *P; + int i; + + P = inout + LSUB_RAW + LSUB_Q; + + memset(P, 0, LSUB_P); + for (i = 0; i < LSUB_RAW + LSUB_Q; i++) { + unsigned char data; + + data = inout[i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (0); +} + +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]); + +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]) +{ + unsigned char Q[LSUB_Q]; + int i; + + memset(Q, 0, LSUB_Q); + for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) { + unsigned char data; + + data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (Q[0] != 0 || Q[1] != 0); +} + +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); + +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) +{ + unsigned char P[LSUB_P]; + int i; + + memset(P, 0, LSUB_P); + for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) { + unsigned char data; + + data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0); +} + +/* Layer 1 CIRC en/decoder */ +#define MAX_L1_DEL1 2 +static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW]; +#define MAX_L1_DEL2 108 +static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q]; +#define MAX_L1_DEL3 1 +static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P]; +static unsigned l1_del_index; + +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute); + +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute) +{ + int i; + + for (i = 0; i < FRAMES_PER_SECTOR; i++) { + int j; + unsigned char t; + + if (in != out) + memcpy(out, in, L1_RAW); + + if (delay1) { + /* shift through delay line 1 */ + for (j = 0; j < L1_RAW; j++) { + if (((j/4) % MAX_L1_DEL1) == 0) { + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j]; + out[j] = t; + } + } + } + + if (permute) { + /* permute */ + t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18]; + out[18] = out[6]; out [6] = t; + t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19]; + out[19] = out[7]; out [7] = t; + t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14]; + out[14] = out[12]; out [12] = t; + t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15]; + out[15] = out[13]; out [13] = t; + } + + /* build Q parity */ + encode_L1_Q(out); + + if (delay2) { + /* shift through delay line 2 */ + for (j = 0; j < L1_RAW+L1_Q; j++) { + if (j != 0) { + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; + l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j]; + out[j] = t; + } + } + } + + /* build P parity */ + encode_L1_P(out); + + if (delay3) { + /* shift through delay line 3 */ + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { + if (((j) & MAX_L1_DEL3) == 0) { + t = l1_delay_line3[0][j]; + l1_delay_line3[0][j] = out[j]; + out[j] = t; + } + } + } + + /* invert Q and P parity */ + for (j = 0; j < L1_Q; j++) + out[j+12] = ~out[j+12]; + for (j = 0; j < L1_P; j++) + out[j+28] = ~out[j+28]; + + l1_del_index++; + out += L1_RAW+L1_Q+L1_P; + in += L1_RAW; + } + return (0); +} + +static +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute); + +static /* XXX should be non static XXX*/ + +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute) +{ + int i; + + for (i = 0; i < FRAMES_PER_SECTOR; i++) { + int j; + unsigned char t; + + if (delay3) { + /* shift through delay line 3 */ + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { + if (((j) & MAX_L1_DEL3) != 0) { + t = l1_delay_line3[0][j]; + l1_delay_line3[0][j] = in[j]; + in[j] = t; + } + } + } + + /* invert Q and P parity */ + for (j = 0; j < L1_Q; j++) + in[j+12] = ~in[j+12]; + for (j = 0; j < L1_P; j++) + in[j+28] = ~in[j+28]; + + /* build P parity */ + decode_L1_P(in); + + if (delay2) { + /* shift through delay line 2 */ + for (j = 0; j < L1_RAW+L1_Q; j++) { + if (j != L1_RAW+L1_Q-1) { + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; + l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j]; + in[j] = t; + } + } + } + + /* build Q parity */ + decode_L1_Q(in); + + if (permute) { + /* permute */ + t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10]; + in[10] = in[8]; in [8] = t; + t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11]; + in[11] = in[9]; in [9] = t; + t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20]; + in[20] = in[16]; in [16] = t; + t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21]; + in[21] = in[17]; in [17] = t; + } + + if (delay1) { + /* shift through delay line 1 */ + for (j = 0; j < L1_RAW; j++) { + if (((j/4) % MAX_L1_DEL1) != 0) { + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j]; + in[j] = t; + } + } + } + + if (in != out) + memcpy(out, in, (L1_RAW)); + + l1_del_index++; + in += L1_RAW+L1_Q+L1_P; + out += L1_RAW; + } + return (0); +} + +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]); + +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]) +{ + return (0); +} + + + +#define MAX_SUB_DEL 8 +static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P]; +static unsigned sub_del_index; + +/* R-W Subchannel en/decoder */ + +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute); + +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute) +{ + int i; + + if (in == out) return -1; + + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { + int j; + unsigned char t; + + memcpy(out, in, (LSUB_RAW)); + + /* build Q parity */ + encode_LSUB_Q(out); + + /* build P parity */ + encode_LSUB_P(out); + + if (permute) { + /* permute */ + t = out[1]; out[1] = out[18]; out[18] = t; + t = out[2]; out[2] = out[ 5]; out[ 5] = t; + t = out[3]; out[3] = out[23]; out[23] = t; + } + + if (delay1) { + /* shift through delay_line */ + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { + if ((j % MAX_SUB_DEL) != 0) { + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; + sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j]; + out[j] = t; + } + } + } + sub_del_index++; + out += LSUB_RAW+LSUB_Q+LSUB_P; + in += LSUB_RAW; + } + return (0); +} + +int +do_decode_sub( + unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute); + +int +do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute) +{ + int i; + + if (in == out) return -1; + + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { + int j; + unsigned char t; + + if (delay1) { + /* shift through delay_line */ + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { + if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) { + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; + sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j]; + in[j] = t; + } + } + } + + if (permute) { + /* permute */ + t = in[1]; in[1] = in[18]; in[18] = t; + t = in[2]; in[2] = in[ 5]; in[ 5] = t; + t = in[3]; in[3] = in[23]; in[23] = t; + } + + /* build P parity */ + decode_LSUB_P(in); + + /* build Q parity */ + decode_LSUB_Q(in); + + memcpy(out, in, LSUB_QRAW); + memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW); + + sub_del_index++; + in += LSUB_RAW+LSUB_Q+LSUB_P; + out += LSUB_RAW; + } + return (0); +} + +static int sectortype = MODE_0; + +int get_sector_type(void); + +int get_sector_type() +{ + return (sectortype); +} + +int set_sector_type(int st); + +int set_sector_type(int st) +{ + switch(st) { + + case MODE_0: + case MODE_1: + case MODE_2: + case MODE_2_FORM_1: + case MODE_2_FORM_2: + sectortype = st; + return 0; + default: + return -1; + } +} + +/* ------------- --------------*/ +#ifdef MAIN + +#define DO_L1 1 +#define DO_L2 2 +#define DO_SUB 4 + +static const unsigned sect_size[8][2] = { +/* nothing */ +{0,0}, +/* Layer 1 decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, +/* Layer 2 decode/encode */ +{ 16+L2_RAW+12+L2_Q+L2_P, L2_RAW}, +/* Layer 1 and 2 decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, +/* Subchannel decode/encode */ +{ (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME}, +/* Layer 1 and subchannel decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L1_RAW*FRAMES_PER_SECTOR}, +/* Layer 2 and subchannel decode/encode */ +{ L2_RAW+L2_Q+L2_P+ + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L2_RAW}, +/* Layer 1, 2 and subchannel decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L1_RAW*FRAMES_PER_SECTOR}, +}; + +int main(int argc, char *argv[]) +{ + int encode = 1; + int mask = DO_L2; + FILE *infp; + FILE *outfp; + unsigned address = 0; + unsigned char *l1_inbuf; + unsigned char *l1_outbuf; + unsigned char *l2_inbuf; + unsigned char *l2_outbuf; + unsigned char *sub_inbuf; + unsigned char *sub_outbuf; + unsigned char *last_outbuf; + unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; + unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; + unsigned load_offset; + + l1_inbuf = l2_inbuf = sub_inbuf = inbuf; + l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf; + + infp = fopen("sectors_in", "rb"); + outfp = fopen("sectors_out", "wb"); + + sectortype= MODE_1; + address = 0 + 75*2; + + switch (sectortype) { + + case MODE_1: + case MODE_2: + load_offset = 16; + break; + case MODE_2_FORM_1: + case MODE_2_FORM_2: + load_offset = 24; + break; + default: + load_offset = 0; + } + while(1) { + + if (1 != fread(inbuf+load_offset, + sect_size[mask][encode], 1, infp)) { + perror(""); + break; + } + if (encode == 1) { + if (mask & DO_L2) { + switch (sectortype) { + + case MODE_0: + break; + case MODE_1: + break; + case MODE_2: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2336 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + break; + case MODE_2_FORM_1: + break; + case MODE_2_FORM_2: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2324 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + break; + default: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2448 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + memset(inbuf,0,16); + /*memset(inbuf+16+2048,0,12+272);*/ + break; + } + do_encode_L2(l2_inbuf, MODE_1, address); + if (0) scramble_L2(l2_inbuf); + last_outbuf = l1_inbuf = l2_inbuf; + l1_outbuf = l2_inbuf; + sub_inbuf = l2_inbuf + L2_RAW; + sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P; + } + if (mask & DO_L1) { + do_encode_L1(l1_inbuf, l1_outbuf,1,1,1,1); + last_outbuf = l1_outbuf; + sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR; + sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; + } + if (mask & DO_SUB) { + do_encode_sub(sub_inbuf, sub_outbuf, 0, 0); + } + } else { + if (mask & DO_L1) { + do_decode_L1(l1_inbuf, l1_outbuf,1,1,1,1); + last_outbuf = l2_inbuf = l1_outbuf; + l2_outbuf = l1_inbuf; + sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; + sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR; + } + if (mask & DO_L2) { + do_decode_L2(l2_inbuf, l2_outbuf); + last_outbuf = l2_outbuf; + sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P; + sub_outbuf = l2_outbuf + L2_RAW; + } + if (mask & DO_SUB) { + do_decode_sub(sub_inbuf, sub_outbuf, 1, 1); + } + } + if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) { + perror(""); + break; + } + address++; + } +#if 0 + /* flush the data from the delay lines with zeroed sectors, if necessary */ +#endif + return (0); +} +#endif |