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