1 #include "rar.hpp"
2
3 #define Clean(D,S) {for (int I=0;I<(S);I++) (D)[I]=0;}
4
RSCoder(int ParSize)5 RSCoder::RSCoder(int ParSize)
6 {
7 RSCoder::ParSize=ParSize;
8 FirstBlockDone=false;
9 gfInit();
10 pnInit();
11 }
12
13
gfInit()14 void RSCoder::gfInit()
15 {
16 for (int I=0,J=1;I<MAXPAR;I++)
17 {
18 gfLog[J]=I;
19 gfExp[I]=J;
20 if ((J<<=1)&256)
21 J^=285;
22 }
23 for (int I=MAXPAR;I<MAXPOL;I++)
24 gfExp[I]=gfExp[I-MAXPAR];
25 }
26
27
gfMult(int a,int b)28 inline int RSCoder::gfMult(int a,int b)
29 {
30 return(a==0 || b == 0 ? 0:gfExp[gfLog[a]+gfLog[b]]);
31 }
32
33
pnInit()34 void RSCoder::pnInit()
35 {
36 int p1[MAXPAR+1],p2[MAXPAR+1];
37
38 Clean(p2,ParSize);
39 p2[0]=1;
40 for (int I=1;I<=ParSize;I++)
41 {
42 Clean(p1,ParSize);
43 p1[0]=gfExp[I];
44 p1[1]=1;
45 pnMult(p1,p2,GXPol);
46 for (int J=0;J<ParSize;J++)
47 p2[J]=GXPol[J];
48 }
49 }
50
51
pnMult(int * p1,int * p2,int * r)52 void RSCoder::pnMult(int *p1,int *p2,int *r)
53 {
54 Clean(r,ParSize);
55 for (int I=0;I<ParSize;I++)
56 if (p1[I]!=0)
57 for(int J=0;J<ParSize-I;J++)
58 r[I+J]^=gfMult(p1[I],p2[J]);
59 }
60
61
Encode(byte * Data,int DataSize,byte * DestData)62 void RSCoder::Encode(byte *Data,int DataSize,byte *DestData)
63 {
64 int ShiftReg[MAXPAR+1];
65
66 Clean(ShiftReg,ParSize+1);
67 for (int I=0;I<DataSize;I++)
68 {
69 int D=Data[I]^ShiftReg[ParSize-1];
70 for (int J=ParSize-1;J>0;J--)
71 ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D);
72 ShiftReg[0]=gfMult(GXPol[0],D);
73 }
74 for (int I=0;I<ParSize;I++)
75 DestData[I]=ShiftReg[ParSize-I-1];
76 }
77
78
Decode(byte * Data,int DataSize,int * EraLoc,int EraSize)79 bool RSCoder::Decode(byte *Data,int DataSize,int *EraLoc,int EraSize)
80 {
81 int SynData[MAXPOL];
82 bool AllZeroes=true;
83 for (int I=0;I<ParSize;I++)
84 {
85 int Sum=Data[0],J=1,Exp=gfExp[I+1];
86 for (;J+8<=DataSize;J+=8)
87 {
88 Sum=Data[J]^gfMult(Exp,Sum);
89 Sum=Data[J+1]^gfMult(Exp,Sum);
90 Sum=Data[J+2]^gfMult(Exp,Sum);
91 Sum=Data[J+3]^gfMult(Exp,Sum);
92 Sum=Data[J+4]^gfMult(Exp,Sum);
93 Sum=Data[J+5]^gfMult(Exp,Sum);
94 Sum=Data[J+6]^gfMult(Exp,Sum);
95 Sum=Data[J+7]^gfMult(Exp,Sum);
96 }
97 for (;J<DataSize;J++)
98 Sum=Data[J]^gfMult(Exp,Sum);
99 if ((SynData[I]=Sum)!=0)
100 AllZeroes=false;
101 }
102 if (AllZeroes)
103 return(true);
104
105 if (!FirstBlockDone)
106 {
107 FirstBlockDone=true;
108 Clean(PolB,ParSize+1);
109 PolB[0]=1;
110 for (int EraPos=0;EraPos<EraSize;EraPos++)
111 for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--)
112 PolB[I]^=gfMult(M,PolB[I-1]);
113
114 ErrCount=0;
115 for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++)
116 {
117 int Sum=0;
118 for (int B=0;B<ParSize+1;B++)
119 Sum^=gfMult(gfExp[(B*Root)%MAXPAR],PolB[B]);
120 if (Sum==0)
121 {
122 Dn[ErrCount]=0;
123 for (int I=1;I<ParSize+1;I+=2)
124 Dn[ErrCount]^= gfMult(PolB[I],gfExp[Root*(I-1)%MAXPAR]);
125 ErrorLocs[ErrCount++]=MAXPAR-Root;
126 }
127 }
128 }
129
130 int PolD[MAXPOL];
131 pnMult(PolB,SynData,PolD);
132 if ((ErrCount<=ParSize) && ErrCount>0)
133 for (int I=0;I<ErrCount;I++)
134 {
135 int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0;
136 for (int J=0;J<ParSize;J++)
137 N^=gfMult(PolD[J],gfExp[DLoc*J%MAXPAR]);
138 int DataPos=DataSize-Loc-1;
139 if (DataPos>=0 && DataPos<DataSize)
140 Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dn[I]]]);
141 }
142 return(ErrCount<=ParSize);
143 }
144