Files
cuetools.net/CUETools.Parity/RsDecode.cs

531 lines
28 KiB
C#
Raw Normal View History

2010-02-18 21:12:44 +00:00
<EFBFBD><EFBFBD>using System;
using System.Collections.Generic;
using System.Text;
namespace CUETools.Parity
{
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0: RS<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
*
* @author Masayuki Miyazaki
* http://sourceforge.jp/projects/reedsolomon/
*/
public class RsDecode
{
protected Galois galois;
protected int npar;
public RsDecode(int npar, Galois galois)
{
this.npar = npar;
this.galois = galois;
2011-11-15 10:56:49 +00:00
}
2010-02-18 21:12:44 +00:00
/// <summary>
/// Modified Berlekamp-Massey
/// </summary>
/// <param name="sigma">
/// <EFBFBD>(z)<h }(uM<EFBFBD>R0g'Ynpar/2 + 2 Pn0<EFBFBD><EFBFBD>WL0<EFBFBD>_<EFBFBD><EFBFBD>
/// <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD>[jisu]
/// </param>
/// <param name="omega">
/// <EFBFBD>(z)<h }(uM<EFBFBD>R0g'Ynpar/2 + 1 Pn0<EFBFBD><EFBFBD>WL0<EFBFBD>_<EFBFBD><EFBFBD>
/// <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD>[jisu-1]
/// </param>
/// <param name="syn">
/// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
/// s0,s1,s2, ... s[npar-1]
/// </param>
/// <returns>
/// >= 0: <EFBFBD>n0!kpe
/// else: <EFBFBD>0<EFBFBD>0<EFBFBD>0
/// </returns>
2010-02-23 15:15:08 +00:00
public unsafe int calcSigmaMBM(int* sigma, int* syn)
2010-02-18 21:12:44 +00:00
{
int* sg0 = stackalloc int[npar + 1];
int* sg1 = stackalloc int[npar + 1];
int* wk = stackalloc int[npar + 1];
sg0[1] = 1;
sg1[0] = 1;
int jisu0 = 1;
int jisu1 = 0;
int m = -1;
for (int n = 0; n < npar; n++)
{
// $R%R_<EFBFBD>0<EFBFBD><EFBFBD>{
int d = syn[n];
for (int i = 1; i <= jisu1; i++)
d ^= galois.mul(sg1[i], syn[n - i]);
if (d != 0)
{
int logd = galois.toLog(d);
for (int i = 0; i <= n; i++)
wk[i] = sg1[i] ^ galois.mulExp(sg0[i], logd);
int js = n - m;
if (js > jisu1)
{
for (int i = 0; i <= jisu0; i++)
sg0[i] = galois.divExp(sg1[i], logd);
m = n - jisu1;
jisu1 = js;
jisu0 = js;
}
for (int i = 0; i < npar; i++)
sg1[i] = wk[i];
}
for (int i = jisu0; i > 0; i--)
sg0[i] = sg0[i - 1];
sg0[0] = 0;
jisu0++;
}
if (sg1[jisu1] == 0)
return -1;
2010-02-23 15:15:08 +00:00
//galois.mulPoly(omega, sg1, syn, npar / 2 + 1, npar, npar);
2010-02-18 21:12:44 +00:00
for (int i = 0; i < Math.Min(npar / 2 + 2, npar); i++)
sigma[i] = sg1[i];
return jisu1;
}
public unsafe int calcSigmaMBM(int[] sigma, int[] omega, int[] syn)
{
fixed (int* s = sigma, o = omega, y = syn)
2010-02-23 15:15:08 +00:00
{
int res = calcSigmaMBM(s, y);
if (res >= 0) galois.mulPoly(o, s, y, npar / 2 + 1, npar, npar);
return res;
}
2010-02-18 21:12:44 +00:00
}
/**
* gB}<EFBFBD>0<EFBFBD>0<EFBFBD>0MOnn0<EFBFBD>0<EFBFBD>0<EFBFBD>0
* @param pos
* <EFBFBD><EFBFBD><EFBFBD>0MOn<h }(uRR
* @param n
* <EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param last
* <EFBFBD>0<EFBFBD>0<EFBFBD>0MOn
* @return
* 0: ck8^B}<EFBFBD>N
* < 0: <EFBFBD>0<EFBFBD>0<EFBFBD>0
*/
private unsafe bool setLastErrorPos(int* pos, int n, int last)
{
if (galois.toLog(last) >= n)
return false; // <EFBFBD>{<EFBFBD>VYj0n0g0<EFBFBD>0<EFBFBD>0<EFBFBD>0
pos[0] = last;
return true;
}
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>c"}k0<6B>0<EFBFBD>0<EFBFBD><30><EFBFBD>0MOn<6E>0Bl<42>0<EFBFBD>0
* <EFBFBD>(z) = 0n00<EFBFBD>c"}Y0<59>0
* _0`0W00<EFBFBD>c"}o0<6F>0<EFBFBD>0<EFBFBD>0w<30><77>N<EFBFBD>Qn0<6E><30>n00g0
* jisu Pn0<EFBFBD><EFBFBD>L0<EFBFBD><EFBFBD>d0K0<EFBFBD>0j0Q0<EFBFBD>0p00<EFBFBD>0<EFBFBD>0<EFBFBD>0h0Y0<EFBFBD>0
* @param pos int[]
* <EFBFBD><EFBFBD><EFBFBD>0MOn<h }(uM<EFBFBD>R0jisu Pn0<EFBFBD><EFBFBD>WL0<EFBFBD>_<EFBFBD><EFBFBD>
* @param n int
* <EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param jisu int
* <EFBFBD>n0!kpe
* @param sigma int[]
* <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD><jisu>
* @return int
* 0: ck8^B}<EFBFBD>N
* < 0: <EFBFBD>0<EFBFBD>0<EFBFBD>0
*/
2011-11-15 10:56:49 +00:00
public unsafe bool chienSearch(int* pos, int n, int jisu, int* sigma)
2010-02-18 21:12:44 +00:00
{
/*
* <EFBFBD>(z) = (1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)
* = 1 + <EFBFBD>1z + <EFBFBD>2z^2 +...
* <EFBFBD>1 = <EFBFBD>^i + <EFBFBD>^j + <EFBFBD>^k
* d0~0<EFBFBD>0<EFBFBD>1o0hQf0n0<EFBFBD><EFBFBD>n0T<EFBFBD>h0j0c0f0D0<EFBFBD>00
N<EFBFBD>n0'`0)R(uW0f00<EFBFBD>0<EFBFBD>0gi<EFBFBD>S
* last = <EFBFBD>1K0<EFBFBD>00<EFBFBD><EFBFBD>d0Q0_00!k0h0_D0f0D0O0S0h0k0<EFBFBD>0<EFBFBD>00g<EFBFBD>_n0<EFBFBD><EFBFBD>o0lasth0j0<EFBFBD>0
*/
int last = sigma[1];
if (jisu == 1)
{
// !kpeL01j0<EFBFBD>0p0lastL0]0n0<EFBFBD><EFBFBD>g0B0<EFBFBD>0
return setLastErrorPos(pos, n, last);
}
2011-11-15 10:56:49 +00:00
int* sg = stackalloc int[jisu + 1];
for (int j = 1; j <= jisu; j++)
2011-11-15 10:56:49 +00:00
sg[j] = sigma[j];
2010-02-18 21:12:44 +00:00
int posIdx = jisu - 1; // <EFBFBD><EFBFBD><EFBFBD>0MOn<h }(u<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
2011-11-15 10:56:49 +00:00
bool haveZeroes = false;
// haveZeroes = true;
for (int j = 1; j <= jisu; j++)
haveZeroes |= sg[j] == 0;
if (!haveZeroes && this.galois.Max == 0xffff)
{
const int himax = 0x11000;
fixed (ushort* exp = this.galois.ExpTbl, log = this.galois.LogTbl)
{
for (int j = 1; j <= jisu; j++)
{
sg[j] = log[sg[j]] - ((j * n) % 0xffff) + 0xffff;
sg[j] = (sg[j] & 0xffff) + (sg[j] >> 16);
}
int i = n;
while (i > 0)
{
int cnt = i;
for (int j = 1; j <= jisu; j++)
{
sg[j] = (sg[j] & 0xffff) + (sg[j] >> 16);
cnt = Math.Min(cnt, (himax - sg[j]) / j);
}
i -= RsDecode.chienFast(sg, exp, cnt, jisu);
int wk = 1;
for (int j = 1; j <= jisu; j++)
wk ^= exp[sg[j]];
if (wk == 0)
{
last ^= pos[posIdx--] = exp[i];
if (posIdx == 0)
{
pos[0] = last;
return log[last] < n;
}
}
}
}
return false;
}
2010-02-18 21:12:44 +00:00
for (int i = 0; i < n; i++)
{
/*
* <EFBFBD>(z)n0<EFBFBD><EFBFBD>{
* w <EFBFBD>01(0WNn0<EFBFBD>)k0RgSW0_0<EFBFBD>_0<EFBFBD>k<EFBFBD>0n0<EFBFBD><1..jisu><EFBFBD>0<EFBFBD>R<EFBFBD>{
* z = 1/<EFBFBD>^i = <EFBFBD>^Ih0Y0<EFBFBD>0h0
* <EFBFBD>(z) = 1 + <EFBFBD>1<EFBFBD>^I + <EFBFBD>2(<EFBFBD>^I)^2 + <EFBFBD>3(<EFBFBD>^I)^3 + ... + <EFBFBD><jisu>/(<EFBFBD>^I)^<jisu>
* = 1 + <EFBFBD>1<EFBFBD>^I + <EFBFBD>2<EFBFBD>^(I*2) + <EFBFBD>3<EFBFBD>^(I*3) + ... + <EFBFBD><jisu><EFBFBD>^(I*<jisu>)
*/
int wk = 1;
for (int j = 1; j <= jisu; j++)
wk ^= sg[j];
for (int j = 1; j <= jisu; j++)
2010-02-18 21:12:44 +00:00
{
2011-11-15 10:56:49 +00:00
sg[j] = galois.divExp(sg[j], j);
2010-02-18 21:12:44 +00:00
}
if (wk == 0)
{
int pv = galois.toExp(i); // <EFBFBD>(z) = 0n0<EFBFBD><EFBFBD>
last ^= pv; // lastK0<EFBFBD>0<EFBFBD>N<EFBFBD><EFBFBD>d0K0c0_00_O0
pos[posIdx--] = pv;
if (posIdx == 0)
{
// <EFBFBD>k<EFBFBD>0L0Nd0j0<EFBFBD>0p00lastL0]0n0<EFBFBD><EFBFBD>g0B0<EFBFBD>0
return setLastErrorPos(pos, n, last);
}
}
}
// <EFBFBD>c"}k0<6B>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0w<30><77>N<EFBFBD>Qk00jisu Pn0<6E><30>L0<4C><30>d0K0<4B>0j0K0c0_0
return false;
}
public unsafe bool chienSearch(int[] pos, int n, int jisu, int[] sigma)
{
fixed (int* p = pos, s = sigma)
2011-11-15 10:56:49 +00:00
return chienSearch(p, n, jisu, s);
2010-02-18 21:12:44 +00:00
}
public unsafe int doForney(int jisu, int ps, int* sigma, int* omega)
{
int zlog = galois.Max - galois.toLog(ps); // zn0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
// <EFBFBD>(z)n0<EFBFBD><EFBFBD>{
int ov = omega[0];
for (int j = 1; j < jisu; j++)
{
ov ^= galois.mulExp(omega[j], (zlog * j) % galois.Max); // ov += <EFBFBD>i * z^j
}
// <EFBFBD>'(z)n0$P<EFBFBD>0<EFBFBD><EFBFBD>{(<EFBFBD>(z)n0b__<EFBFBD>v<EFBFBD>_R)
int dv = sigma[1];
for (int j = 2; j < jisu; j += 2)
{
dv ^= galois.mulExp(sigma[j + 1], (zlog * j) % galois.Max); // dv += <EFBFBD><j+1> * z^j
}
/*
* <EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ck E^i = <EFBFBD>^i * <EFBFBD>(z) / <EFBFBD>'(z)
* <EFBFBD><EFBFBD><EFBFBD>0MOnn0<EFBFBD>{<EFBFBD>Vo0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>c"}n0h0M0k0<6B>O<<3C>U0<55>0f0D0<44>0n0g00
* S0S0g0o0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0W0j0D0
*/
return galois.mul(ps, galois.div(ov, dv));
}
2011-11-15 10:56:49 +00:00
private unsafe static int chienFast(int* sg, ushort* exp, int cnt, int jisu)
{
int start = cnt;
switch (jisu)
{
case 2:
{
int sg1 = sg[1];
int sg2 = sg[2];
do
{
sg1 += 1;
sg2 += 2;
}
while (--cnt > 0 && (exp[sg1] ^ exp[sg2]) != 1);
sg[1] = sg1;
sg[2] = sg2;
}
break;
case 3:
{
int sg1 = sg[1];
int sg2 = sg[2];
int sg3 = sg[3];
do
{
sg1 += 1;
sg2 += 2;
sg3 += 3;
}
while (--cnt > 0 && (exp[sg1] ^ exp[sg2] ^ exp[sg3]) != 1);
sg[1] = sg1;
sg[2] = sg2;
sg[3] = sg3;
}
break;
case 4:
{
int sg1 = sg[1];
int sg2 = sg[2];
int sg3 = sg[3];
int sg4 = sg[4];
do
{
sg1 += 1;
sg2 += 2;
sg3 += 3;
sg4 += 4;
}
while (--cnt > 0 && (exp[sg1] ^ exp[sg2] ^ exp[sg3] ^ exp[sg4]) != 1);
sg[1] = sg1;
sg[2] = sg2;
sg[3] = sg3;
sg[4] = sg4;
}
break;
default:
{
int sg1 = sg[1];
int sg2 = sg[2];
int sg3 = sg[3];
int sg4 = sg[4];
int sg5 = sg[5];
int wkhi;
do
{
wkhi = exp[sg1 += 1] ^ exp[sg2 += 2] ^ exp[sg3 += 3] ^ exp[sg4 += 4] ^ exp[sg5 += 5];
for (int j = 6; j <= jisu; j++)
wkhi ^= exp[sg[j] += j];
}
while (--cnt > 0 && wkhi != 1);
sg[1] = sg1;
sg[2] = sg2;
sg[3] = sg3;
sg[4] = sg4;
sg[5] = sg5;
}
break;
}
return start - cnt;
}
2010-02-18 21:12:44 +00:00
}
public class RsDecode8: RsDecode
{
public RsDecode8(int npar)
: base(npar, Galois81D.instance)
{
}
/**
* Forney<EFBFBD>lg0<EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ck<EFBFBD>0L<EFBFBD>F0
* <EFBFBD>(z) = (1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)
* <EFBFBD>'(z) = <EFBFBD>^i * (1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)...
* + <EFBFBD>^j * (1-<EFBFBD>^i*z)(1-<EFBFBD>^k*z)...
* + <EFBFBD>^k * (1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)...
* <EFBFBD>(z) = (E^i/(1-<EFBFBD>^i*z) + E^j/(1-<EFBFBD>^j*z) + ...) * <EFBFBD>(z)
* = E^i*(1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)...
* + E^j*(1-<EFBFBD>^i*z)(1-<EFBFBD>^k*z)...
* + E^k*(1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)...
* 4" E^i = <00>^i * <00>(z) / <00>'(z)
* @param data int[]
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
* @param length int
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>U0
* @param jisu int
* <EFBFBD>n0!kpe
* @param pos int[]
* <EFBFBD><EFBFBD><EFBFBD>0MOnM<EFBFBD>R
* @param sigma int[]
* <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD><jisu>
* @param omega int[]
* <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD><jisu-1>
*/
private unsafe void doForney(byte[] data, int length, int jisu, int[] pos, int[] sigma, int[] omega)
{
fixed (int* s = sigma, o = omega)
for (int i = 0; i < jisu; i++)
{
int ps = pos[i];
data[galois.toPos(length, ps)] ^= (byte)doForney(jisu, ps, s, o);
}
}
/**
* RS<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
*
* @param data int[]
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
* @param length int
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0+T<EFBFBD>0_0<EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param noCorrect boolean
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n00g0<EFBFBD>cko0L<EFBFBD><EFBFBD>0j0D0
* @return bool
* 0: <EFBFBD>0<EFBFBD>0<EFBFBD>0j0W0
* > 0: ;b<EFBFBD>0$P Pn0<EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>0<EFBFBD>ckW0_0
* < 0: <EFBFBD>ck N<EFBFBD><EFBFBD>
*/
public bool decode(byte[] data, int length, bool noCorrect, out int errors)
{
if (length < npar || length > galois.Max)
throw new Exception("RsDecode: wrong length");
errors = 0;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD><EFBFBD>{
int[] syn = new int[npar];
if (galois.calcSyndrome(data, length, syn))
return true; // <EFBFBD>0<EFBFBD>0<EFBFBD>0!qW0
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>h0<EFBFBD><EFBFBD>0Bl<EFBFBD>0<EFBFBD>0
int[] sigma = new int[npar / 2 + 2];
int[] omega = new int[npar / 2 + 1];
int jisu = calcSigmaMBM(sigma, omega, syn);
if (jisu <= 0)
return false;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>c"}k0<6B>0<EFBFBD>0<EFBFBD><30><EFBFBD>0MOn<6E>0Bl<42>0<EFBFBD>0
int[] pos = new int[jisu];
if (!chienSearch(pos, length, jisu, sigma))
return false;
if (!noCorrect) // <EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ck
doForney(data, length, jisu, pos, sigma, omega);
errors = jisu;
return true;
}
}
public class RsDecode16 : RsDecode
{
public RsDecode16(int npar, Galois galois)
: base(npar, galois)
{
}
public RsDecode16(int npar)
: this(npar, Galois16.instance)
{
}
/**
* Forney<EFBFBD>lg0<EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ck<EFBFBD>0L<EFBFBD>F0
* <EFBFBD>(z) = (1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)
* <EFBFBD>'(z) = <EFBFBD>^i * (1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)...
* + <EFBFBD>^j * (1-<EFBFBD>^i*z)(1-<EFBFBD>^k*z)...
* + <EFBFBD>^k * (1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)...
* <EFBFBD>(z) = (E^i/(1-<EFBFBD>^i*z) + E^j/(1-<EFBFBD>^j*z) + ...) * <EFBFBD>(z)
* = E^i*(1-<EFBFBD>^j*z)(1-<EFBFBD>^k*z)...
* + E^j*(1-<EFBFBD>^i*z)(1-<EFBFBD>^k*z)...
* + E^k*(1-<EFBFBD>^i*z)(1-<EFBFBD>^j*z)...
* 4" E^i = <00>^i * <00>(z) / <00>'(z)
* @param data int[]
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
* @param length int
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>U0
* @param jisu int
* <EFBFBD>n0!kpe
* @param pos int[]
* <EFBFBD><EFBFBD><EFBFBD>0MOnM<EFBFBD>R
* @param sigma int[]
* <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD><jisu>
* @param omega int[]
* <EFBFBD>0,<EFBFBD>1,<EFBFBD>2, ... <EFBFBD><jisu-1>
*/
private unsafe void doForney(ushort* data, int length, int jisu, int[] pos, int[] sigma, int[] omega)
{
fixed (int* s = sigma, o = omega)
for (int i = 0; i < jisu; i++)
{
int ps = pos[i];
data[galois.toPos(length, ps)] ^= (ushort)doForney(jisu, ps, s, o);
}
}
/**
* RS<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
*
* @param data int[]
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
* @param length int
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0+T<EFBFBD>0_0<EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param noCorrect boolean
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n00g0<EFBFBD>cko0L<EFBFBD><EFBFBD>0j0D0
* @return bool
* 0: <EFBFBD>0<EFBFBD>0<EFBFBD>0j0W0
* > 0: ;b<EFBFBD>0$P Pn0<EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>0<EFBFBD>ckW0_0
* < 0: <EFBFBD>ck N<EFBFBD><EFBFBD>
*/
public unsafe bool decode(ushort* data, int length, bool noCorrect, out int errors)
{
if (length < npar || length > galois.Max)
throw new Exception("RsDecode: wrong length");
errors = 0;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD><EFBFBD>{
int[] syn = new int[npar];
if (galois.calcSyndrome(data, length, syn))
return true; // <EFBFBD>0<EFBFBD>0<EFBFBD>0!qW0
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>h0<EFBFBD><EFBFBD>0Bl<EFBFBD>0<EFBFBD>0
int[] sigma = new int[npar / 2 + 2];
int[] omega = new int[npar / 2 + 1];
int jisu = calcSigmaMBM(sigma, omega, syn);
if (jisu <= 0)
return false;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>c"}k0<6B>0<EFBFBD>0<EFBFBD><30><EFBFBD>0MOn<6E>0Bl<42>0<EFBFBD>0
int[] pos = new int[jisu];
if (!chienSearch(pos, length, jisu, sigma))
return false;
if (!noCorrect) // <EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ck
doForney(data, length, jisu, pos, sigma, omega);
errors = jisu;
return true;
}
public unsafe bool decode(byte[] data, int datapos, int length, bool noCorrect, out int errors)
{
if ((length & 1) != 0)
throw new Exception("RsDecode: wrong length");
fixed (byte* bytes = &data[datapos])
return decode((ushort*)bytes, length >> 1, noCorrect, out errors);
}
}
}