📄 rs.cpp
字号:
//if (DEBUG && NErrors) fprintf(stderr, "Uncorrectable codeword\n"); UncorrectableCodeword=true; return(0); }
}
int __fastcall RS::correct_errors_erasures(int codeword[], int csize)
{
int r, i, j, err,yy;
unsigned char uc;
/* If you want to take advantage of erasure correction, be sure to set NErasures and ErasureLocs[] with the locations of erasures. */ NErasures = 0; for(i=0;i<csize;i++) { if(codeword[i]<0) { codeword[i]=0; ErasureLocs[NErasures] = i; NErasures++; } } //for (i = 0; i < NErasures; i++) ErasureLocs[i] = erasures[i]; Modified_Berlekamp_Massey(); Find_Roots(); if ((NErrors <= NPAR) && NErrors > 0) { UncorrectableCodeword=false; /* first check for illegal error locs */ for (r = 0; r < NErrors; r++) { if (ErrorLocs[r] >= csize) { //if (DEBUG) fprintf(stderr, "Error loc i=%d outside of codeword length %d\n", i, csize); return(0); } } for (r = 0; r < NErrors; r++) { int num, denom; i = ErrorLocs[r]; /* evaluate Omega at alpha^(-i) */ num = 0; for (j = 0; j < MAXDEG; j++) num ^= gmult(Omega[j], gexp[((255-i)*j)%255]); /* evaluate Lambda' (derivative) at alpha^(-i) ; all odd powers disappear */ denom = 0; for (j = 1; j < MAXDEG; j += 2) { denom ^= gmult(Lambda[j], gexp[((255-i)*(j-1)) % 255]); } err = gmult(num, ginv(denom)); //if (DEBUG) fprintf(stderr, "Error magnitude %#x at loc %d\n", err, csize-i); codeword[csize-i-1] = (codeword[csize-i-1] ^ err)&255; } return(1); } else { //if (DEBUG && NErrors) fprintf(stderr, "Uncorrectable codeword\n"); UncorrectableCodeword=true; return(0); }
}
void __fastcall RS::Modified_Berlekamp_Massey()
{
int n, L, L2, k, d, i;
int *psi=new int[MAXDEG];
int *psi2=new int[MAXDEG];
int *D=new int[MAXDEG];
int *gamma=new int[MAXDEG];
/* initialize Gamma, the erasure locator polynomial */ init_gamma(gamma); /* initialize to z */ copy_poly(D, gamma); mul_z_poly(D); copy_poly(psi, gamma); k = -1; L = NErasures; for (n = NErasures; n < NPAR; n++) { d = compute_discrepancy(psi, synBytes, L, n); if (d != 0) { /* psi2 = psi - d*D */ for (i = 0; i < MAXDEG; i++) psi2[i] = psi[i] ^ gmult(d, D[i]); if (L < (n-k)) { L2 = n-k; k = n-L; /* D = scale_poly(ginv(d), psi); */ for (i = 0; i < MAXDEG; i++) D[i] = gmult(psi[i], ginv(d)); L = L2; } /* psi = psi2 */ for (i = 0; i < MAXDEG; i++) psi[i] = psi2[i]; } mul_z_poly(D); } for(i = 0; i < MAXDEG; i++) Lambda[i] = psi[i]; compute_modified_omega(); delete [] D;
delete [] gamma;
delete [] psi;
delete [] psi2;
}
/* given Psi (called Lambda in Modified_Berlekamp_Massey) and synBytes,
compute the combined erasure/error evaluator polynomial as Psi*S mod z^4 */
void __fastcall RS::compute_modified_omega()
{
int i;
int *product=new int[MAXDEG*2];
mult_polys(product, Lambda, synBytes); zero_poly(Omega); for(i = 0; i < NPAR; i++) Omega[i] = product[i];
delete [] product;
}
/* gamma = product (1-z*a^Ij) for erasure locs Ij */
void __fastcall RS::init_gamma(int gamma[])
{
int e;
int *tmp=new int[MAXDEG];
zero_poly(gamma); zero_poly(tmp); gamma[0] = 1; for (e = 0; e < NErasures; e++) { copy_poly(tmp, gamma); scale_poly(gexp[ErasureLocs[e]], tmp); mul_z_poly(tmp); add_polys(gamma, tmp); }
delete [] tmp;
}
int __fastcall RS::compute_discrepancy(int lambda[], int S[], int L, int n)
{
int i, sum=0;
for (i = 0; i <= L; i++) sum ^= gmult(lambda[i], S[n-i]); return (sum);
}
void __fastcall RS::add_polys(int dst[], int src[])
{
int i;
for (i = 0; i < MAXDEG; i++) dst[i] ^= src[i];
}
void __fastcall RS::scale_poly(int k, int poly[])
{
int i;
for (i = 0; i < MAXDEG; i++) poly[i] = gmult(k, poly[i]);
}
/* multiply by z, i.e., shift right by 1 */
void __fastcall RS::mul_z_poly(int src[])
{
int i;
for (i = MAXDEG-1; i > 0; i--) src[i] = src[i-1]; src[0] = 0;
}
/* Finds all the roots of an error-locator polynomial with coefficients
* Lambda[j] by evaluating Lambda at successive values of alpha. * * This can be tested with the decoder's equations case. */
void __fastcall RS::Find_Roots()
{
int sum, r, k;
NErrors = 0; for (r = 1; r < 256; r++) { sum = 0; /* evaluate lambda at r */ for (k = 0; k < NPAR+1; k++) { sum ^= gmult(gexp[(k*r)%255], Lambda[k]); } if (sum == 0) { ErrorLocs[NErrors] = (255-r); NErrors++; //if (DEBUG) fprintf(stderr, "Root found at r = %d, (255-r) = %d\n", r, (255-r)); } }
}
__fastcall RS::~RS()
{
delete [] pBytes;
delete [] synBytes;
delete [] genPoly;
delete [] Lambda;
delete [] Omega;
}
//-----------------
int __fastcall RSWrapper::GetEncodedChar()
{
if(!GotEncodedChar)return -2;
int Result=EnCodedData[EnCodedDataPtr];
EnCodedDataPtr++;
if(EnCodedDataPtr>=EnCodedDataSize)
{
EnCodedDataPtr=0;
GotEncodedChar=false;
if(!NeedCharToEncode)SwitchEncodeBuffers();
}
return Result;
}
void __fastcall RSWrapper::LoadCharToEncode(int Value)
{
if(!NeedCharToEncode)return;
EnCodeingBuffers[EnCodeingBuffersPtr][EnCodeingDataPtr]=Value;
EnCodeingDataPtr++;EnCodeingDataPtr%=EnCodeingBuffers[EnCodeingBuffersPtr].size()-NumberOfParityBytes;
if(EnCodeingDataPtr==0)SwitchEncodeBuffers();
}
void __fastcall RSWrapper::SwitchEncodeBuffers()
{
if(GotEncodedChar)
{
NeedCharToEncode=false;
return;
}
NeedCharToEncode=true;
encode_data(&EnCodeingBuffers[EnCodeingBuffersPtr][0],EnCodeingBuffers[EnCodeingBuffersPtr].size()-NumberOfParityBytes);
EnCodedData=&EnCodeingBuffers[EnCodeingBuffersPtr][0];
EnCodedDataPtr=0;
EnCodedDataSize=EnCodeingBuffers[EnCodeingBuffersPtr].size();
GotEncodedChar=true;
EnCodeingBuffersPtr=1-EnCodeingBuffersPtr;
}
void __fastcall RSWrapper::LoadCharToDecode(int Value)
{
if(!NeedCharToDecode)return;
DeCodeingBuffers[DeCodeingBuffersPtr][DeCodeingDataPtr]=Value;
DeCodeingDataPtr++;DeCodeingDataPtr%=DeCodeingBuffers[DeCodeingBuffersPtr].size();
if(DeCodeingDataPtr==0)SwitchDecodeBuffers();
}
int __fastcall RSWrapper::GetDecodedChar()
{
if(!GotDecodedChar)return -2;
int Result=DeCodedData[DeCodedDataPtr];
DeCodedDataPtr++;
if(DeCodedDataPtr>=DeCodedDataSize)
{
DeCodedDataPtr=0;
GotDecodedChar=false;
if(!NeedCharToDecode)SwitchDecodeBuffers();
}
return Result;
}
void __fastcall RSWrapper::SwitchDecodeBuffers()
{
if(GotDecodedChar)
{
NeedCharToDecode=false;
return;
}
NeedCharToDecode=true;
decode_data(&DeCodeingBuffers[DeCodeingBuffersPtr][0],DeCodeingBuffers[DeCodeingBuffersPtr].size());
if(check_syndrome()!=0)
{
GotError=true;
correct_errors_erasures(&DeCodeingBuffers[DeCodeingBuffersPtr][0],DeCodeingBuffers[DeCodeingBuffersPtr].size());
}
DeCodedData=&DeCodeingBuffers[DeCodeingBuffersPtr][0];
DeCodedDataPtr=0;
DeCodedDataSize=DeCodeingBuffers[DeCodeingBuffersPtr].size()-NumberOfParityBytes;
DeCodeingBuffersPtr=1-DeCodeingBuffersPtr;
GotDecodedChar=true;
}
__fastcall RSWrapper::RSWrapper()
{
GotError=false;
SetNumberOfParityBytes(16);
SetEnCodedTotalBlockSize(58);
}
void __fastcall RSWrapper::SetNumberOfParityBytes(int Value)
{
NumberOfParityBytes=Value;
ResetEnCodedDataBuffer();
ResetDeCodedDataBuffer();
}
void __fastcall RSWrapper::ResetEnCodedDataBuffer()
{
EnCodeingBuffersPtr=0;
EnCodedDataPtr=0;
EnCodeingDataPtr=0;
GotEncodedChar=false;
NeedCharToEncode=true;
}
void __fastcall RSWrapper::ResetDeCodedDataBuffer()
{
DeCodeingBuffersPtr=0;
DeCodedDataPtr=0;
DeCodeingDataPtr=0;
GotDecodedChar=false;
NeedCharToDecode=true;
}
void __fastcall RSWrapper::SetEnCodedTotalBlockSize(int Value)
{
EnCodeingBuffers[0].resize(Value);
EnCodeingBuffers[1].resize(Value);
DeCodeingBuffers[0].resize(Value);
DeCodeingBuffers[1].resize(Value);
ResetEnCodedDataBuffer();
ResetDeCodedDataBuffer();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -