Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_ReedSolomon.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "barcode.h"\r
8 #include "include/BC_ReedSolomonGF256.h"\r
9 #include "include/BC_ReedSolomonGF256Poly.h"\r
10 #include "include/BC_ReedSolomon.h"\r
11 CBC_ReedSolomonEncoder::CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256* field)\r
12 {\r
13     m_field = field;\r
14 }\r
15 void CBC_ReedSolomonEncoder::Init()\r
16 {\r
17     m_cachedGenerators.Add(FX_NEW CBC_ReedSolomonGF256Poly(m_field, 1));\r
18 }\r
19 CBC_ReedSolomonGF256Poly* CBC_ReedSolomonEncoder::BuildGenerator(FX_INT32 degree, FX_INT32 &e)\r
20 {\r
21     if(degree >= m_cachedGenerators.GetSize()) {\r
22         CBC_ReedSolomonGF256Poly* lastGenerator = (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators[m_cachedGenerators.GetSize() - 1]);\r
23         for(FX_INT32 d = m_cachedGenerators.GetSize(); d <= degree; d++) {\r
24             CFX_Int32Array temp;\r
25             temp.Add(1);\r
26             temp.Add(m_field->Exp(d - 1));\r
27             CBC_ReedSolomonGF256Poly temp_poly;\r
28             temp_poly.Init(m_field, &temp, e);\r
29             BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
30             CBC_ReedSolomonGF256Poly* nextGenerator = lastGenerator->Multiply(&temp_poly, e);\r
31             BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
32             m_cachedGenerators.Add(nextGenerator);\r
33             lastGenerator = nextGenerator;\r
34         }\r
35     }\r
36     return (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators[degree]);\r
37 }\r
38 void CBC_ReedSolomonEncoder::Encode(CFX_Int32Array *toEncode, FX_INT32 ecBytes, FX_INT32 &e)\r
39 {\r
40     if(ecBytes == 0) {\r
41         e = BCExceptionNoCorrectionBytes;\r
42         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
43     }\r
44     FX_INT32 dataBytes = toEncode->GetSize() - ecBytes;\r
45     if(dataBytes <= 0) {\r
46         e = BCExceptionNoDataBytesProvided;\r
47         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
48     }\r
49     CBC_ReedSolomonGF256Poly* generator = BuildGenerator(ecBytes, e);\r
50     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
51     CFX_Int32Array infoCoefficients;\r
52     infoCoefficients.SetSize(dataBytes);\r
53     for(FX_INT32 x = 0; x < dataBytes; x++) {\r
54         infoCoefficients[x] = toEncode->operator [](x);\r
55     }\r
56     CBC_ReedSolomonGF256Poly info;\r
57     info.Init(m_field, &infoCoefficients, e);\r
58     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
59     CBC_ReedSolomonGF256Poly* rsg = info.MultiplyByMonomial(ecBytes, 1, e);\r
60     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
61     CBC_AutoPtr<CBC_ReedSolomonGF256Poly> infoTemp(rsg);\r
62     CFX_PtrArray *pa = infoTemp->Divide(generator, e);\r
63     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
64     CBC_AutoPtr<CFX_PtrArray > temp(pa);\r
65     CBC_ReedSolomonGF256Poly* remainder = (CBC_ReedSolomonGF256Poly*)(temp->operator [](1));\r
66     CFX_Int32Array* coefficients = remainder->GetCoefficients();\r
67     FX_INT32 numZeroCoefficients = ecBytes - coefficients->GetSize();\r
68     for(FX_INT32 i = 0; i < numZeroCoefficients; i++) {\r
69         (*toEncode)[dataBytes + i] = 0;\r
70     }\r
71     for(FX_INT32 y = 0; y < coefficients->GetSize(); y++) {\r
72         (*toEncode)[dataBytes + numZeroCoefficients + y] =\r
73             coefficients->operator [](y);\r
74     }\r
75     for (FX_INT32 k = 0; k < temp->GetSize(); k++) {\r
76         delete (CBC_ReedSolomonGF256Poly*)(*temp)[k];\r
77     }\r
78 }\r
79 CBC_ReedSolomonEncoder::~CBC_ReedSolomonEncoder()\r
80 {\r
81     for (FX_INT32 i = 0; i < m_cachedGenerators.GetSize(); i++) {\r
82         delete (CBC_ReedSolomonGF256Poly*)m_cachedGenerators[i];\r
83     }\r
84 }\r