OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 // Original code is licensed as follows: | |
7 /* | |
8 * Copyright 2012 ZXing authors | |
9 * | |
10 * Licensed under the Apache License, Version 2.0 (the "License"); | |
11 * you may not use this file except in compliance with the License. | |
12 * You may obtain a copy of the License at | |
13 * | |
14 * http://www.apache.org/licenses/LICENSE-2.0 | |
15 * | |
16 * Unless required by applicable law or agreed to in writing, software | |
17 * distributed under the License is distributed on an "AS IS" BASIS, | |
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
19 * See the License for the specific language governing permissions and | |
20 * limitations under the License. | |
21 */ | |
22 | |
23 #include "barcode.h" | |
24 #include "include/BC_PDF417Common.h" | |
25 #include "include/BC_PDF417ECModulusGF.h" | |
26 #include "include/BC_PDF417ECModulusPoly.h" | |
27 CBC_PDF417ECModulusPoly::CBC_PDF417ECModulusPoly(CBC_PDF417ECModulusGF* field, C
FX_Int32Array &coefficients, FX_INT32 &e) | |
28 { | |
29 if (coefficients.GetSize() == 0) { | |
30 e = BCExceptionIllegalArgument; | |
31 } | |
32 m_field = field; | |
33 FX_INT32 coefficientsLength = coefficients.GetSize(); | |
34 if (coefficientsLength > 1 && coefficients[0] == 0) { | |
35 FX_INT32 firstNonZero = 1; | |
36 while (firstNonZero < coefficientsLength && coefficients[firstNonZero] =
= 0) { | |
37 firstNonZero++; | |
38 } | |
39 if (firstNonZero == coefficientsLength) { | |
40 m_coefficients = field->getZero()->m_coefficients; | |
41 } else { | |
42 m_coefficients.SetSize(coefficientsLength - firstNonZero); | |
43 FX_INT32 l = 0; | |
44 for (FX_INT32 i = firstNonZero; i < firstNonZero + m_coefficients.Ge
tSize(); i++) { | |
45 m_coefficients.SetAt(l, coefficients.GetAt(i)); | |
46 l++; | |
47 } | |
48 } | |
49 } else { | |
50 m_coefficients.Copy(coefficients); | |
51 } | |
52 } | |
53 CBC_PDF417ECModulusPoly::~CBC_PDF417ECModulusPoly() | |
54 { | |
55 } | |
56 CFX_Int32Array& CBC_PDF417ECModulusPoly::getCoefficients() | |
57 { | |
58 return m_coefficients; | |
59 } | |
60 CBC_PDF417ECModulusGF* CBC_PDF417ECModulusPoly::getField() | |
61 { | |
62 return m_field; | |
63 } | |
64 FX_INT32 CBC_PDF417ECModulusPoly::getDegree() | |
65 { | |
66 return m_coefficients.GetSize() - 1; | |
67 } | |
68 FX_BOOL CBC_PDF417ECModulusPoly::isZero() | |
69 { | |
70 return m_coefficients[0] == 0; | |
71 } | |
72 FX_INT32 CBC_PDF417ECModulusPoly::getCoefficient(FX_INT32 degree) | |
73 { | |
74 return m_coefficients[m_coefficients.GetSize() - 1 - degree]; | |
75 } | |
76 FX_INT32 CBC_PDF417ECModulusPoly::evaluateAt(FX_INT32 a) | |
77 { | |
78 if (a == 0) { | |
79 return getCoefficient(0); | |
80 } | |
81 FX_INT32 size = m_coefficients.GetSize(); | |
82 if (a == 1) { | |
83 FX_INT32 result = 0; | |
84 for (FX_INT32 l = 0; l < m_coefficients.GetSize(); l++) { | |
85 FX_INT32 coefficient = m_coefficients.GetAt(l); | |
86 result = m_field->add(result, coefficient); | |
87 } | |
88 return result; | |
89 } | |
90 FX_INT32 result = m_coefficients[0]; | |
91 for (FX_INT32 i = 1; i < size; i++) { | |
92 result = m_field->add(m_field->multiply(a, result), m_coefficients[i]); | |
93 } | |
94 return result; | |
95 } | |
96 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::add(CBC_PDF417ECModulusPoly* o
ther, FX_INT32 &e) | |
97 { | |
98 CBC_PDF417ECModulusPoly* modulusPoly = NULL; | |
99 if (isZero()) { | |
100 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(other->getField(), other->g
etCoefficients(), e); | |
101 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
102 return modulusPoly; | |
103 } | |
104 if (other->isZero()) { | |
105 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e)
; | |
106 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
107 return modulusPoly; | |
108 } | |
109 CFX_Int32Array smallerCoefficients; | |
110 smallerCoefficients.Copy(m_coefficients); | |
111 CFX_Int32Array largerCoefficients; | |
112 largerCoefficients.Copy(other->m_coefficients); | |
113 if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) { | |
114 CFX_Int32Array temp; | |
115 temp.Copy(smallerCoefficients); | |
116 smallerCoefficients.Copy(largerCoefficients); | |
117 largerCoefficients.Copy(temp); | |
118 } | |
119 CFX_Int32Array sumDiff; | |
120 sumDiff.SetSize(largerCoefficients.GetSize()); | |
121 FX_INT32 lengthDiff = largerCoefficients.GetSize() - smallerCoefficients.Get
Size(); | |
122 for (FX_INT32 l = 0; l < lengthDiff; l++) { | |
123 sumDiff.SetAt(l, largerCoefficients.GetAt(l)); | |
124 } | |
125 for (FX_INT32 i = lengthDiff; i < largerCoefficients.GetSize(); i++) { | |
126 sumDiff[i] = m_field->add(smallerCoefficients[i - lengthDiff], largerCoe
fficients[i]); | |
127 } | |
128 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, sumDiff, e); | |
129 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
130 return modulusPoly; | |
131 } | |
132 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::subtract(CBC_PDF417ECModulusPo
ly* other, FX_INT32 &e) | |
133 { | |
134 CBC_PDF417ECModulusPoly* modulusPoly = NULL; | |
135 if (other->isZero()) { | |
136 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e)
; | |
137 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
138 return modulusPoly; | |
139 } | |
140 CBC_PDF417ECModulusPoly* poly = other->negative(e); | |
141 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
142 modulusPoly = add(poly, e); | |
143 delete poly; | |
144 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
145 return modulusPoly; | |
146 } | |
147 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply(CBC_PDF417ECModulusPo
ly* other, FX_INT32 &e) | |
148 { | |
149 CBC_PDF417ECModulusPoly* modulusPoly = NULL; | |
150 if (isZero() || other->isZero()) { | |
151 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->getFiel
d(), m_field->getZero()->getCoefficients(), e); | |
152 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
153 return modulusPoly; | |
154 } | |
155 CFX_Int32Array aCoefficients; | |
156 aCoefficients.Copy(m_coefficients); | |
157 FX_INT32 aLength = aCoefficients.GetSize(); | |
158 CFX_Int32Array bCoefficients; | |
159 bCoefficients.Copy(other->m_coefficients); | |
160 FX_INT32 bLength = bCoefficients.GetSize(); | |
161 CFX_Int32Array product; | |
162 product.SetSize(aLength + bLength - 1); | |
163 for (FX_INT32 i = 0; i < aLength; i++) { | |
164 FX_INT32 aCoeff = aCoefficients[i]; | |
165 for (FX_INT32 j = 0; j < bLength; j++) { | |
166 product[i + j] = m_field->add(product[i + j], m_field->multiply(aCoe
ff, bCoefficients[j])); | |
167 } | |
168 } | |
169 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e); | |
170 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
171 return modulusPoly; | |
172 } | |
173 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::negative(FX_INT32 &e) | |
174 { | |
175 FX_INT32 size = m_coefficients.GetSize(); | |
176 CFX_Int32Array negativeCoefficients; | |
177 negativeCoefficients.SetSize(size); | |
178 for (FX_INT32 i = 0; i < size; i++) { | |
179 negativeCoefficients[i] = m_field->subtract(0, m_coefficients[i]); | |
180 } | |
181 CBC_PDF417ECModulusPoly* modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_fiel
d, negativeCoefficients, e); | |
182 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
183 return modulusPoly; | |
184 } | |
185 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply(FX_INT32 scalar, FX_I
NT32 &e) | |
186 { | |
187 CBC_PDF417ECModulusPoly* modulusPoly = NULL; | |
188 if (scalar == 0) { | |
189 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->getFiel
d(), m_field->getZero()->getCoefficients(), e); | |
190 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
191 return modulusPoly; | |
192 } | |
193 if (scalar == 1) { | |
194 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e)
; | |
195 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
196 return modulusPoly; | |
197 } | |
198 FX_INT32 size = m_coefficients.GetSize(); | |
199 CFX_Int32Array product; | |
200 product.SetSize(size); | |
201 for (FX_INT32 i = 0; i < size; i++) { | |
202 product[i] = m_field->multiply(m_coefficients[i], scalar); | |
203 } | |
204 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e); | |
205 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
206 return modulusPoly; | |
207 } | |
208 CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiplyByMonomial(FX_INT32 de
gree, FX_INT32 coefficient, FX_INT32 &e) | |
209 { | |
210 if (degree < 0) { | |
211 e = BCExceptionIllegalArgument; | |
212 return NULL; | |
213 } | |
214 CBC_PDF417ECModulusPoly* modulusPoly = NULL; | |
215 if (coefficient == 0) { | |
216 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->m_field
, m_field->getZero()->m_coefficients, e); | |
217 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
218 return modulusPoly; | |
219 } | |
220 FX_INT32 size = m_coefficients.GetSize(); | |
221 CFX_Int32Array product; | |
222 product.SetSize(size + degree); | |
223 for (FX_INT32 i = 0; i < size; i++) { | |
224 product[i] = m_field->multiply(m_coefficients[i], coefficient); | |
225 } | |
226 modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e); | |
227 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
228 return modulusPoly; | |
229 } | |
230 CFX_PtrArray* CBC_PDF417ECModulusPoly::divide(CBC_PDF417ECModulusPoly* other, FX
_INT32 &e) | |
231 { | |
232 if (other->isZero()) { | |
233 e = BCExceptionDivideByZero; | |
234 return NULL; | |
235 } | |
236 CBC_PDF417ECModulusPoly* quotient = FX_NEW CBC_PDF417ECModulusPoly(m_field->
getZero()->m_field, m_field->getZero()->m_coefficients, e); | |
237 BC_EXCEPTION_CHECK_ReturnValue(e, NULL); | |
238 CBC_PDF417ECModulusPoly* remainder = FX_NEW CBC_PDF417ECModulusPoly(m_field,
m_coefficients, e); | |
239 if (e != BCExceptionNO) { | |
240 delete quotient; | |
241 return NULL; | |
242 } | |
243 FX_INT32 denominatorLeadingTerm = other->getCoefficient(other->getDegree()); | |
244 FX_INT32 inverseDenominatorLeadingTerm = m_field->inverse(denominatorLeading
Term, e); | |
245 if (e != BCExceptionNO) { | |
246 delete quotient; | |
247 delete remainder; | |
248 return NULL; | |
249 } | |
250 while (remainder->getDegree() >= other->getDegree() && !remainder->isZero())
{ | |
251 FX_INT32 degreeDifference = remainder->getDegree() - other->getDegree(); | |
252 FX_INT32 scale = m_field->multiply(remainder->getCoefficient(remainder->
getDegree()), inverseDenominatorLeadingTerm); | |
253 CBC_PDF417ECModulusPoly* term = other->multiplyByMonomial(degreeDifferen
ce, scale, e); | |
254 if (e != BCExceptionNO) { | |
255 delete quotient; | |
256 delete remainder; | |
257 return NULL; | |
258 } | |
259 CBC_PDF417ECModulusPoly* iterationQuotient = m_field->buildMonomial(degr
eeDifference, scale, e); | |
260 if (e != BCExceptionNO) { | |
261 delete quotient; | |
262 delete remainder; | |
263 delete term; | |
264 return NULL; | |
265 } | |
266 CBC_PDF417ECModulusPoly* temp = quotient; | |
267 quotient = temp->add(iterationQuotient, e); | |
268 delete iterationQuotient; | |
269 delete temp; | |
270 if (e != BCExceptionNO) { | |
271 delete remainder; | |
272 return NULL; | |
273 } | |
274 temp = remainder; | |
275 remainder = temp->subtract(term, e); | |
276 delete term; | |
277 delete temp; | |
278 if (e != BCExceptionNO) { | |
279 delete quotient; | |
280 return NULL; | |
281 } | |
282 } | |
283 CFX_PtrArray* modulusPoly = FX_NEW CFX_PtrArray; | |
284 modulusPoly->Add(quotient); | |
285 modulusPoly->Add(remainder); | |
286 return modulusPoly; | |
287 } | |
288 CFX_ByteString CBC_PDF417ECModulusPoly::toString() | |
289 { | |
290 CFX_ByteString result; | |
291 for (FX_INT32 degree = getDegree(); degree >= 0; degree--) { | |
292 FX_INT32 coefficient = getCoefficient(degree); | |
293 if (coefficient != 0) { | |
294 if (coefficient < 0) { | |
295 result += " - "; | |
296 coefficient = -coefficient; | |
297 } else { | |
298 if (result.GetLength() > 0) { | |
299 result += " + "; | |
300 } | |
301 } | |
302 if (degree == 0 || coefficient != 1) { | |
303 result += coefficient; | |
304 } | |
305 if (degree != 0) { | |
306 if (degree == 1) { | |
307 result += 'x'; | |
308 } else { | |
309 result += "x^"; | |
310 result += degree; | |
311 } | |
312 } | |
313 } | |
314 } | |
315 return result; | |
316 } | |
OLD | NEW |